LDAP是轻量目录访问协议(LightweightDirectory Access Protocol)的缩写,LDAP标准实际上是在X.500标准基础上产生的一个简化版本。

AD是Active Directory的缩写,AD是LDAP的一个应用实例,而不应该是LDAP本身。比如:windows域控的用户、权限管理应该是微软公司使用LDAP存储了一些数据来解决域控这个具体问题,只是AD顺便还提供了用户接口,也可以利用ActiveDirectory当做LDAP服务器存放一些自己的东西而已。

域控查看ldap日志_SAP


需求描述:SAP中的HR数据,比如用户姓名,手机号,邮箱地址,员工照片等,创建或者修改后需要同步更新到AD域服务器,用户登录windows操作系统后可以查看是否更新成功。

通信连接配置

LDAP前期配置需BASIS事先做好,执行LDAP事务码可以正常登录到AD目录。

域控查看ldap日志_abap_02


连接器LDAP_HRO_500是一个RFC目标,通过SM59创建。详细的配置参数如下:

域控查看ldap日志_数据_03


域控查看ldap日志_域控查看ldap日志_04


域控查看ldap日志_SAP_05


域控查看ldap日志_数据_06


域控查看ldap日志_字段_07


通过点击系统用户可以设置登录的用户:

域控查看ldap日志_abap_08


LDAP账号密码需要设置:

域控查看ldap日志_abap_09


LDAP连接器:

域控查看ldap日志_字段_10


域控查看ldap日志_abap_11


LDAP服务器:

域控查看ldap日志_域控查看ldap日志_12


域控查看ldap日志_字段_13


通过查找功能可以查看AD库里的数据:

域控查看ldap日志_域控查看ldap日志_14


维护查询条件,注意格式:

域控查看ldap日志_数据_15


执行LDAPMAP事务码,进行字段匹配。

域控查看ldap日志_字段_16


域控查看ldap日志_字段_17


· 1 筛选,用于查找SAP中的唯一数据

· 2 导入映射,设置筛选字段时需要设置此字段,用户查找AD域中的数据

· 3 导入映射,用于设置是否写入AD域字段

· 4 创建数据库,在SAP端生成新数据

· 5 创建LDAP,在AD端生成新数据

· 6 RDN,相对识别名称映射,本次传输的数据未使用到,但是系统程序里会校验这个字段,没有打勾的话会报错,此处只是有字段匹配被勾选,但是程序里未传输此字段的值

USERNAME– BAPIBNAME是必输项,但是本次场景中AD没有与其匹配的字段,所以将AD库中的主键值字段mail在此处匹配,程序里赋值的时候将邮箱地址赋值给BAPIBNAME。

执行数据传输

此次场景HR数据传输是定制化的字段,可以通过自开发程序来发送数据。通过SE19人员主数据的增强HRPAD00INFTY来将有变动的人员号写入自定义表,然后通过执行自开发程序发起数据同步。

自定义表ZHRLDAP_PERNR,与系统表HRLDAP_PERNR结构一样。

域控查看ldap日志_abap_18


SE19中增强代码将需要同步的人员ID信息更新到上面的自定义表中。新建报表程序,取上表中人员数据发送到AD域。

*&---------------------------------------------------------------------*
*& Report Z01HRI0026
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT z01hri0026.

*----------------------------------------------------------------------
* type
*----------------------------------------------------------------------
TYPES: BEGIN OF ts_ldap_attr_l,
         pernr      LIKE lda_attr_l-pernr,
         attr_tab   LIKE lda_attr_l-attr_tab,
         attr_field LIKE lda_attr_l-attr_field,
         value      LIKE lda_attr_l-value,
       END OF ts_ldap_attr_l.

*----------------------------------------------------------------------
* table
*----------------------------------------------------------------------
DATA: gt_ldap TYPE TABLE OF Zhrldap_pernr,
      gt_0001 TYPE TABLE OF pa0001,
      gt_0105 TYPE TABLE OF pa0105.

*----------------------------------------------------------------------
* work area
*----------------------------------------------------------------------
DATA: gw_ldap TYPE Zhrldap_pernr,
      gw_0001 TYPE pa0001,
      gw_0105 TYPE pa0105.

