dhnish
25th January 2003, 05:07
Hi

Hope someone can assist me. Is there a tool which I could use
to monitor number of users logged into Baan sorted by Department ????
Pls assist . Thank you and have a nice day

Yours in service
.d

Paul P
25th January 2003, 05:24
Dear .d,

You can use something similar to licmon.exe that BaanERP provides for NT boxes in your {$BSE}\bin directory. It doesn't sort by department, however, unless your user IDs contain departmental coding too. If you don't have too many users, probably no departmental sorting is still bearable

Rgds,
Paul

victor_cleto
26th January 2003, 22:01
There are always ways to get information if you know exactly what you are looking for and how to get it...
The users in Baan are or super or normal users. How do you know that a user is from a certain department, special login coding, special name when created in UX and/or Baan, special authorizations?

dhnish
28th January 2003, 06:17
Hi

Thanks guys.
Well appreciated

Old Vens
28th January 2003, 08:34
Hi,
You can also add the department code in /etc/passwd in GECOS field (it is a comment field) and with the help of a small shell script you can easily monitor who is logged in from what departments. It is also helpful when your company is lacking licences to provide every department to work only in their schedule time.
:)

dhnish
29th January 2003, 03:13
Hi

Dear Old Vens,

Received your reply.
Yes, i was able to add into the 'comment field' . But I dont' understand about the script you mentioned. Furthermore with this , can I use licmon6.1 to monitor OR need I use something else?
Pls help................

ps: perhaps if you could help me with the script I would be able to understand better.

Thank you and have a nice day

Yours in service
.d

Old Vens
29th January 2003, 08:14
Hi,

Frankly speaking there are several scripts providing this kind of monitoring. The idea is first scanning all OS ps grepping bshells among them then remember the needed fields (awk can help) then scanning /etc/passwd and sending to the output its contents matching working bshells. Finally the sort is needed in order to see the result in proper way.

suhas-mahajan
29th January 2003, 10:18
Dear,

I faced same problem but finally succeed, We are having three different plants at diffrent locations, diffrent department and contact nos.
I created a master table with login code, name, dept, contact no. fields. Using licmon, I have taken out to a text file and later file to table. Using same logic, I have given facilities like send message, kill session, print reports etc.

-Suhas

dhnish
29th January 2003, 10:49
Hi

Dont' quite understand why you need to create a table ?
At end of the day is this being monitored by end-users or by
administrators ?
Apologize for any inconvenience caused , i'am new...
Pls assist

suhas-mahajan
29th January 2003, 11:52
Dear Dhnish,

It is only for Administrators, I made a menu driven program and everytime it refreshes when you select any option.

-Suhas

tokselampit
24th April 2003, 07:33
Hi,

I use a script "login_user" in my server (hp-ux) to list BaaN users by their respective departments. I've attached a screen-shots for viewing.

Basically, the login_user scripts gives u the no. of ascii & gui BaaN users in each department and the details of who is log in.

If this is what you are looking for, then I will be gladly give u the scripts for testing.

regards,

Mok

amarpreet
24th April 2003, 09:55
Dear Suhas,

Can u please elaborate how u have written that session & how ur using it through licmon. I found it very intersting , will be thankful if u can provide a detailed documentation.

suhas-mahajan
25th April 2003, 08:14
Hi Amarpreet,

Really it is very interesting. This utility act as a BaaN Administrator. Which will facilitates to select a active user or all users, send a message to selected user or all users, display users log on date, time, server name etc. info., display opened session(s) for particular or all users by entering random criteria. It also facilitates to kill particular active BaaN user or specific session or all users with specific session. It can give plant-wise, department-wise, active user list with his contact no. It has good User Interface and tough security to not work on other server. This is frequently being used.

Please find attached herewith screenshot of small tool of this utility called "Plantwise, Deptwise active user list."

How I made this, I already wrote.

-Suhas
:)

