LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - General
User Name
Password
Linux - General This Linux forum is for general Linux questions and discussion.
If it is Linux Related and doesn't seem to fit in any other forum then this is the place.

Notices


Reply
  Search this Thread
Old 05-23-2007, 03:16 AM   #1
sachinh
Member
 
Registered: Jul 2004
Location: india
Distribution: RH
Posts: 189

Rep: Reputation: 30
/etc/profile script


Our reqt is , whenever any user logs in to the system , a script should get executed. This script will create a new file in respective Home Dir.
I tried writing such script and put it under /etc/profile.d/test { We have RHEL 4.0 }
But whenever the user logs in it gives error as

touch: cannot touch `.last_date': Permission denied

The script we are trying to execute is having following permissions.
-rwxr-xr-x 1 root root 187 /etc/profile.d/test

Please suggest !!!!!!
 
Old 05-23-2007, 03:19 AM   #2
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

What is the content of the test script? Looks like it's one (?) of the commands in there that's causing the problem/error.
 
Old 05-23-2007, 03:30 AM   #3
sachinh
Member
 
Registered: Jul 2004
Location: india
Distribution: RH
Posts: 189

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by druuna
Hi,

What is the content of the test script? Looks like it's one (?) of the commands in there that's causing the problem/error.
Script :- I have put it under /etc/profile.d/

echo $HOME
if [ -f $HOME/.neverlogin ]; then
rm $HOME/.neverlogin
else
touch $HOME/.lastlogin_date
date >> $HOME/.lastlogin_date
fi
 
Old 05-23-2007, 06:51 AM   #4
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

The given info looks ok.

What are the permissions/owner/group of the .lastlogin_date file?
 
Old 05-23-2007, 07:31 AM   #5
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
You could use "lastlog -u username" to obtain the last login of a user. To lock out an account, you can use "passwd -l username" instead of file in their home directory.
 
Old 05-23-2007, 09:26 PM   #6
sachinh
Member
 
Registered: Jul 2004
Location: india
Distribution: RH
Posts: 189

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by jschiwal
You could use "lastlog -u username" to obtain the last login of a user. To lock out an account, you can use "passwd -l username" instead of file in their home directory.

We are little reluctant to use lastlog as it does not consider YEAR . (Thats what we think) .

Another thing is that , how can we get a user's home directory in a shell.

E.g.

for i in `cat UserList`
do
HomeDir= {This variable should get the value of the respective User's
Home Directory in every iteration of "i" }
echo $HomeDir
done
 
Old 05-24-2007, 01:49 AM   #7
druuna
LQ Veteran
 
Registered: Sep 2003
Posts: 10,532
Blog Entries: 7

Rep: Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405Reputation: 2405
Hi,

Quote:
Another thing is that , how can we get a user's home directory in a shell.

E.g.

for i in `cat UserList`
do
HomeDir= {This variable should get the value of the respective User's
Home Directory in every iteration of "i" }
echo $HomeDir
done
Something like this will give you the homedir of a specific user:

HomeDir="`awk -F: -v i=$i '$1 ~ i { print $6}' /etc/passwd`"

Hope this helps.

BTW: Did you solve your original problem?
 
Old 05-24-2007, 02:29 AM   #8
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
Quote:
Originally Posted by sachinh
We are little reluctant to use lastlog as it does not consider YEAR . (Thats what we think) .

Another thing is that , how can we get a user's home directory in a shell.

E.g.

for i in `cat UserList`
do
HomeDir= {This variable should get the value of the respective User's
Home Directory in every iteration of "i" }
echo $HomeDir
done
The home directory is contained in a field of /etc/passwd. However, if you use the default setup, you probably have a directory under /home that has the same name as the user.

So you could have a loop like:
Code:
for dir in /home/*; do

....

done
Also, keep in mind that /etc/passwd has system users as well. The range of UIDs used for regular users differs for different distros. Mandriva & Fedora Core start at 500, whereas SuSE starts at 1000. Anyway, you will need to examine the UID to determine if the user in /etc/passwd is a regular user. The bottom and top range may be defined in /etc/login.defs.

Given the tests you need to perform, you may want to produce a temp file containing the usernames and then use that list as items in a loop.
Code:
passwords=$(cat /etc/passwd)  # I'm always looking for excuses to use arrays in bash
for (( entry=0; entry<${#passwords[@]}; entry++ )); do
   uid=$(echo ${passwords[$entry]} | cut -d':' -f1)
   if [ $uid -ge 500 -a $uid -lt 2000 ]; then  # regular users have uids between 500 and 2000 inclusively.
      echo $(echo ${passwords[$entry]} | cut -d':' -f3) >reguserlist
   fi   # add user to list if in range.
done

for username in $(cat reguserlist);do

...

done
rm reguserlist
The normal lastlog entry does have the year:
Code:
Username         Port     From             Latest
root             tty1                      Thu Jan 25 15:23:50 +0530 2007
daemon                                     **Never logged in**
bin                                        **Never logged in**
sys                                        **Never logged in**
sync                                       **Never logged in**
vivek            tty1                      Sat Jan 27 22:10:36 +0530 2007
pdnsd                                      **Never logged in**
sshd                                       **Never logged in**
messagebus                                 **Never logged in**
bind                                       **Never logged in**
I'm not at my linux machine to check the output of "lastlog -u username".

A user would be able to delete a ~/.last_date file before logging off.
Or even use the touch command using a date years in the future.
If you really don't want to use lastlog, you could list the access time for ~/.profile or ~/.bashrc, however, the user might be using another shell.

Last edited by jschiwal; 05-24-2007 at 03:17 AM.
 
Old 05-24-2007, 09:23 PM   #9
sachinh
Member
 
Registered: Jul 2004
Location: india
Distribution: RH
Posts: 189

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by druuna
Hi,

The given info looks ok.

What are the permissions/owner/group of the .lastlogin_date file?

Hi Druuna,

Yes the problem with /etc/profile got resolved . How ?? Initially we thought just placing the script under /etc/profile.d would itself execute the script whenevera user logs in. But it didnt work ( Dont know whether it should be working this way ) .
So added an entry in /etc/profile file to execute the script. It worked !!
Last but not the least , we can place this script under any directory , it need not be /etc/profile.d.

Anyways ....thanks to you for showing concern!!!! Will meet sooon
 
Old 05-24-2007, 09:32 PM   #10
sachinh
Member
 
Registered: Jul 2004
Location: india
Distribution: RH
Posts: 189

Original Poster
Rep: Reputation: 30
[QUOTE=jschiwal]The home directory is contained in a field of /etc/passwd. However, if you use the default setup, you probably have a directory under /home that has the same name as the user.

So you could have a loop like:
Code:
for dir in /home/*; do

....

done
Yes you are correct. But we didnt want to take any chances as few of our systems are having users with non-default( other than /home) home directories. But thanks for pointing it out.

Quote:
Originally Posted by jschiwal
Also, keep in mind that /etc/passwd has system users as well. The range of UIDs used for regular users differs for different distros. Mandriva & Fedora Core start at 500, whereas SuSE starts at 1000. Anyway, you will need to examine the UID to determine if the user in /etc/passwd is a regular user. The bottom and top range may be defined in /etc/login.defs.

Given the tests you need to perform, you may want to produce a temp file containing the usernames and then use that list as items in a loop.
Code:
passwords=$(cat /etc/passwd)  # I'm always looking for excuses to use arrays in bash
for (( entry=0; entry<${#passwords[@]}; entry++ )); do
   uid=$(echo ${passwords[$entry]} | cut -d':' -f1)
   if [ $uid -ge 500 -a $uid -lt 2000 ]; then  # regular users have uids between 500 and 2000 inclusively.
      echo $(echo ${passwords[$entry]} | cut -d':' -f3) >reguserlist
   fi   # add user to list if in range.
done

for username in $(cat reguserlist);do

...

done
rm reguserlist
We wrote a different code to find out regular user list but yes the above code is also worth.
Will definately give it a shot !!!! Thanks again


Quote:
Originally Posted by jschiwal
The normal lastlog entry does have the year:
Code:
Username         Port     From             Latest
root             tty1                      Thu Jan 25 15:23:50 +0530 2007
daemon                                     **Never logged in**
bin                                        **Never logged in**
sys                                        **Never logged in**
sync                                       **Never logged in**
vivek            tty1                      Sat Jan 27 22:10:36 +0530 2007
pdnsd                                      **Never logged in**
sshd                                       **Never logged in**
messagebus                                 **Never logged in**
bind                                       **Never logged in**
I'm not at my linux machine to check the output of "lastlog -u username".
Yes even on Linux we get year field. But we are trying to manipulate things based on whether User has logged into the system for more than 90 Days or not. So we decided not to rely on to lastlog.




Quote:
Originally Posted by jschiwal
A user would be able to delete a ~/.last_date file before logging off.
Or even use the touch command using a date years in the future.
If you really don't want to use lastlog, you could list the access time for ~/.profile or ~/.bashrc, however, the user might be using another shell.

The above points you mentioned are really interesting and we have to give it a thought before we finalise things.
Maybe we would think of creating .last_date file for each user in a different location where regular users dont have access to. Will it help??

Listing the access time for ~/.profile is also a nice way . Will think over it and see if it fits our requirement.

Last but not the least .... Thanks a TON for your valuable advise. Its people like you and Druuna that make this Life more beautiful !!!!!!!!!!!!!

Last edited by sachinh; 05-24-2007 at 09:37 PM.
 
Old 05-24-2007, 09:50 PM   #11
frob23
Senior Member
 
Registered: Jan 2004
Location: Roughly 29.467N / 81.206W
Distribution: OpenBSD, Debian, FreeBSD
Posts: 1,450

Rep: Reputation: 48
Now comes the issue of users who change their default shell. People who prefer something other than a bourne style shell are almost certain to change that as one of the first things when they get access to the system. I'll freely admit that it's something I do. So after 90 days, regardless of how often I log in, it looks like I have only been on once.

Frankly, using login scripts to monitor this is too much of a kluge to be reliable and is likely to be easily subverted by smart users who feel like it inconveniences them.
 
Old 05-24-2007, 09:56 PM   #12
sachinh
Member
 
Registered: Jul 2004
Location: india
Distribution: RH
Posts: 189

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by frob23
Now comes the issue of users who change their default shell. People who prefer something other than a bourne style shell are almost certain to change that as one of the first things when they get access to the system. I'll freely admit that it's something I do. So after 90 days, regardless of how often I log in, it looks like I have only been on once.

Frankly, using login scripts to monitor this is too much of a kluge to be reliable and is likely to be easily subverted by smart users who feel like it inconveniences them.
Hi ,
Listed nice points...... but then its without any suggestions ....so ..now waiting for it !!
 
Old 05-24-2007, 10:01 PM   #13
frob23
Senior Member
 
Registered: Jan 2004
Location: Roughly 29.467N / 81.206W
Distribution: OpenBSD, Debian, FreeBSD
Posts: 1,450

Rep: Reputation: 48
Personally, you have some good suggestions... but let me tell you how to make them work.

Don't toss out the lastlog suggestion above... but if you feel it is not adequate then supplement it. Write a shell script which will take the output of lastlog, grab only the last day, and will parse them into a sorted file.

Have that same script produce a list of users who have not logged in for 90 days and output that list to a file somewhere.

Have this list called, daily, from cron. It will automate the whole thing... actually you can go even further... and have it email the users or deactivate their accounts automatically if they haven't been on for 90 days. Just be sure (if you automate it) to not deactivate/remove the root account.
 
Old 05-24-2007, 10:50 PM   #14
frob23
Senior Member
 
Registered: Jan 2004
Location: Roughly 29.467N / 81.206W
Distribution: OpenBSD, Debian, FreeBSD
Posts: 1,450

Rep: Reputation: 48
Code:
#!/bin/sh
OLDMASK=`umask`
TIMESTAMP=`date +%s`
FILENAME=/tmp/accounting
TMPFILE=/tmp/accounting.new
EXPIRED=/tmp/expired.accounts

# This is the number of seconds until the account is out of date:
# 7776000 = 90 days
SECONDS=7776000

umask 077

if [ ! -f ${FILENAME} ]; then
        touch ${FILENAME}
fi

#lastlog | awk '{print $1}' | while read LINE
lastlog | grep "`date | awk '{print $2, $3".*"$6}'`" | awk '{print $1}' | while read LINE
do
        awk -v time=${TIMESTAMP} -v user="${LINE}" 'BEGIN{found=0}{if($2 == user){$1=time;found=1};print $0}END{if(found!=1){print time" "user}}' ${FILENAME} > ${TMPFILE}
        mv ${TMPFILE} ${FILENAME}
done

sort -n ${FILENAME} > ${TMPFILE}
mv ${TMPFILE} ${FILENAME}

awk -v time=${TIMESTAMP} -v secs=${SECONDS} 'BEGIN{old=time-secs}{if($1<=old)print $2}' ${FILENAME} >> ${EXPIRED}

umask ${OLDMASK}
Here is something I just threw together... as an example... obviously, this is not what I would use in production. You would want those temp files somewhere else (probably under a protected directory only readable by the user running the program). This program is also simplified a lot (it could be more complex but I didn't see the need).

The people who have not logged in for 90 days would be put in /tmp/expired in this program. Also... you would need to modify this for the initial population of /tmp/accounting or else it will only catch those who don't use the system for 90 days after using it once this system is in place. It doesn't catch those who never log in... so that's another matter.

And so on. You could have the expired file mailed... oh, and one more thing... the current version doesn't remove the expired accounts from /tmp/accounts. That would require a trivial change (look at the last awk line) and is left as an exercise for the reader.

More could be done with this framework... but it gives an idea. And it also is outside the control of pesky users... and their evil ways.

Last edited by frob23; 05-24-2007 at 10:51 PM.
 
Old 05-24-2007, 11:06 PM   #15
sachinh
Member
 
Registered: Jul 2004
Location: india
Distribution: RH
Posts: 189

Original Poster
Rep: Reputation: 30
Quote:
Originally Posted by frob23
Code:
#!/bin/sh
OLDMASK=`umask`
TIMESTAMP=`date +%s`
FILENAME=/tmp/accounting
TMPFILE=/tmp/accounting.new
EXPIRED=/tmp/expired.accounts

# This is the number of seconds until the account is out of date:
# 7776000 = 90 days
SECONDS=7776000

umask 077

if [ ! -f ${FILENAME} ]; then
        touch ${FILENAME}
fi

#lastlog | awk '{print $1}' | while read LINE
lastlog | grep "`date | awk '{print $2, $3".*"$6}'`" | awk '{print $1}' | while read LINE
do
        awk -v time=${TIMESTAMP} -v user="${LINE}" 'BEGIN{found=0}{if($2 == user){$1=time;found=1};print $0}END{if(found!=1){print time" "user}}' ${FILENAME} > ${TMPFILE}
        mv ${TMPFILE} ${FILENAME}
done

sort -n ${FILENAME} > ${TMPFILE}
mv ${TMPFILE} ${FILENAME}

awk -v time=${TIMESTAMP} -v secs=${SECONDS} 'BEGIN{old=time-secs}{if($1<=old)print $2}' ${FILENAME} >> ${EXPIRED}

umask ${OLDMASK}
Here is something I just threw together... as an example... obviously, this is not what I would use in production. You would want those temp files somewhere else (probably under a protected directory only readable by the user running the program). This program is also simplified a lot (it could be more complex but I didn't see the need).

The people who have not logged in for 90 days would be put in /tmp/expired in this program. Also... you would need to modify this for the initial population of /tmp/accounting or else it will only catch those who don't use the system for 90 days after using it once this system is in place. It doesn't catch those who never log in... so that's another matter.

And so on. You could have the expired file mailed... oh, and one more thing... the current version doesn't remove the expired accounts from /tmp/accounts. That would require a trivial change (look at the last awk line) and is left as an exercise for the reader.

More could be done with this framework... but it gives an idea. And it also is outside the control of pesky users... and their evil ways.

Thanks a ton..This thread is really rising HIGH now. Cant wait to work on the above script. Wait for my feedback on above script.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Script in /etc/profile.d/ won't won't work!? BlueSpirit Slackware 1 10-15-2006 11:21 AM
system profile vs user profile bonito SUSE / openSUSE 3 06-28-2006 01:02 PM
non roaming profile on a roaming profile system fieldyweb Linux - Newbie 1 10-03-2005 12:27 PM
Is there a .profile script in Linux? rsuri Linux - Newbie 1 07-31-2003 12:39 PM
shell script to find user(s) profile j-me Programming 2 01-31-2003 11:16 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - General

All times are GMT -5. The time now is 06:28 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration