[ Licence and User Group Enhancement ]

This enhancement was developed to assist with licence management and user classification issues. This enhancement will assist the security team in identifying when too many licences are allocated and will ensure that the user master data is maintained.

When a user is created/changed in SU01 the following checks occur:

1. Has a user group is assigned
2. Has a licence type has been assigned
3. Check the BSL budgeted licence numbers

Depending on the outcome of the above checks the following messages will be presented when the user is created/modified:

Check 1:

Check 2:

Check 3:

 

If more than one of the above conditions fail, then all the messages will be combined as shown below:

All these messages are essentially just warnings and will never stop a user from being changed/created, but it will allow the security team to keep the numbers under control and notify the requestor immediately.

The enhancement exists in the following function group:

Z_SEC_ASSIGN_AG_CLEANUP

This function module is designed to complete the following:

1. Remove any duplicate role assignments from users
2. Ensure that the user group field is completed
3. Ensure that a licence has been allocated to the user
4. Checks the current licence number for selected licence type (uses table zss_licence)
5. Checks for specific cross-system pre-requisite roles (will be discussed in another document)

The function module will take into account if the system is a development, productive or CUA system.

*-------------------------------------------------------
*     Check where you are
      CALL FUNCTION 'SUSR_ZBV_CENTRALSYSTEM_CHECK'
        EXCEPTIONS
          duplicate_central_system = 1
          new_system               = 2
          not_central              = 3
          OTHERS                   = 4.

*     Found non-cua central system
      IF sy-subrc EQ 3.
        gv_central_cua = space.
      ELSE.
        gv_central_cua = 'X'.
      ENDIF.

*     Check if system is productive
      SELECT SINGLE cccategory
        FROM t000
        INTO gv_cat
        WHERE mandt EQ sy-mandt.

      IF sy-subrc = 0.
        gv_sys_not_found = space.
        IF gv_cat EQ 'P'. "Productive system
          gv_productive = 'X'.
        ELSE.
          gv_productive = space.
        ENDIF.
      ELSE.
        gv_sys_not_found = 'X'.
      ENDIF.
*-------------------------------------------------------

 

*       Found CUA central System
        IF gv_central_cua EQ 'X'.

          ASSIGN ('(SAPLSUU5)G_USERNAME') TO <fcuaname>.

*         Get the current list of user roles
          CALL FUNCTION 'SUSR_USER_LOCAGR_ACTGROUPS_GET'
            EXPORTING
              user_name           = <fcuaname>
            TABLES
              user_activitygroups = gt_roles.

*         Remove invalid entries
          LOOP AT gt_roles INTO gs_roles.

            IF gs_roles-to_dat LT sy-datum.
              DELETE gt_roles.
            ENDIF.

          ENDLOOP.

*         Put new list of roles back
          CALL FUNCTION 'SUSR_USER_LOCAGR_ACTGROUPS_PUT'
            EXPORTING
              user_name           = <fcuaname>
            TABLES
              user_activitygroups = gt_roles.

*         Add changes to the DB from the buffer
          CALL FUNCTION 'SUSR_UM_USR_AGR_BUFFERS_TO_DB'.

        ENDIF.

 

*       If the system is either CUA or Productive
*      (all other systems are excluded: Dev, Test etc)
        IF gv_central_cua EQ 'X' OR gv_productive EQ 'X'.

*         Check the Auth User group field
          ASSIGN ('(SAPLSUU5)uslogond-class') TO <fgrps>.

*         Check General User group
*         assign ('(SAPLSUU5)G_GROUPS') to <fgrps>.
          IF <fgrps> IS INITIAL.

            gs_msgtab-msgv1 = text-e01.
            gs_msgtab-msgty = 'W'.
            gs_msgtab-msgno = c_msg.
            gs_msgtab-msgid = c_msg_class.

            APPEND gs_msgtab TO gt_msgtab.
            CLEAR gs_msgtab.

*           As this exit only occurs after the save has already completed
*           we need to re-call the SU01 program with the user currently
*           being chnaged passed as a parameter. This will give the
*           impression that the field must be updated before it can be
*           saved.

