3682 Tage zuvor: RFC-Umwege

Um die Optionen einen RFC-Verbindung auszuwerten gibt es einen sch√∂nen Funktionsbaustein namens RFCDES2RFCDISPLAY. Dieser l√∂st den Connect-String aus Tabelle RFCDES auf und bietet einem die Informationen in Struktur RFCDISPLAY zur weiteren Verarbeitung an. Leider musste ich jedoch feststellen, dass sowohl die Load-Balancing Informationen der RFC-Verbindung selbst, als auch die der dazugeh√∂rigen A-RFC Einstellungen nicht korrekt √ľbergeben werden.

Da ich weder im SDN noch in den sonstigen weiten des Internets f√ľndig geworden bin, m√∂chte ich auf diese Weise meinen Work-Around mit dem Rest der Welt teilen:

* ----- Get RFC-Details (Options) -------------------------------------*
Form get_rfcoptions using     value(dest) type RFCDES-RFCDEST
                    changing  options type RFCDISPLAY.
*       Temporary variables
  Data:         rfcdest       like rfcdes,
        Begin of it_rfcopt occurs 32,
                token         like rfcdes-rfcoptions,
        End of it_rfcopt.
*       Get RFC-Destination
  Select single * from RFCDES into rfcdest where RFCDEST = dest.
*       Get Details
  Call function 'RFCDES2RFCDISPLAY'
                exporting     import_rfcdes = rfcdest
                importing     export_rfcdisplay = options.
*       Check Load-Balancing (not properly checked in Function-Module)
  Split rfcdest-rfcoptions at ',' into table it_rfcopt.
  Loop at it_rfcopt where token = 'X=LB=ON'.
    options-rfclbflag = true.
  EndLoop.
*       Check A-RFC Options (not checked in Function-Module)
  Select * from RFCCHECK where rfcdest = dest.
    If RFCCHECK-ARFCACTIVE = true.
      options-rfcarfcopt = true.
    EndIf.
  EndSelect.
EndForm.

3947 Tage zuvor: Passwörter-Raten

Als Administrator weist man ab und an seine Anwender darauf hin komplexere Passw√∂rter zu nutzen, die aus einer zuf√§lligen Reihenfolge von Buchstaben und Zahlen bestehen. Innerhalb eines SAP-System pflegt man denn auch einige Passwortregeln in Bezug auf deren L√§nge oder einiger W√∂rter und Wortteile, die nicht in Passw√∂rtern vorkommen d√ľrfen. Und man selbst geht nat√ľrlich mit leuchtendem Beispiel voran und verwendet ausschlie√ülich kryptische Passw√∂rter.

Dumm nur, wenn man dann die Passwortliste f√ľr technische Hintergrund-User verliert. Da diese User meist f√ľr die Anbindung anderer Systeme genutzt werden, kann man auch deren Passwort nicht einfach wieder zur√ľcksetzen. Grund genug also, sich einmal n√§hergehend mit der Passwortverschl√ľsselung von SAP zu besch√§ftigen.

Zun√§chst einmal das Wichtigste: Passw√∂rter werden innerhalb eines SAP-Systems mit einem nicht weiter bekannten Algorhytmus im Kernel selbst verschl√ľsselt. Dabei wird der Username mit in die Berechnung einbezogen, wodurch ein anderer User mit demselben Passwort einen anderen Hash-String bek√§me. Der so verschl√ľsselte Hash-String wird anschlie√üend in Tabelle USR02 zu einem User abgelegt.

Wie die Passw√∂rter genau verschl√ľsselt werden ist nicht bekannt. Allerdings k√∂nnen wir uns zunutze machen, dass die SID eines Systems nicht mit in die Berechnung eingeschlossen wird. Dadurch k√∂nnen wir auf einem anderen System, auf dem der User nicht existiert, einen Report starten, der die m√∂glichen Passwort-Kombinationen durchtestest. Der Report benutzt einen Funktionsbaustein, der einen User mit einem gegebenen Namen und Passwort anlegt. Nach der Anlage kann nun der Hash-Wert ausgelesen und mit einem anderen Wert verglichen werden. Ist der Hash-Wert derselbe, hat man das Passwort gefunden:

REPORT ZBOE_TEST .
parameters: user    like usr02-bname,
            pw_hash like usr02-bcode.

data: charset type table of c with default key initial size 26,
      char1 like line of charset,
      char2 like line of charset,
      char3 like line of charset,
      char4 like line of charset,
      char5 like line of charset,
      char6 like line of charset,
      char7 like line of charset,
      char8 like line of charset,
      pass(8),
      logondata type USLOGOND.

CALL FUNCTION 'SUSR_USER_CREATE'
  EXPORTING
    USER_NAME                          = user
    USER_LOGONDATA                     = logondata
    PASSWORD                           = ''
  EXCEPTIONS
    USER_NAME_ALREADY_EXISTS           = 1
    USER_LOCKED_BY_ANOTHER_ADMIN       = 2
    PASSWORD_NOT_ALLOWED               = 3
    ERROR_IN_LOCK_MANAGEMENT           = 4
    ERROR_WRITING_TO_DB                = 5
    INTERNAL_ERROR                     = 6
    OTHERS                             = 7.
case SY-SUBRC.
  when 0.
    break 1.
  when 1.
    MESSAGE e000(fb) with 'User existiert bereits!'.
  when others.
    MESSAGE e000(fb) with 'User konnte nicht angelegt werden.'.
endcase.

append 'A' to charset.
append 'B' to charset.
append 'C' to charset.
append 'D' to charset.
append 'E' to charset.
append 'F' to charset.
append 'G' to charset.
append 'H' to charset.
append 'I' to charset.
append 'J' to charset.
append 'K' to charset.
append 'L' to charset.
append 'M' to charset.
append 'N' to charset.
append 'O' to charset.
append 'P' to charset.
append 'Q' to charset.
append 'R' to charset.
append 'S' to charset.
append 'T' to charset.
append 'U' to charset.
append 'V' to charset.
append 'W' to charset.
append 'X' to charset.
append 'Y' to charset.
append 'Z' to charset.

loop at charset into char1.
  loop at charset into char2.
    loop at charset into char3.
      loop at charset into char4.
        loop at charset into char5.
          loop at charset into char6.
            loop at charset into char7.
              loop at charset into char8.
                 concatenate char1 char2 char3 char4
                             char5 char6 char7 char8 into pass.
                 CALL FUNCTION 'SUSR_USER_CHANGE'
                   EXPORTING
                     USER_NAME                 = user
                     PASSWORD                  = pass
                   EXCEPTIONS
                     USER_NAME_NOT_EXISTS      = 1
                     PASSWORD_NOT_ALLOWED      = 2
                     INTERNAL_ERROR            = 3
                     OTHERS                    = 4.
                 IF SY-SUBRC <> 0.
                   exit.
                 ENDIF.
                 CALL FUNCTION 'SUSR_USER_LOGONDATA_GET'
                   EXPORTING
                     USER_NAME                 = user
                   IMPORTING
                     USER_LOGONDATA            = logondata.
                 if pw_hash EQ logondata-BCODE.
                   write pass.
                   break 9.
                 endif.
              endloop.
            endloop.
          endloop.
        endloop.
      endloop.
    endloop.
  endloop.
endloop.

data ret_table type table of BAPIRET2.
CALL FUNCTION 'BAPI_USER_DELETE'
  EXPORTING
    USERNAME       = user
  TABLES
    RETURN         = ret_table.

Die Laufzeiten bei diesem Verfahren sind jedoch immens; auch wenn der Report selbst, der hier nur als Proof-of-Concept verstanden werden will, durchaus noch einiges Optimierungspotential besitzt. Die Laufzeit steigt jedoch expotentiell zur Anzahl der verwendeten Zeichen. Die möglichen Kombinationen lassen sich einfach berechnen:

<Anzahl Zeichen>^<Passwortlänge>

In einem Test habe ich ein bekanntes Passwort bei einer Passwortl√§nge von acht Zeichen und sieben verschiedenen Zeichen in f√ľnf bis zehn Minuten finden k√∂nnen.

3961 Tage zuvor: Deleting TPSTAT

TPSTAT is a standard SAP-table containing information on TMS, on transport requests that are currently being imported to be exact. Once in a while – most likely when a TP-process hangs and must be abported – you need to clear it so you can restart your transport requests. To prevent opening up the client you can use this report to delete its entries:

*&--- Technical description -------------------------------------------*
*& Report  Y12S_22_TP_DELTPSTAT                            Version 1.1 *
*& 09.11.2004 by Kai Boenke                         *
*&                                                                     *
*&--- Function overview -----------------------------------------------*
*& Delete an entry within table TPSTAT.                                *
*&                                                                     *
*&--- Changelog -------------------------------------------------------*
*&  09.11.2004  Kai Boenke         First edition                       *
*&  09.12.2004  Kai Boenke         Added support for *                 *
*&---------------------------------------------------------------------*
REPORT Y12S_22_TP_DELTPSTAT.

*&----- Declare variables
Tables:      TPSTAT.
Parameters:  trname   Like TPSTAT-TRKORR     Obligatory.
Data:        retcode  Like SY-SUBRC.


*&----- Validate given data
If trname <> '*'.
  Select * From TPSTAT  Where TRKORR = trname.
  EndSelect.

  If SY-SUBRC <> 0.
    Message a000(fb) With 'No such transport in TPSTAT.'.
  EndIf.
EndIf.


*&----- Delete table-entry
If trname <> '*'.
  Delete from TPSTAT    Where TRKORR = trname.
  retcode = SY-SUBRC.
Else.
  Delete from TPSTAT    Where TRKORR like '%'.
  retcode = SY-SUBRC.
EndIf.


*&----- Show result
If retcode <> 0.
  Message e000(fb) With 'Could not delete entry. '
                        '(' retcode ')'.
Else.
  Message s000(fb) With 'Entry deleted'.
EndIf.

3975 Tage zuvor: TPSTAT l√∂schen

Die TPSTAT ist eine Tabelle im Transport Organizer-Umfeld. Ab und an, wenn sich der Transport-Prozess aufh√§ngt und manuell beendet wird, bleiben in ihr Eintr√§ge f√ľr die abgebrochenen Importe stehen. Neben den Semaphoren im Transportverzeichniss m√ľssen dann auch diese Eintr√§ge gel√∂scht werden. Um in einem Produktivsystem den Mandanten nicht √∂ffnen zu m√ľssen, kann dieser kleine Report genutzt werden um die Eintr√§ge zu l√∂schen:

*&--- Technical description -------------------------------------------*
*& Report  Y12S_22_TP_DELTPSTAT                            Version 1.1 *
*& 09.11.2004 by Kai Boenke                         *
*&                                                                     *
*&--- Function overview -----------------------------------------------*
*& Delete an entry within table TPSTAT.                                *
*&                                                                     *
*&--- Changelog -------------------------------------------------------*
*&  09.11.2004  Kai Boenke         First edition                       *
*&  09.12.2004  Kai Boenke         Added support for *                 *
*&---------------------------------------------------------------------*
REPORT Y12S_22_TP_DELTPSTAT.

*&----- Declare variables
Tables:      TPSTAT.
Parameters:  trname   Like TPSTAT-TRKORR     Obligatory.
Data:        retcode  Like SY-SUBRC.


*&----- Validate given data
If trname <> '*'.
  Select * From TPSTAT  Where TRKORR = trname.
  EndSelect.

  If SY-SUBRC <> 0.
    Message a000(fb) With 'No such transport in TPSTAT.'.
  EndIf.
EndIf.


*&----- Delete table-entry
If trname <> '*'.
  Delete from TPSTAT    Where TRKORR = trname.
  retcode = SY-SUBRC.
Else.
  Delete from TPSTAT    Where TRKORR like '%'.
  retcode = SY-SUBRC.
EndIf.


*&----- Show result
If retcode <> 0.
  Message e000(fb) With 'Could not delete entry. '
                        '(' retcode ')'.
Else.
  Message s000(fb) With 'Entry deleted'.
EndIf.