MFG menu security

peter_f

New Member
Hi all,

I already searched all the existing posts about menu security reports in MFG, but couldn´t find any satisfying answer.
Is there really no existing program, that is able to list a users effective access to any menu option. I found some programs, that list menus an user has access to. But these programs do not take care, that perhaps a user has access to a sub-menu, but not to the previous menu.
For example, user a has theoretically access to sub-menu 3.4.1, but not to menu 3.4, so he at least is not even able to access 3.4.1. Isn´t there a program, that is able to cope with this and list only those menus a user really can access?
Additionaly the program should be able to list a users really permissions to a menu option due to a group-membership.

We are using MFG 7.x with security option "P" enabled.

Thanks for your replies.

Peter
 
Hi Peter,

I have a few examples of code that i use:

/* xxseciq.p */
/*V8:ConvertMode=Report */
{mfdtitle.i "A"}
DEFINE VARIABLE nbr# LIKE mnd_nbr NO-UNDO.
DEFINE VARIABLE users# AS CHARACTER NO-UNDO
VIEW-AS EDITOR SIZE 60 BY 1.
DEFINE TEMP-TABLE u# NO-UNDO
FIELD u_user_groups AS CHAR
FIELD u_userid AS CHAR
INDEX i1 IS PRIMARY UNIQUE u_userid.
define NEW shared variable menu as character.
DEFINE NEW SHARED VARIABLE GLOBAL_user_groups AS CHARACTER.
DEFINE VARIABLE ogroups AS CHAR NO-UNDO.
DEFINE VARIABLE oid AS CHARACTER NO-UNDO.
DEFINE VARIABLE omenu AS CHARACTER NO-UNDO.
DEFINE VARIABLE ok# AS LOGICAL NO-UNDO.
FORM
nbr# COLON 20
WITH FRAME a SIDE-LABELS WIDTH 80.
ogroups = global_user_groups.
oid = GLOBAL_userid.
FOR EACH usr_mstr NO-LOCK:
CREATE u#.
ASSIGN
u_userid = usr_userid
u_user_groups = usr_groups.
END.
REPEAT:
UPDATE
nbr#
WITH FRAME a SIDE-LABELS.
{mfselbpr.i "printer" 132}
FOR EACH mnt_det WHERE mnt_nbr BEGINS nbr#
AND mnt_lang = GLOBAL_user_lang NO-LOCK:
users# = "".
FOR EACH u#:
ASSIGN
GLOBAL_user_groups = u_user_groups
GLOBAL_userid = u_userid.
{gprun.i ""mfsec.p"" "(input mnt_nbr, input mnt_sel, input false, output ok#)"}
IF ok# THEN
IF users# = "" THEN
users# = u_userid.
ELSE
users# = users# + ", " + u_userid.
END.
DISP mnt_nbr mnt_sel mnt_label users# WITH WIDTH 132.
END.
ASSIGN
GLOBAL_user_groups = ogroups
GLOBAL_userid = oid.

{mfreset.i}
END.
ASSIGN
GLOBAL_user_groups = ogroups
GLOBAL_userid = oid.