amarpreet
25th April 2003, 08:29
Dear Suhas

I am unable to find any attachment. I think u just missed to attach it.

Thanks again.

How is Aurangabad. It must be too hot these days there.

suhas-mahajan
25th April 2003, 08:50
Hi Amarpreet, (Your name is good)

No, because of size it is not accepted, I converted it in .jpg, please find now.

Aurangabad is good, yes, it is hot upto 44, but rarely I come across.

-Suhas:)

sibon1
25th April 2003, 09:10
i have written my own program using native baan. you can see all active baan user by company; you can sort them by processID, UserID, LogonDate and Company; you also can kill a specific process or send a notice to a active user; if you wish, you can see the open sessions of a user.

You can find the source in the Code & Utilities forum right here (http://www.baanboard.com/baanboard/showthread.php?s=&threadid=9763)

it works good and fast for me on Windows 2000 Server; i never tested it on Unix.

Josef N.

--
Admin comment: moved the source code to the Code & Utilities forum and linked from here

learner
3rd May 2003, 20:26
Could u attach the script for this small utility which seems to be very useful !!

evertsen
4th May 2003, 00:28
Learner, follow the link in sibon1's last post above.

learner
4th May 2003, 12:28
Thanks, yaah i found the link to the script, but some words i can't understand since those r not english words, seems portugese.

Can it be converted into english ?

Regards

Learner

victor_cleto
7th May 2003, 20:43
I can positively confirm that it is not portuguese :)

patvdv
8th May 2003, 00:08
Mmm Victor, are you sure the version of Pedro Sousa isn't portuguese? :)

Josef's version is in German by the way. Maybe if you ask the authors nicely, they will translate their work.

chjagge
17th May 2003, 00:13
I've done this using a combination of C using the ci_server, shell scripts and a in house written Baan dll. There are three levels of monitoring and I lock down any user/department/company I need to.
1) by Company,
2) Cost Center (dept)
3) User.

Do a search on chjagge in this forum and you should find the scripts I posted up. If you cannot find it I can post it again.

learner
17th May 2003, 20:37
Hi,

Kindly post the script , although i searched through that keyword but i could only only find the screen shots of the system ( jpg image) & not the actuall script.

Waiting for your reply.

Regards

Learner