*----------------------------------------------------------------------
* data
*----------------------------------------------------------------------
DATA: gv_error TYPE c.

*----------------------------------------------------------------------
* screen
*----------------------------------------------------------------------
SELECT-OPTIONS: s_date FOR sy-datum.
PARAMETERS: p_del TYPE c AS CHECKBOX.

*----------------------------------------------------------------------
* START-OF-SELECTION
*----------------------------------------------------------------------
START-OF-SELECTION.
  IF p_del IS INITIAL.
* 取需要同步的数据
    PERFORM frm_data_get.
* 编辑并同步数据
    PERFORM frm_data_send.
  ELSE.
    DELETE FROM Zhrldap_pernr WHERE AEDTM in s_date and PROCESSED = 'X'.
  ENDIF.

*&---------------------------------------------------------------------*
*& Form FRM_DATA_GET
*&---------------------------------------------------------------------*
*& text
*&---------------------------------------------------------------------*
*& -->  p1        text
*& <--  p2        text
*&---------------------------------------------------------------------*
FORM frm_data_get .
  SELECT *
    FROM Zhrldap_pernr
    INTO TABLE gt_ldap
   WHERE processed = ''
     AND aedtm in s_date.

  CHECK gt_ldap IS NOT INITIAL.

  SELECT pernr bukrs orgeh plans zzbz
    FROM pa0001
    INTO CORRESPONDING FIELDS OF TABLE gt_0001
     FOR ALL ENTRIES IN gt_ldap
   WHERE pernr = gt_ldap-pernr
     AND begda <= sy-datum
     AND endda >= sy-datum.

  SELECT *
    FROM pa0105
    INTO CORRESPONDING FIELDS OF TABLE gt_0105
     FOR ALL ENTRIES IN gt_ldap
   WHERE pernr = gt_ldap-pernr
     AND begda <= sy-datum
     AND endda >= sy-datum.

  SORT gt_0105 BY subty begda DESCENDING.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_DATA_SEND
*&---------------------------------------------------------------------*
*& 编辑并同步数据
*&---------------------------------------------------------------------*
FORM frm_data_send .
  DATA: attributes    TYPE ts_ldap_attr_l OCCURS 0,
        attributes_wa TYPE ts_ldap_attr_l,
        lv_time       TYPE i,
        lv_deptn      TYPE string,
        lv_photo      TYPE string,
        lv_objid      TYPE hrp1001-objid,
        logsys        LIKE tbdls-logsys,
        ldapsrv       LIKE lda_types-ldapserver,
        errors        LIKE bapiret2 OCCURS 0,
        errors_wa     LIKE bapiret2.
  DATA: mid   TYPE sy-msgid VALUE 'LDAPSYNC',
        mtype TYPE sy-msgty VALUE 'I',
        num   TYPE sy-msgno.

  LOOP AT gt_ldap INTO gw_ldap.
    attributes_wa-pernr = gw_ldap-pernr.