This one more or less does what you want:
/* xxseciq.p */
/*V8:ConvertMode=Report */
{mfdtitle.i "A"}
DEFINE VARIABLE nbr# LIKE mnd_nbr NO-UNDO.
DEFINE VARIABLE users# AS CHARACTER NO-UNDO
VIEW-AS EDITOR SIZE 60 BY 1.
DEFINE TEMP-TABLE u# NO-UNDO
FIELD u_user_groups AS CHAR
FIELD u_name AS CHAR
FIELD u_userid AS CHAR
INDEX i1 IS PRIMARY UNIQUE u_userid.
define NEW shared variable menu as character.
DEFINE NEW SHARED VARIABLE GLOBAL_user_groups AS CHARACTER.
DEFINE VARIABLE filnavn AS CHARACTER NO-UNDO FORMAT "x(40)" INIT "P:\usrsec.csv".
DEFINE VARIABLE ogroups AS CHAR NO-UNDO.
DEFINE VARIABLE oid AS CHARACTER NO-UNDO.
DEFINE VARIABLE omenu AS CHARACTER NO-UNDO.
DEFINE VARIABLE ok# AS LOGICAL NO-UNDO.
FORM
nbr# COLON 20
filnavn COLON 20
SKIP(.2)
WITH FRAME a SIDE-LABELS WIDTH 80.
ogroups = global_user_groups.
oid = GLOBAL_userid.
FOR EACH usr_mstr NO-LOCK:
CREATE u#.
ASSIGN
u_name = USR_name
u_userid = usr_userid
u_user_groups = usr_groups.
END.
REPEAT:
UPDATE
nbr#
filnavn
WITH FRAME a SIDE-LABELS.
OUTPUT TO VALUE(filnavn) CONVERT TARGET "ISO8859-1".
users# = "".
FOR EACH u#:
ASSIGN
GLOBAL_user_groups = u_user_groups
GLOBAL_userid = u_userid.
FOR EACH mnt_det WHERE mnt_nbr = nbr#
AND mnt_lang = GLOBAL_user_lang NO-LOCK:
{gprun.i ""mfsec.p"" "(input mnt_nbr, input mnt_sel, input false, output ok#)"}
IF ok# THEN
EXPORT DELIMITER ";"
u_name
u_userid
mnt_nbr
mnt_sel
mnt_label.
END.
END.
ASSIGN
GLOBAL_user_groups = ogroups
GLOBAL_userid = oid.

OUTPUT CLOSE.
END.
ASSIGN
GLOBAL_user_groups = ogroups
GLOBAL_userid = oid.

This one is actually very usefull:
/* xxaccess.p */
/*V8:ConvertMode=Report */

/********************* RAPPORT KOMMENTAR START ******************
* Filnavn : xxaccess.p
* Type : Rapport
********************** RAPPORT KOMMENTAR SLUT *****************/

{mfdtitle.i "a"}

DEFINE SHARED VARIABLE global_user_groups AS CHARACTER FORMAT "x(60)" LABEL "Grupper".

DEFINE VARIABLE test_menu AS CHARACTER LABEL "Menu" FORMAT "x(10)".
DEFINE VARIABLE test_item AS CHARACTER LABEL "Programnummer" FORMAT "x(10)".
DEFINE VARIABLE test_prog AS CHARACTER LABEL "Programnavn/Overmenu" FORMAT "x(10)".
DEFINE VARIABLE through AS CHARACTER LABEL "Gennem" FORMAT "x(10)".

DEFINE VARIABLE mn-pgm-name AS CHARACTER NO-UNDO LABEL "Pgm name".
DEFINE VARIABLE mn-pgm-title AS CHARACTER NO-UNDO LABEL "Pgm titel".
DEFINE VARIABLE mn-passedSecurity LIKE mfc_logical NO-UNDO LABEL "Passedsecurity".
DEFINE VARIABLE mn-isaprogram LIKE mfc_logical NO-UNDO LABEL "Is a program".
DEFINE VARIABLE mn-valid LIKE mfc_logical NO-UNDO LABEL "Is a valid menu".
DEFINE VARIABLE current_user# AS CHARACTER.
DEFINE VARIABLE current_user_grp# AS CHARACTER.
DEFINE VARIABLE program AS CHARACTER.
DEFINE VARIABLE useraccess AS LOGICAL.

DEFINE VARIABLE menuer LIKE mfc_logical init true.
DEFINE VARIABLE bruger LIKE mfc_logical init false.

DEFINE TEMP-TABLE check_menus
FIELDS check_nbr LIKE mnd_nbr
FIELDS check_select LIKE mnd_select
INDEX check_indx1 AS PRIMARY UNIQUE check_nbr check_select.

FORM
SKIP(.4)
test_menu COLON 25
test_item COLON 25
SKIP(.4)
"eller" COLON 25
SKIP(.4)
test_prog COLON 25
" Ved programnavn, husk .p"
SKIP(.4)
menuer colon 25 label "Vis Menuer"
skip(.4)
bruger colon 25 label "Vis Bruger"
WITH FRAME A WIDTH 80 SIDE-LABELS.