evertsen
18th May 2003, 06:24
I believe this is the post chjagge is referring to License (http://www.baanboard.com/baanboard/showthread.php?s=&postid=30782#post30782). It contains the code for the dll.

learner
18th May 2003, 06:45
Thanks i will go through the script.

Regards

Learner

chjagge
23rd June 2003, 19:57
Sorry for taking so long to responed to you. Here is the C program

#include <stdio.h>
#include <string.h>
long check_login(int flogin); /* Baan dll login_dll */
long baan_logout(); /* Baan dll login_dll */
void log_in(int flogin);
void log_out();

int main (argc, argv)
int argc;
char *argv[];
{
int i_login;
i_login = atoi(argv[2]);
i_login--;
start_ci( argv[0] );
if ((strcmp(argv[1], "in")) == 0)
{
log_in(999);
}
else
{
if ((strcmp(argv[1], "out")) == 0)
{
log_out();
}
else
{
if ((strcmp(argv[1], "re")) == 0)
{
log_in(i_login);
}
}
}
stop_ci();
return 0;
}

void log_in(int flogin)
{
long retval;
retval = check_login(flogin);

switch (retval)
{
case 1:
printf("1");
break;
case 2:
/* printf("Login at this time not possible.\n"); */
/* printf("Max users for your department has been reached\n"); */
printf("2");
break;
case 3:
/* printf("Missing Cost Center\n"); */
printf("3");
break;
case 4:
/* printf("Number of licences assigned to you exceeded\n"); */
printf("4");
break;
case 5:
/* printf("User missing from logon - Cost Center file\n"); */
printf("5");
break;
case 6:
/* printf("You have exceeded the Company login limit\n"); */
printf("6");
break;
default:
printf("0");
/* printf("Invalid Code\n"); */
break;
}
}

void log_out()
{

long retval;
retval = baan_logout();

if (retval == 7)
{
printf("7");
}
else
{
printf("1");
}
}

Here is the Baan dll

|******************************************************************************
|* tctkndll0002 0 VRC B40O c2 bta0
|* Evaluate Login
|* bsp
|* 06-07-02 [08:02]
|******************************************************************************
|* Script Type: Library
|******************************************************************************
|******************************************************************************
|* tctkn9201 0 VRC B40O c2 bta0
|* Update User logon reference counter
|* Christopher R Jaggernauth
|* 2002-03-08
|******************************************************************************
|* Main table tctkn021 User logon reference counter, Form Type 4
|******************************************************************************

|****************************** declaration section ***************************

table ttctkn021 | User logon reference counter
table ttctkn022 | Cost Center Max Users
table ttctkn023 | License Usage Limit by Company
table ttctkn024 | Parent Company - SubCompany Link
table tttaad200 | User Data

domain tcmcs.str12 user.f fixed
domain tcmcs.str12 user.t fixed
domain tcmcs.long maxusers.w
domain tfgld.dimx costcenter.w
domain tcmcs.long comp.users
domain tfgld.dimx parent.comp
string buf.tctkn021(1) based

#include "/baan/bse/application/tcB40O_c2_bta0/ptctkn/ptkndll00010"

function extern long baan_logout()
{

long count
long ret

ret = 1
user.f = strip$(logname$)
user.t = strip$(logname$)
db.retry.point()

select tctkn021.*
from tctkn021 for update
where tctkn021._compnr = 100
and tctkn021._index1 inrange {:user.f}
and {:user.t}
order by tctkn021._index1
selectdo
| update set
if tctkn021.logc > 0 then
tctkn021.logc = tctkn021.logc - 1
db.update(ttctkn021, db.retry)
endif
count = count + 1
if count > 50 then
count = 0
commit.transaction()
endif
selectempty
ret = 7
| message("User Missing from Logon - Cost Center file")
endselect

commit.transaction()
return(ret)
}

function extern long check_login(long flogin)
{
long count
user.f = strip$(logname$)
user.t = strip$(logname$)
long ret

ret = 1 | true and allow login if ret is 1
db.retry.point()

|*** Re align login count with that in UNIX
if flogin <> 999 then
select tctkn021.*
from tctkn021 for update
where tctkn021._compnr = 100
and tctkn021._index1 inrange {:user.f}
and {:user.t}
order by tctkn021._index1
selectdo
tctkn021.logc = flogin
db.update(ttctkn021, db.retry)
commit.transaction()
selectempty
endselect
endif
|*** Above select re-align login counts with that on UNIX

select tctkn021.*
from tctkn021 for update
where tctkn021._compnr = 100
and tctkn021._index1 inrange {:user.f}
and {:user.t}
order by tctkn021._index1
selectdo
| update set
if (tctkn021.conu > tctkn021.logc) then
costcenter.w = tctkn021.dimx
sum.users.for.cost.center()

select tctkn022.*
from tctkn022
where tctkn022._compnr = 100
and tctkn022._index1 = {:costcenter.w}
selectdo
if tctkn022.maxu > maxusers.w then
sum.users.for.company()
if under.company.max() then
ret = 1 | Used only for emphasis since already initialized above
tctkn021.logc = tctkn021.logc + 1
db.update(ttctkn021, db.retry)
else
| message("Login at this time is not possible. Max users for company has been reached")
ret = 6
endif
else
ret = 2
| message("Login at this time is not possible. Max users for your department has been reached")
endif
selectempty
ret = 3
| message("Missing Cost Center")
endselect

count = count + 1
if count > 50 then
count = 0
commit.transaction()
endif
else
ret = 4
| message ("Number of licenses assigned to you exceeded. Limit - " & str$(tctkn021.conu) & " licenses")
endif

selectempty
ret = 5
| message("User Missing from Logon - Cost Center file")
endselect

commit.transaction()
return (ret)
}

function sum.users.for.cost.center()
{
select sum(tctkn021.logc):maxusers.w
from tctkn021
where tctkn021._compnr = 100
and tctkn021._index2 = {:costcenter.w}
selectdo
endselect
}

function sum.users.for.company()
{
domain tcncmp save.comp
domain tcncmp user.comp
long len.tctkn021

db.row.length(ttctkn021, len.tctkn021)
alloc.mem(buf.tctkn021, len.tctkn021)
buf.tctkn021 = rcd.ttctkn021
comp.users = 0
save.comp = get.compnr()
select tctkn024.*
from tctkn024
where tctkn024._compnr = 100
and tctkn024._index1 = {:save.comp}
selectdo
parent.comp = tctkn024.pcmp
selectempty
parent.comp = ""
endselect

select tctkn021.*
from tctkn021
where tctkn021._compnr = 100
order by tctkn021._index1
selectdo
select ttaad200.*
from ttaad200
where ttaad200._compnr = 0
and ttaad200._index1 = {:tctkn021.user}
selectdo
user.comp = ttaad200.comp
select tctkn024.*
from tctkn024
where tctkn024._compnr = 100
and tctkn024._index2 = {:parent.comp, :user.comp}
order by tctkn024._index2
selectdo
comp.users = comp.users + tctkn021.logc
endselect
endselect
endselect
rcd.ttctkn021 = buf.tctkn021
free.mem(buf.tctkn021)
}

function domain tcbool under.company.max()
{
select tctkn023.*
from tctkn023
where tctkn023._compnr = 100
and tctkn023._index1 = {:parent.comp}
order by tctkn023._index1
selectdo
if tctkn.dll0001.decrypt(tctkn023.musr, tctkn023.pcmp) >
comp.users then
return(true)
endif
endselect
return(false)
}

Here is the makefile:
LD=${BSE}/api/lib
CFLAGS=-g -I${BSE}/api/include
LINKFLAGS=-g
CC=cc

BIC=bic6.1
BIC_CSTUB=bic_cstub6.1
BICFLAGS=
BICINCL=-I ${BSE}/gfd

all: ci_login

ci_login: ci_login.o c_login_dll.o
${CC} ${LINKFLAGS} ci_login.o c_login_dll.o \
${LD}/libci.a \
${LD}/libalbsh.a \
${LD}/libipc.a \
${LD}/libtss.a \
${LD}/libyybsh.a \
${LD}/libhal.a \
${LD}/libalbsh.a \
-lm -o $@

ci_login.o: ci_login.c
${CC} -c ${CFLAGS} ci_login.c -o $@

c_login_dll.o: c_login_dll.c
${CC} -c ${CFLAGS} c_login_dll.c -o $@

c_login_dll.c: qloginobj_dll
${BIC_CSTUB} -s -d qloginobj_dll -o $@

qloginobj_dll: login_dll
${BIC} ${BICFLAGS} login_dll -o $@

clean:
rm -f ci_login ci_login.o c_login_dll.o c_login_dll.c qloginobj_dll

Here is the unix script .profile
PATH=$HOME/bin:${PATH:-/usr/bin:.}
export PATH
stty dec
tset -I -Q
PS1="`hostname`:$LOGNAME> "
MAIL=/usr/spool/mail/$USER
pwd

BSE=/baan/bse
BSE_TMP=/baan/bse/tmp
BSE_SORT=/baan/bse/tmp
PATH=$BSE/bin:$PATH
TERM=vt100
export BSE BSE_TMP BSE_SORT PATH TERM
SKIP_FIN_POST=TRUE
export SKIP_FIN_POST
umask o+rw
stty erase "^H"
cd /usr/users/licmon/loginscr
COUNT=0
UCOUNT=0
COUNT=`ci_login in $UCOUNT`
if [ $COUNT -gt 1 ]; then
BCOUNT=`ps -ef|grep bisam|grep $USER|wc -l`
ICOUNT=`ps -ef|grep informix|grep $USER|wc -l`
if [ $BCOUNT -gt $ICOUNT ]; then
UCOUNT=$BCOUNT
else
UCOUNT=$ICOUNT
fi
echo Rebuild reference count for $USER and retrying login sequence.
COUNT=0
COUNT=`ci_login re $UCOUNT`
fi
if [ $COUNT -eq 4 ]; then
ba6.1 tctknt202m000
COUNT=8
fi
if [ $COUNT -eq 1 ]; then
ba6.1
COUNT=`ci_login out 99`
if [ $COUNT -eq 7 ]; then
echo Login missing from Cost center table
fi
cd /usr/users/bsp
elif [ $COUNT -eq 2 ]; then
echo Login at this time not possible. Max Users for your department has been
reached
sleep 5
elif [ $COUNT -eq 3 ]; then
echo Missing Cost Center
sleep 5
elif [ $COUNT -eq 4 ]; then
echo Number of licenses assigned to you has been exceeded!!!!
sleep 5
elif [ $COUNT -eq 5 ]; then
echo User Login does not exists in Cost Center File
sleep 5
elif [ $COUNT -eq 6 ]; then
echo Company login limt has been exceeded
sleep 5
elif [ $COUNT -eq 0 ]; then
echo Invalid Parameter
sleep 5
fi
exit


Here is the encryption dll.
function extern long tctkn.dll0001.decrypt(string in.code(12), string key(6))
| The function takes an 8-character string and converts back to a number. If
| the convertion fails, the function returns the value -1.
{
long check.total
long curr.num
long i
long key.num
long return.val
long total.num

if session.found() then
check.total = 0
total.num = 0
key.num = 0
for i = 1 to 6
key.num = key.num + asc(key(i;1))
endfor
for i = 1 to 7
curr.num = (asc(in.code(i + 1;1)) - 66) / 2
check.total = check.total + curr.num
total.num = total.num + curr.num * lpow(13, 7 - i)
endfor
if asc(in.code(1;1)) - 65 <> (check.total \ 26) then
return(-1)
endif
return.val = total.num - key.num * 100000
if return.val < 0 then
return.val = -1
endif
return(return.val)
endif
return(-1)
}

function extern string tctkn.dll0001.encrypt(long in.num, string key(6))
| The function encrypt takes a non-negative number (in.num) and converts it
| into an 8-character string. A key is used for encryption/decryption.
{
long check.total
long curr.num
long encrypt.num
long i
long key.num
string return.str(8)

if session.found() then
check.total = 0
key.num = 0
for i = 1 to 6
key.num = key.num + asc(key(i;1))
endfor
encrypt.num = key.num * 100000 + in.num
for i = 1 to 7
curr.num = encrypt.num / lpow(13, 7 - i)
return.str(i + 1;1) = chr$(66 + curr.num * 2)
check.total = check.total + curr.num
encrypt.num = encrypt.num \ lpow(13, 7 - i)
endfor
return.str(1;1) = chr$(65 + check.total \ 26)
return(return.str)
endif
return("")
}

function domain tcbool session.found()
{

on case prog.name$
case "tctkn9201s000":
case "tctkn9203s000":
case "tctknt104m000":
case "ottstpciserver":
return(true)
default:
endcase
return(false)
}

Here is tctknt202m000:
|* tctknt202 0 VRC B40O c2 bta0
|* Terminate user Baan session
|* Christopher Jaggernauth
|* 2002-07-24
|******************************************************************************
|* Main table tctkn021 User logon reference counter, Form Type 4
|******************************************************************************

|****************************** declaration section ***************************
declaration:
extern domain tcmcs.str12 user.w fixed


|****************************** form section **********************************

form.1:
init.form:
get.screen.defaults()
user.w = logname$
display("user.w")
refresh()

|****************************** choice section ********************************

choice.cont.process:
on.choice:
read.main.table()

|****************************** function section ******************************

functions:

function read.main.table()
{
long ret.val
if (ask.enum("tdilc40079", tcyesno.no) = tcyesno.yes) then
ret.val = shell ("kill `ps -efu $LOGNAME|grep -v grep|grep -w -f /usr/users/licmon/loginscr/bshell.dat|awk '{print $2}'`", SHELL_NO_OUTPUT)
endif
}

Hope this helps. Have fun.

vishbaan
24th October 2005, 15:11
hi suhaas

on the license utility, it is quite useful; sometimes back we were forced with similar situation to have licenses allocated by company. I attempted the similar way and added the program in bms mask during boot time to check the user dept and total dount for the user dept. etc..

since I could not cope up with the shell, run prog commands could not quite well do it;

would you mind giving me a dump of these components you did in baan.

thanks

VISH

ganesh_kapase
28th October 2005, 21:19
Hi Suhas

It seems your utility is good. Can we allocate users locationwise / departmentwise ? I mean to say suppose we are having 20 licenses and having 10 departments. And if we want to allocate 2 users to each department can we do it ?

If not tell me alternates if any.


Regards,


GANESH - Kolhapur
(Can u remember me, we had telephonic conversation in few months back)

suhas-mahajan
31st October 2005, 10:32
Vish,

Yes, M$ systems lacking scipting too much, batch programming has so many limitations. In Unix/Linux, you can hold and initialize logged on user ID and use it for external programs using BMS mask or IPCINFO.

Unfortunately, this is not developed using BaaN scripting. This is a DOS based external program, internally uses licmon.exe, bshcmd.exe and few exe's downloaded from www.sysinternal.com to run it on client side.

Ganesh,

Thanks for the compliments, This utility can not allocate licences locationwise / dept. wise. It is post event trapping and 99% real time monitoring tool. But, later you can monitor it and send messages to users to logged out or can ring them seeing extension no. or kill them, if they are not using maintain sessions.

If you are facing licence distribution problem, you can configure session_timeout mechanism into dbresource file. This definately helps you lot.

Yes, I recognised and remember you.

Regards & Happy Diwali to everybody.

-Suhas

chjagge
31st October 2005, 15:35
The script I posted above can allocate by department, companies. You can shut down a department eg Finance whenever finance to run a rebuild on finance only without affecting the rest of the company. It takes a bit of implementation but it works well.

mama123
13th November 2007, 02:35
Hi there,

may i know how to kill or kick the user from the licmon?
the incident was the user pc hang, so the baan license still hanging in licmon and it do not clear off, need to wait for more than 1/2 hours only disappear from the licmon.

pls advice

thanks

nice day

suhas-mahajan
13th November 2007, 06:29
Hi,

Please refer to -

1. http://www.baanboard.com/baanboard/showthread.php?t=25098&highlight=licmon

2. http://www.baanboard.com/baanboard/showthread.php?t=12824&highlight=licmon

3. http://www.baanboard.com/baanboard/showthread.php?t=28142&highlight=licmon

Hope this helps.

regards,

-Suhas

ahmer91
13th November 2007, 08:27
there is a command in unix that will show you the list of all the users logged into to baaan

# ps -ef |grep baan

but you will not be able to sort out by company.

mama123
30th November 2007, 09:59
hi there,

is there any idea to restrict the user login more than 1 time?
i wanna restrict the the user login 1 Baan, do not allow them login 2 Baan using the same user ID, bcos lack of license issues.

thanks for help

victor_cleto
30th November 2007, 17:48
Search the threads for killing users and restrict logins.
These 2 topics have been very well discussed all over the Tools section (for UNIXes and even Windows), please do not ask the same questions over and over again - search first and read as much as possible.