*      attributes_wa-attr_tab = 'EMPLOYEE'.
*      attributes_wa-attr_field = 'KEY'.
**      attributes_wa-value = gw_0105-usrid.
*      APPEND attributes_wa TO attributes.

    "邮件、手机号、SAP账号
    CLEAR gw_0105.
    READ TABLE gt_0105 INTO gw_0105 WITH KEY pernr = gw_ldap-pernr subty = '0006'.

    IF gw_0105-usrid IS NOT INITIAL.
      attributes_wa-attr_tab = 'USERNAME'.
      attributes_wa-attr_field = 'BAPIBNAME'.
      attributes_wa-value = gw_0105-usrid.
      APPEND attributes_wa TO attributes.
    else.
      CONTINUE.
    ENDIF.

    CLEAR gw_0105.
    READ TABLE gt_0105 INTO gw_0105 WITH KEY pernr = gw_ldap-pernr subty = '0004'.

    IF gw_0105-usrid IS NOT INITIAL.
      attributes_wa-attr_tab = 'EMPLOYEE'.
      attributes_wa-attr_field = 'MOBILE'.
      attributes_wa-value = gw_0105-usrid.
      APPEND attributes_wa TO attributes.
    ENDIF.

    CLEAR gw_0105.
    READ TABLE gt_0105 INTO gw_0105 WITH KEY pernr = gw_ldap-pernr subty = '0001'.

    IF gw_0105-usrid IS NOT INITIAL.
      attributes_wa-attr_tab = 'EMPLOYEE'.
      attributes_wa-attr_field = 'BNAME'.
      attributes_wa-value = gw_0105-usrid.
      APPEND attributes_wa TO attributes.
    ENDIF.

    "同步公司、组织单位、职位
    CLEAR gw_0001.
    READ TABLE gt_0001 INTO gw_0001 WITH KEY pernr = gw_ldap-pernr.
    attributes_wa-attr_tab = 'EMPLOYEE'.
    attributes_wa-attr_field = 'PERNR'.
    attributes_wa-value = gw_0001-pernr.
    APPEND attributes_wa TO attributes.

    "公司
    SELECT SINGLE butxt
      FROM t001
      INTO @DATA(lv_butxt)
     WHERE bukrs = @gw_0001-bukrs.

    attributes_wa-attr_tab = 'EMPLOYEE'.
    attributes_wa-attr_field = 'COMPANY'.
    attributes_wa-value = lv_butxt.
    APPEND attributes_wa TO attributes.
    CLEAR lv_butxt.

    "职务
    if gw_0001-zzbz is INITIAL.
      SELECT SINGLE stext
        FROM hrp1000
        INTO @DATA(lv_stext)
       WHERE plvar = '01'
         AND otype = 'S'
         AND objid = @gw_0001-plans
         AND istat = '1'
         AND begda <= @sy-datum
         AND endda >= @sy-datum
         AND langu = '1'.
    else.
      lv_stext = gw_0001-zzbz.
    endif.

    attributes_wa-attr_tab = 'EMPLOYEE'.
    attributes_wa-attr_field = 'TITLE'.
    attributes_wa-value = lv_stext.
    APPEND attributes_wa TO attributes.
    CLEAR lv_stext.

    "部门
    lv_objid = gw_0001-orgeh.
    "先检查当前条,不符合条件则检索上一级的组织
    CLEAR: lv_time,lv_deptn.
    IF lv_objid IS NOT INITIAL.
      DO 10 TIMES.
        lv_time = lv_time + 1.

        SELECT SINGLE *
          FROM hrp9503
          INTO @DATA(lw_9503)
         WHERE otype = 'O'
           AND objid = @lv_objid
           AND begda <= @sy-datum
           AND endda >= @sy-datum.
        IF sy-subrc = 0.    "取到组织单位

          SELECT SINGLE *
            FROM hrp1000
            INTO @DATA(lw_1000)
           WHERE otype = 'O'
             AND objid = @lv_objid
             AND begda <= @sy-datum
             AND endda >= @sy-datum.

          IF lw_9503-zznsjgcj = '2'.
            lv_deptn = lw_1000-mc_stext.
          ELSEIF lw_9503-zznsjgcj = '1'.
            IF lv_deptn IS INITIAL.
              lv_deptn = lw_1000-mc_stext.
            ELSE.
              CONCATENATE lw_1000-mc_stext lv_deptn INTO lv_deptn.
            ENDIF.
            EXIT.
          ENDIF.

        ENDIF.

        "检索上一级组织
        SELECT SINGLE *
          FROM hrp1001
          INTO @DATA(lw_1001)
         WHERE otype = 'O'
           AND objid = @lv_objid
           AND rsign = 'A'
           AND relat = '002'
           AND begda <= @sy-datum
           AND endda >= @sy-datum.
        IF sy-subrc = 0.
          lv_objid = lw_1001-sobid.
        ENDIF.

        CLEAR: lw_9503,lw_1000,lw_1001.
      ENDDO.
    ENDIF.

    attributes_wa-attr_tab = 'EMPLOYEE'.
    attributes_wa-attr_field = 'DEPARTMENT'.
    attributes_wa-value = lv_deptn.
    APPEND attributes_wa TO attributes.
    CLEAR lv_deptn.

* 取员工照片
    PERFORM frm_get_photo USING gw_ldap-pernr CHANGING lv_photo.

    attributes_wa-attr_tab = 'EMPLOYEE'.
    attributes_wa-attr_field = 'PHOTO'.
    attributes_wa-value = lv_photo.
    APPEND attributes_wa TO attributes.
    CLEAR lv_photo.

  ENDLOOP.