REPEAT:

FOR EACH check_menus EXCLUSIVE-LOCK: DELETE check_menus. END.

UPDATE
test_menu
test_item
test_prog
menuer
bruger
WITH FRAME A.

current_user# = global_userid.
current_user_grp# = global_user_groups.


IF test_prog = "" THEN
DO:
FIND mnd_det NO-LOCK
WHERE mnd_nbr = test_menu
AND STRING(mnd_select) = test_item NO-ERROR.
IF AVAILABLE(mnd_det) THEN program = substring(mnd_exec,1, r-index(mnd_exec, ".")).
ELSE
DO:
MESSAGE "Menu item not found!".
UNDO, RETRY.
END.
END.
ELSE
DO:
FIND FIRST mnd_det NO-LOCK
WHERE mnd_exec = test_prog NO-ERROR.
IF AVAILABLE(mnd_det) THEN program = mnd_exec.
ELSE
DO:
MESSAGE "Program" test_prog " not found!".
UNDO, RETRY.
END.
END.

program = substring(mnd_exec,1, r-index(mnd_exec, ".")).

/* QUOTE DATA */
bcdparm = "".
{mfquoter.i test_menu }
{mfquoter.i test_item }
{mfquoter.i test_prog }
{mfquoter.i menuer }
{mfquoter.i bruger }

/* Vlg. Print device */
{mfselbpr.i "printer" 80}

FOR EACH mnd_det NO-LOCK
WHERE mnd_exec begins program:
CREATE check_menus.
ASSIGN check_nbr = mnd_nbr.
ASSIGN check_select = mnd_select.

if menuer then
do:
find mnt_det where mnt_lang = "DA" and mnt_nbr = mnd_nbr and mnt_select = mnd_select no-lock no-error.
DISPLAY
MND_NBR
MND_SELECT
mnt_label when available mnt_det
with width 80.
end.
END.


{mfphead2.i}

DO TRANSACTION:

if bruger then
FOR EACH usr_mstr NO-LOCK:

global_userid = usr_userid.
global_user_groups = usr_groups.

useraccess = FALSE.
through = "".
FOR EACH check_menus NO-LOCK:
/*G1VJ*/{gprun1.i ""mfsec.p"" "(INPUT check_nbr,
/*G1VJ*/ INPUT check_select,
/*G1VJ*/ INPUT FALSE, /* DISPLAY ERROR */
/*G1VJ*/ OUTPUT mn-passedSecurity)"
/*G1VJ*/}
IF mn-passedSecurity THEN
DO:
useraccess = TRUE.
through = check_nbr + "." + string(check_select).
leave.
END.
END. /* FOR EACH check_menus */

IF useraccess THEN
DISPLAY
global_userid LABEL "Bruger"
global_user_groups LABEL "som er medlem af..." FORMAT "x(57)"
through
WITH WIDTH 80.

END. /* FOR EACH */
END. /* TRANSACTION */

global_userid = current_user#.
global_user_groups = current_user_grp#.

{mfrtrail.i}
END. /* REPEAT */

I hope you can use this.

Ole
 
Hi Ole,

thanks a lot for your programs, I´m pretty sure they will help me further on.
But could you please provide me also the external program "mfsec.p", that you´re using in your programs? It seems, this program is part of newer MFG versions, cause I can´t find it anywhere in our version 7.3.

Cheers

Peter
 
Hi Peter,

I can't give you mfsec.p (qad property) - but you can create your own. I am not totaly sure how the security worked back in 7.3 - Did they have security groups or was it just pass in mnd_det.

if it only was passwords in mnd_det then the code should be something like:
if global_sec_opt = "P" then can-do(mnd_canrun + ",!*", global_passwd)
else can-do(mnd_canrun + ",!*", global_userid)

I hope this will help you.

I think maybe you have an include file called mfsec.i, otherwise look in mfmenu.p and look for mnd_canrun

Ole
 
Back
Top