*           call su01 again.
            gv_call_su01 = 'X'.

          ENDIF.

 

*           Get a list of all the users assigned to selected
*           licence type
            SELECT *
              FROM usr06
             INTO TABLE gt_lic
              WHERE lic_type EQ <flictype>.


*           remove invalid users
            LOOP AT gt_lic.
              SELECT COUNT( * )
                FROM usr02
                WHERE bname EQ gt_lic-bname
                AND gltgb LT sy-datum
                AND gltgb NE '00000000'.

              IF sy-subrc = 0.
                DELETE gt_lic.
              ENDIF.

            ENDLOOP.

*           Get the budgeted licence numbers
            SELECT *
              FROM zss_licence
              INTO TABLE gt_lic_nums.

            CLEAR gv_lic_count.

*           Count the total licences for the selected licence type
            CASE <flictype>.
              WHEN '51'.                                    " Cat 1
                LOOP AT gt_lic_nums.
                  gv_lic_count = gv_lic_count + gt_lic_nums-cat1.
                ENDLOOP.

              WHEN '52'.                                    " cat 2 Pro
                LOOP AT gt_lic_nums.
                  gv_lic_count = gv_lic_count + gt_lic_nums-cat2.
                ENDLOOP.

              WHEN '53'. " Cat 3 Limited Pro
                LOOP AT gt_lic_nums.
                  gv_lic_count = gv_lic_count + gt_lic_nums-cat3.
                ENDLOOP.

              WHEN '54'. " Cat 4 - Employee
                LOOP AT gt_lic_nums.
                  gv_lic_count = gv_lic_count + gt_lic_nums-cat4.
                ENDLOOP.

              WHEN '71'. " Shift User
                LOOP AT gt_lic_nums.
                  gv_lic_count = gv_lic_count + gt_lic_nums-cat6.
                ENDLOOP.

              WHEN '72'. " ESS
                LOOP AT gt_lic_nums.
                  gv_lic_count = gv_lic_count + gt_lic_nums-cat5.
                ENDLOOP.

              WHEN '73'. " Shift User
                LOOP AT gt_lic_nums.
                  gv_lic_count = gv_lic_count + gt_lic_nums-cat6.
                ENDLOOP.

            ENDCASE.

*           Get user count of current licences assigned
            DESCRIBE TABLE gt_lic LINES gv_lines.

*           Compare actual vs budgeted
            IF gv_lines GE gv_lic_count.

              gv_lic_count_out = gv_lic_count.
              CONDENSE gv_lic_count_out.
              gs_msgtab-msgv1 = text-e02.
              gs_msgtab-msgv2 = <flictype>.
              gs_msgtab-msgv3 = ' Available: '.
              gs_msgtab-msgv4 = gv_lic_count_out.
              gs_msgtab-msgty = 'W'.
              gs_msgtab-msgno = c_msg.
              gs_msgtab-msgid = c_msg_class.

              APPEND gs_msgtab TO gt_msgtab.
              CLEAR gs_msgtab.
            ENDIF.
          ELSE.
            gs_msgtab-msgv1 = text-e03.
            gs_msgtab-msgty = 'E'.
            gs_msgtab-msgno = c_msg.
            gs_msgtab-msgid = c_msg_class.

            APPEND gs_msgtab TO gt_msgtab.
            CLEAR gs_msgtab.

*           call su01 again.
            gv_call_su01 = 'X'.

          ENDIF.

        ENDIF.

 

Z_SEC_ASSIGN_AG_CLEANUP_SINGLE

This function module will remove roles for the user master that have already expired.

FUNCTION Z_SEC_ASSIGN_AG_CLEANUP_SINGLE.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     REFERENCE(ACTIVITY_GROUP) LIKE  AGR_DEFINE-AGR_NAME
*"----------------------------------------------------------------------

*       Global data declarations
tables agr_users.

delete from agr_users where agr_name = ACTIVITY_GROUP and
                            to_dat LT sy-datum.

ENDFUNCTION.