* send attributes to ldap client
  logsys = 'LDAP_HRQ_500'.
  ldapsrv = 'AD_SINOCHEM'.
* send attributes
  CALL FUNCTION 'SPLDAP_RECEIVE_ATTRIBUTES'
    EXPORTING
      logsys       = logsys
      serverid     = ldapsrv
*     ATTRIBUTES_S = attributes[]
*     initial_run  = ldapinitialrun
      attributes_l = attributes[]
*     ATTRIBUTES_X = TOTAL_ATTRS_X[].
    IMPORTING
      return       = errors[].
  IF NOT errors[] IS INITIAL.
    READ TABLE errors INDEX 1 INTO errors_wa.

    MESSAGE ID errors_wa-id TYPE errors_wa-type
    NUMBER errors_wa-number
    WITH errors_wa-message_v1 errors_wa-message_v2
    errors_wa-message_v3 errors_wa-message_v4.

  else.

    MESSAGE ID mid TYPE mtype
    NUMBER 022.

    gw_ldap-PROCESSED = 'X'.
    modify gt_ldap FROM gw_ldap TRANSPORTING PROCESSED WHERE PROCESSED = ''.

    modify Zhrldap_pernr FROM TABLE gt_ldap.
    commit WORK.
  ENDIF.

ENDFORM.

*&---------------------------------------------------------------------*
*& Form FRM_GET_PHOTO
*&---------------------------------------------------------------------*
*& 取员工照片
*&---------------------------------------------------------------------*
*&      --> LS_PA_REQUEST_PERNR
*&      <-- LS_PA_REQUEST_PHOTO
*&---------------------------------------------------------------------*
FORM frm_get_photo  USING    pv_pernr
                    CHANGING pv_photo.
  DATA: ls_image_info      TYPE toav0,
        lv_image_exists(1) TYPE c,
        lv_len             TYPE i,
        lv_pos             TYPE i,
        lv_time            TYPE i,
        lt_mime            TYPE TABLE OF W3MIME,
        lv_content         TYPE XSTRING,
        lv_pernr           TYPE p0001-pernr,
        lt_data            LIKE TABLE OF tbl1024,
        lw_data            like tbl1024.

* 以下用于取照片
  CLEAR: ls_image_info,
         lv_len,
         lt_data,
         lv_image_exists.

  lv_pernr = pv_pernr."'20600010'.
  "2、员工照片
  CALL FUNCTION 'HR_IMAGE_EXISTS'
    EXPORTING
      p_pernr               = lv_pernr
      p_tclas               = 'A'
      p_begda               = sy-datum
      p_endda               = sy-datum
    IMPORTING
      p_exists              = lv_image_exists
      p_connect_info        = ls_image_info
    EXCEPTIONS
      error_connectiontable = 1
      OTHERS                = 2.

  IF sy-subrc = 0.
    CALL FUNCTION 'SCMS_AO_TABLE_GET'
      EXPORTING
        arc_id       = ls_image_info-archiv_id
        doc_id       = ls_image_info-arc_doc_id
      IMPORTING
        length       = lv_len
      TABLES
        data         = lt_data
      EXCEPTIONS
        error_http   = 1
        error_archiv = 2
        error_kernel = 3
        error_config = 4
        OTHERS       = 5.

    IF sy-subrc = 0.
      LOOP AT lt_data INTO lw_data..
        pv_photo = pv_photo && lw_data-LINE.
      ENDLOOP.
      exit.

      CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
        EXPORTING
          input_length = lv_len
        IMPORTING
          buffer       = lv_content
        TABLES
          binary_tab   = lt_data
        EXCEPTIONS
          failed       = 1
          OTHERS       = 2.

      pv_photo = lv_content.

*          CALL FUNCTION 'RSFO_XSTRING_TO_MIME'
*            EXPORTING
*              C_XSTRING = lv_content
*              I_LENGTH  = lv_len
*            TABLES
*              C_T_MIME  = lt_MIME.

    ENDIF.
  ELSE.
*        CLEAR GV_GLAG.
*        GV_GLAG = 'X'.
*        EXIT.

  ENDIF.

ENDFORM.