ahulikavi
24th February 2005, 07:51
Hi,
Have developed a 3gl solution for password ageing and controlling no of logins.
Purpose :
1. Enforce Password change after policy number of days (30 in our case)
2. Restrict multiple logins as per policy
3. Quickly list out logged in users in client instead of using licmon etc
Method :
1. create 2 tables one for password policy and max logins allowed per user and another to store current logins
2. create 3 gl session and add it in BMS as startup boot session.
3. Session check user status as per password policy and max logins allowed and takes neccessary action i.e. allow/dissallow login, force password change.
We use it on IVc4 with BW / Worktop on Sun Solaris 2.6. You may need to change certain OS specific commands for this to work at your end.
Now for the code ...Hope this helps, let me know any suggestions for improvement
||******************************************************************************
|* tdtcdmsg : VRC B40C Live
|* Title : Login and Password Control
|* Author : Akshay Hulikavi
|* Date : 2004-02-09 [09:17]
|******************************************************************************
|* License :
|* Copyright 2004 by Akshay Hulikavi
|*
|* All Rights Reserved
|*
|* Permission to use, copy, modify, and distribute this software and its
|* documentation for any purpose and without fee is hereby granted,
|* provided that the above copyright notice appear in all copies and that
|* both that copyright notice and this permission notice appear in
|* supporting documentation.
|*
|* Akshay Hulikavi DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|* AND FITNESS, IN NO EVENT SHALL Vamsi Potluru BE LIABLE FOR ANY
|* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|* OR PERFORMANCE OF THIS SOFTWARE.
|******************************************************************************
table ttdtcd991 | User login info
table ttdtcd990 | Current logins
string date.str(10), bucket(50), progname(512)
long procid, proclist(100), i, j, user.bshell.pid, ret, no.of.logins
long info(PSMAXSIZE)
function main()
{
if logname$ <> "root" or logname$ <> "smis1" then | Not for super user
user.bshell.pid = bshell.pid()
remove.user.from.990.if.disconnected()
db.retry.point()
no.of.logins = 0
select tdtcd991.*
from tdtcd991 for update
where tdtcd991._compnr = 010 | Only applicable for live company
and user = :logname$
selectdo
select count(tdtcd990.user):no.of.logins
from tdtcd990
where tdtcd990.user = :logname$
selectdo
endselect
if no.of.logins >= tdtcd991.maxl then | logins exceed maximum allowed for user ?
kill.and.exit()
exit(0)
else
tdtcd990.pid = user.bshell.pid
tdtcd990.user = logname$
tdtcd990.serv = hostname$()
tdtcd990.date = sprintf$("%D(%02d/%02m/%04Y)", date.num())
tdtcd990.comp = get.compnr()
db.insert(ttdtcd990, db.retry)
endif
date.str = sprintf$("%D(%02d/%02m/%04Y)", tdtcd991.lldt)
| tdtcd991.npwc = tdtcd991.lpwc + 30 | Add next pwc date
message( "Welcome "&logname$&", This is your login no "&str$(no.of.logins + 1)&" you are allowed max "&str$(tdtcd991.maxl)&" logins")
if date.num() >= tdtcd991.npwc then |time to Change password
ret = shell( "passwd",SHELL_CONFIRM)
if ret = 0 then |Password successfully changed
tdtcd991.lpwc = date.num() |Capture password change date
tdtcd991.npwc = tdtcd991.lpwc + 30 |Next change on
endif
endif
tdtcd991.lldt = date.num() | Last Login date
tdtcd991.lltm = time.num() | Last login Time
tdtcd991.nolg = tdtcd991.nolg + 1 | Number of logins till date
db.update(ttdtcd991, db.retry)
selectempty
message( "Welcome "&logname$&", This is your login no "&str$(no.of.logins + 1)&" you are allowed max "&str$(tdtcd991.maxl)&" logins")
tdtcd991.user = logname$
tdtcd991.lpwc = date.num() | Assume today as lastpw change if first time login
tdtcd991.npwc = tdtcd991.lpwc + 30 | Add next pwc date
tdtcd991.lldt = date.num() | Last Login Date
tdtcd991.lltm = time.num() | Last Login Time
tdtcd991.nolg = tdtcd991.nolg + 1 | no of logins till date
tdtcd991.maxl = 1 | Default Only 1 login allowed
db.insert(ttdtcd991, db.retry)
endselect
commit.transaction()
bms.add.mask("bms.shutdown") | to detect the shutdown event which is sent by the system
while true
bucket = bms.receive$()
if bucket = "bms.shutdown" then
remove.user.from.990()
exit(0)
endif
endwhile
endif
}
function remove.user.from.990()
{
select tdtcd990.*
from tdtcd990 for update
where tdtcd990.user = :logname$
and tdtcd990.pid = :user.bshell.pid
selectdo
db.delete(ttdtcd990, db.retry)
endselect
commit.transaction()
}
function kill.and.exit()
{
i = 1
procid = -1
procid = pstat(procid, progname, info )
while procid > 0
proclist(i) = procid
i = i + 1
procid = pstat( procid, progname, info )
endwhile
for j = i to 1 step -1
if proclist(j) <> pid then | Keep current process active so that we can remove everything and then
kill(proclist(j)) | display message
endif
endfor
message( " *** LOGIN DISSALLOWED : "&logname$&", you have already logged in "&str$(no.of.logins)&" times, you are allowed max "&str$(tdtcd991.maxl)&" logins")
kill(pid)
}
function remove.user.from.990.if.disconnected()
{
select tdtcd990.*
from tdtcd990 for update
where tdtcd990.user = :logname$
selectdo
ret = shell( "ps -p "&str$(tdtcd990.pid),SHELL_NO_OUTPUT) | Check if process active at OS level
if ret <> 0 then | Process does not exist at OS Level, probably killed or disconnected
db.delete(ttdtcd990, db.retry) | Delete from ligins table if bshell pid not found
endif
endselect
commit.transaction()
}
Note : When you need a situation when no one should log into baan just change tdtcd991.maxl field to 0 for all users except yourself ;-), this will not allow anybody else to login.
Have developed a 3gl solution for password ageing and controlling no of logins.
Purpose :
1. Enforce Password change after policy number of days (30 in our case)
2. Restrict multiple logins as per policy
3. Quickly list out logged in users in client instead of using licmon etc
Method :
1. create 2 tables one for password policy and max logins allowed per user and another to store current logins
2. create 3 gl session and add it in BMS as startup boot session.
3. Session check user status as per password policy and max logins allowed and takes neccessary action i.e. allow/dissallow login, force password change.
We use it on IVc4 with BW / Worktop on Sun Solaris 2.6. You may need to change certain OS specific commands for this to work at your end.
Now for the code ...Hope this helps, let me know any suggestions for improvement
||******************************************************************************
|* tdtcdmsg : VRC B40C Live
|* Title : Login and Password Control
|* Author : Akshay Hulikavi
|* Date : 2004-02-09 [09:17]
|******************************************************************************
|* License :
|* Copyright 2004 by Akshay Hulikavi
|*
|* All Rights Reserved
|*
|* Permission to use, copy, modify, and distribute this software and its
|* documentation for any purpose and without fee is hereby granted,
|* provided that the above copyright notice appear in all copies and that
|* both that copyright notice and this permission notice appear in
|* supporting documentation.
|*
|* Akshay Hulikavi DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
|* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|* AND FITNESS, IN NO EVENT SHALL Vamsi Potluru BE LIABLE FOR ANY
|* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
|* OR PERFORMANCE OF THIS SOFTWARE.
|******************************************************************************
table ttdtcd991 | User login info
table ttdtcd990 | Current logins
string date.str(10), bucket(50), progname(512)
long procid, proclist(100), i, j, user.bshell.pid, ret, no.of.logins
long info(PSMAXSIZE)
function main()
{
if logname$ <> "root" or logname$ <> "smis1" then | Not for super user
user.bshell.pid = bshell.pid()
remove.user.from.990.if.disconnected()
db.retry.point()
no.of.logins = 0
select tdtcd991.*
from tdtcd991 for update
where tdtcd991._compnr = 010 | Only applicable for live company
and user = :logname$
selectdo
select count(tdtcd990.user):no.of.logins
from tdtcd990
where tdtcd990.user = :logname$
selectdo
endselect
if no.of.logins >= tdtcd991.maxl then | logins exceed maximum allowed for user ?
kill.and.exit()
exit(0)
else
tdtcd990.pid = user.bshell.pid
tdtcd990.user = logname$
tdtcd990.serv = hostname$()
tdtcd990.date = sprintf$("%D(%02d/%02m/%04Y)", date.num())
tdtcd990.comp = get.compnr()
db.insert(ttdtcd990, db.retry)
endif
date.str = sprintf$("%D(%02d/%02m/%04Y)", tdtcd991.lldt)
| tdtcd991.npwc = tdtcd991.lpwc + 30 | Add next pwc date
message( "Welcome "&logname$&", This is your login no "&str$(no.of.logins + 1)&" you are allowed max "&str$(tdtcd991.maxl)&" logins")
if date.num() >= tdtcd991.npwc then |time to Change password
ret = shell( "passwd",SHELL_CONFIRM)
if ret = 0 then |Password successfully changed
tdtcd991.lpwc = date.num() |Capture password change date
tdtcd991.npwc = tdtcd991.lpwc + 30 |Next change on
endif
endif
tdtcd991.lldt = date.num() | Last Login date
tdtcd991.lltm = time.num() | Last login Time
tdtcd991.nolg = tdtcd991.nolg + 1 | Number of logins till date
db.update(ttdtcd991, db.retry)
selectempty
message( "Welcome "&logname$&", This is your login no "&str$(no.of.logins + 1)&" you are allowed max "&str$(tdtcd991.maxl)&" logins")
tdtcd991.user = logname$
tdtcd991.lpwc = date.num() | Assume today as lastpw change if first time login
tdtcd991.npwc = tdtcd991.lpwc + 30 | Add next pwc date
tdtcd991.lldt = date.num() | Last Login Date
tdtcd991.lltm = time.num() | Last Login Time
tdtcd991.nolg = tdtcd991.nolg + 1 | no of logins till date
tdtcd991.maxl = 1 | Default Only 1 login allowed
db.insert(ttdtcd991, db.retry)
endselect
commit.transaction()
bms.add.mask("bms.shutdown") | to detect the shutdown event which is sent by the system
while true
bucket = bms.receive$()
if bucket = "bms.shutdown" then
remove.user.from.990()
exit(0)
endif
endwhile
endif
}
function remove.user.from.990()
{
select tdtcd990.*
from tdtcd990 for update
where tdtcd990.user = :logname$
and tdtcd990.pid = :user.bshell.pid
selectdo
db.delete(ttdtcd990, db.retry)
endselect
commit.transaction()
}
function kill.and.exit()
{
i = 1
procid = -1
procid = pstat(procid, progname, info )
while procid > 0
proclist(i) = procid
i = i + 1
procid = pstat( procid, progname, info )
endwhile
for j = i to 1 step -1
if proclist(j) <> pid then | Keep current process active so that we can remove everything and then
kill(proclist(j)) | display message
endif
endfor
message( " *** LOGIN DISSALLOWED : "&logname$&", you have already logged in "&str$(no.of.logins)&" times, you are allowed max "&str$(tdtcd991.maxl)&" logins")
kill(pid)
}
function remove.user.from.990.if.disconnected()
{
select tdtcd990.*
from tdtcd990 for update
where tdtcd990.user = :logname$
selectdo
ret = shell( "ps -p "&str$(tdtcd990.pid),SHELL_NO_OUTPUT) | Check if process active at OS level
if ret <> 0 then | Process does not exist at OS Level, probably killed or disconnected
db.delete(ttdtcd990, db.retry) | Delete from ligins table if bshell pid not found
endif
endselect
commit.transaction()
}
Note : When you need a situation when no one should log into baan just change tdtcd991.maxl field to 0 for all users except yourself ;-), this will not allow anybody else to login.