/*---------------------------------------------------------------------------*\
|   SET all access control profiles to  a LS 3.0 and higher                   |
|   from an ASCII file                                                        |
|       (C) Alain Rykaert IBM Belgium & Hermann Pauli IBM Germany SEP95-MAY96 |
\*---------------------------------------------------------------------------*/

    Parse Arg Option

    Call INIT                     /* Initalisation of DLL's and other stuff*/
    Call CHKOPT                          /* Check Options & display welcome*/
    Call CHKPWS                               /* Check the PWS & Admin name*/
    Call MAIN                                            /* do the main job*/
    Call CHECKERR                                       /* check for Errors*/
    Call QUIT                                                       /* Quit*/

 MAIN:/* ------------------------------------------------------ MAIN: -------*/

    Call Time('R')
   'if exist' CHKF 'del' CHKF
    EC    = 0
    Apply = 0                                        /* no Apply by default*/
    ExitCode = X2D('FE00')                          /* Good CID Return code*/

    do while Lines(INPF)
       LLINE = strip(TRANSLATE(LineIN(INPF)))
       OLINE = LLINE
       parse value LLINE with OPT ';' LLINE
       OPT = strip(OPT)
       if length(OPT) >1
        then select
              when OPT = 'UA' | OPT = 'AA' | OPT = 'AU'
               then do
                       Apply = 1                        /* set Apply option*/
                       OPT   = 'U'
               end
              otherwise nop
             end
        else nop

       select
        when OPT = '' | LLINE = ''    then Iterate
        when Left(OPT,1)      = '*'   then Iterate
        when OPT              = 'OPT' then Call COLUMNS
        when OPT              = 'D'   then Call DELACL
        when OPT              = 'A'   then Call UPDACL
        when OPT              = 'U'   then Call UPDACL
        otherwise
         do
            Call LineOut CHKF, OLINE
            Call Logit 'Main' , 'wrong input' , 'invalid option' OPT
         end
       end
       if EC
        then do
                 Call LineOut CHKF, OLINE
                 EC = 0
                 ExitCode = X2D('1604')              /* Bad CID return code*/
             end
        else Nop
    end

    say '0A0909'x 'Total Time  =' Trunc(Time('E'),2)

    Return

 UPDACL: /*---------------------------------------------------- UPDACL: -----*/

    /*   get the new ACL of the actual alias */
    parse value LLINE with Alias ';' ACL.Audit ';' LLINE
    ACL.Audit = strip(ACL.Audit)
    if ACL.Audit = '-NONE-' then ACL.Audit = 'N'

    /* scan through input line to retrieve new ACL assignments         */
    ACLNum = 0

    ACP_Set. = 0
    i = 0
    do while LLine <> ''
       i = i + 1
       UserGroup = UserGroupByCol.i
       parse value LLINE with ActACP ';' LLINE
       ActACP = strip(ActACP)
       if ActACP <> ''
       then do    /* there is an ACP */
               ACLNum = ACLNum + 1
               ACL.ACLNum.UGname  = strip(UserGroup)
               ACL.ACLNum.access  = strip(ActACP)
               ACP_Set.UserGroup = 1
            end
       else nop
    end

    ACL.count = ACLNum

    say '0909'x 'updating Alias ...' Alias

    /* Retrieve info about alias (we need server and path) */
    RC = NetGetInfo(NETALIAS, 'AliasInfo', '\\'SRVNAME, Alias)
    if RC = 0
     then nop
     else do
           call LOGIT 'NetGetInfo Alias' , Alias , RC
           EC = 1
           return
          end

    /* find the correct ressource, dependend on alias type  */
    select
     when AliasInfo.type = 'Files'   then Alias_Res = AliasInfo.path
     when AliasInfo.type = 'Printer' then Alias_Res = '\print\'AliasInfo.queue
     when AliasInfo.type = 'Serial'  then Alias_Res = '\comm\'AliasInfo.queue
     otherwise nop
    end

    /* Get actual ACL for  alias */
    RC = NetGetInfo(NETACCESS, 'O_ACL', '\\'AliasInfo.server, Alias_Res)
    if RC = 0
     then ACL_exists = 1
     else if left(strip(RC),4) = '2222'         /* no ACP found */
           then do
                   ACL_exists  = 0
                   O_ACL.count = 0
                end
           else do
                   call LOGIT 'NetGetInfo ACL' , W_User ||'/'|| Alias , RC
                   EC = 1
                   return
                end

    /*  del existing ACL for alias                             */
    if ACL_exists
     then do
             RC = NetDelete(NETACCESS, '\\'AliasInfo.server, Alias_Res)
             if RC = 0
              then nop
              else do
                      Call LOGIT 'NetDelete ACL' , Alias , RC
                      EC = 1
                     return
                   end

             /*  log deleted audit ?                       */
             if strip(O_ACL.audit) <> '' & strip(Audit) = ''
              then Call LOGIT 'Delete Audit' ,
                              Alias 'Audit ('strip(O_ACL.i.access)')' , ''
              else nop
          end
      else nop


    /*  log deleted assignments                   */
    do i = 1 to O_ACL.count
       UserGroup = O_ACL.i.ugname
       if ACP_Set.userGroup
        then iterate
        else Call LOGIT 'Delete ACP' ,,
                        Alias UserGroup '-' strip(O_ACL.i.access) , ''
    end


    /*  add, update ACPs                          */

    /* no ACL -> create ACL and Add ACPs          */
    RC = NetAdd(NETACCESS,'ACL','\\'AliasInfo.server, Alias_Res)

    if RC = 0
     then do /* log changes */
             call LOGIT 'New Audit' , Alias '-' strip(ACL.audit) , ''
             do i = 1 to ACL.count
                call LOGIT 'New ACP' ,,
                           Alias ACL.i.ugname '-' strip(ACL.i.access) , ''
             end

             if Apply & AliasInfo.type = 'Files'
              then do
                      /* Apply access control profile to resource */
                      RC = NetMisc(NETACCESSAPPLY, 'applyerr',,
                                   '\\'AliasInfo.server, Alias_Res)
                     if RC = 0
                      then call logit 'Apply' , Alias Alias_Res , ''
                      else do
                              call logit 'NetMisc Apply' ,Alias ,,
                              applyerr.error_buf applyerr.error_code RC
                              EC =1
                              return
                           end
                   end
              else nop
          end
     else do /* log error */
             Call LOGIT 'NetAdd ACL' , Alias , RC
             EC = 1
             return
          end
    Return

 DELACL: /*---------------------------------------------------- DELACL: -----*/

    i  = 0
    say '0909'x 'Updating User ...' UserId

    parse value LLINE with Alias ';' .

    /* Retrieve info about alias (we need server and path) */
    RC = NetGetInfo(NETALIAS, 'AliasInfo', '\\'SRVNAME, Alias)
    if RC = 0
     then nop
     else do
           call LOGIT 'NetGetInfo Alias' ,  Alias , RC
           EC = 1
           return
          end


    /* delete access control list */
    RC = NetDelete(NETACCESS, '\\'AliasInfo.server, AliasInfo.path)
    if RC = 0
     then call LOGIT 'Delete ACL' , Alias '- all' , ''
     else do
             Call LOGIT 'NetDelete ACL' , Alias , RC
             EC = 1
             return
          end
    Return

 COLUMNS: /*--------------------------------------------------- COLUMNS: ----*/

    Banner.0 = 3
    Banner.1 = LEFT('*',Length(OLINE),'-')
    Banner.2 = OLINE
    Banner.3 = Banner.1

    UGLst = OPT || ';' || LLINE

    parse value LLINE with . ';' . ';' LLINE

    i = 0
    do while LLine <> ''
       i = i+1
       parse value LLINE with UserGroupByCol.i ';' LLINE
       UserGroupByCol.i = strip(UserGroupByCol.i)
    end
    UserGroupByCol.0 = i /* UserGroupByCol.: user/group name retrieveable    */
                         /*                  via col number                  */

    Return


 CHECKERR: /*-------------------------------------------------- CHECKERR: ---*/

    Call Stream CHKF, 'C', 'CLOSE'
    if \Lines(CHKF)
     then Return
     else do
             do j = 1 to BANNER.0
                Call LineOut 'TEMP', BANNER.j
             end
             i = 0
             do while Lines(CHKF)
                LLINE = LineIn(CHKF)
                Call LineOut 'TEMP', LLINE
                i = i + 1
                if i > 20
                 then do
                         do j = 1 to BANNER.0
                            Call LineOut 'TEMP', BANNER.j
                         end
                          i = 0
                      end
                 else Nop
             end
          end

   Call Stream CHKF,   'C', 'CLOSE'
   Call Stream 'TEMP', 'C', 'CLOSE'
   Call SysFileDelete CHKF
  'ren TEMP' CHKF

   Return

 CHKOPT: /*---------------------------------------------------- CHKOPT: -----*/

    SRVNAME = '';
    INPF    = 'ACL.CSV';
    LOGF    = 'LSMT.LOG';
    CHKF    = 'ACL.CHK';
    PIPE    = '';
    TRACE   = 0;
    MUTE    = 0;

    OPTION = Translate(OPTION)
    do while OPTION <> ''
       Parse value OPTION with ARGUMENT ' ' OPTION
       select
        when Left(ARGUMENT,5) = '/SRV:' then SRVNAME = Substr(ARGUMENT,6)
        when Left(ARGUMENT,5) = '/INP:' then INPF    = Substr(ARGUMENT,6)
        when Left(ARGUMENT,5) = '/LOG:' then LOGF    = Substr(ARGUMENT,6)
        when Left(ARGUMENT,5) = '/CHK:' then CHKF    = Substr(ARGUMENT,6)
        when Left(ARGUMENT,5) = '/PIP:' then PIPE    = Substr(ARGUMENT,6)
        when Left(ARGUMENT,2) = '/M'    then MUTE    = 1
        when Left(ARGUMENT,2) = '/T'    then TRACE   = 1
        otherwise Nop
       end
    end

    if SRVNAME = '' then signal GETHELP

    if \MUTE
     then do
             Topic1='SETWELCOME'
             Topic_String.Topic1.1=SRVNAME;
             Topic_String.Topic1.2=INPF;
             Topic_String.Topic1.3=LOGF;
             Topic_String.Topic1.4=CHKF;
             Topic_String.Topic1.5=PIPE' ';
             Topic_List='WELCOMELOGO' Topic1 'SETACL';
             Call GETANS
             Parse VALUE SysCurPos() With Old_R Old_C; '@pause'
             Call SysCurPos Old_R, Old_C; say ESC'[K'
          end
     else do
             say 'ServerName =' SRVNAME
             say 'InputFile  =' INPF
             say 'LogFile    =' LOGF
             say 'CheckFile  =' CHKF
          end

    Return

 CHKPWS: /*---------------------------------------------------- CHKPWS: -----*/

    RC = NetGetInfo(350, 'WKSTAINFO','')
    if RC = 0
     then do
             ADMNAME = WKSTAINFO.UserName
             PWSNAME = WKSTAINFO.ComputerName
          end
     else do
            Call LOGIT 'Get PWS Info', ,RC
            Call Quit
          end
    Return

 INIT: /*------------------------------------------------------ INIT: -------*/

    Call RgUtil   '/m' /* Rexx Utilities        */
    Call RgUtils  '/m' /* Rexx Utilities        */
    Call RgLSRXUT '/m' /* Lan Server Rexx Utils */

    Parse Upper Source . . P_NAME
    PRGN = Filespec('N', Left(P_NAME, Length(P_NAME) -4))

   '@echo off'
    ESC   = '1B'x
    REDIR = '>NUL 2>NUL'

    NETLOGONASN    = 52
    NETALIAS       = 20
    NETACCESS      = 10
    NETACCESSAPPLY = 520
    EC  = 0
    CHKLines = 0

    Resource_File = 'LSMT.RSC'
    Call CHKFILE Resource_File

    Return

 GETANS: /*---------------------------------------------------- GETANS: -----*/

    Vars_List =Ansi_Say(Resource_File Topic_List);
    Parse VALUE SysCurPos() With Old_R Old_C;
    Do While Vars_List <> '';
       Parse VALUE Vars_List With Topic_Id ';' Var_Id ';' Row ';' Column ';' Color ';' Vars_List;
       Call SysCurPos Row, Column;
       Say x2c(Color) || Topic_String.Topic_Id.Var_Id || '1B'x || '[0m';
       End;
    Call SysCurPos Old_R, Old_C;

    Return

 GETHELP: /*--------------------------------------------------- GETHELP: ----*/

    if \MUTE
     then do
             Topic1='SETHELP'
             Topic_String.Topic1.1=PRGN;
             Topic_List=Topic1;
             Call GETANS
          end
     else say 'Incorrect options.'

    Call QUIT

    Return

 CHKFILE: /*--------------------------------------------------- CHKFILE: ----*/

    Parse Arg FILE
    RC = Stream(FILE, 'C', 'QUERY EXIST')
    if RC = ''
     then do
             say ' File' FILE 'not found.'
             Call QUIT
          end
     else Nop
    Call Stream FILE, 'C', 'CLOSE'

    Return

 LOGIT: /*----------------------------------------------------- LOGIT: ------*/

    FUNC = ARG(1); INFO = ARG(2); RCOD = ARG(3)
    RC = LLOGIT(LOGF, PIPE, ADMNAME, PRGN, FUNC, INFO, RCOD)

    Return

 QUIT: /*------------------------------------------------------ QUIT: -------*/

    Call LineOut 'LSMT.END', PRGN, 1
    Call Stream  'LSMT.END', 'C', 'CLOSE'
    Call Stream   INPF,      'C', 'CLOSE'
    Call Stream   LOGF,      'C', 'CLOSE'
    Call Stream   CHKF,      'C', 'CLOSE'
    Exit ExitCode

 /*--------------------------------------------------------------------------*/
