SAP und die Suche der Passworthistorie

Wenn man wissen möchte, wie es um das Passwort eines Benutzers steht, wann er es das letzte mal geändert hat oder wann ein Account gelöscht worden ist hat man zwei Möglichkeiten:

1) Man(n) bedient sich der Tools, die SAP hierfür bereit stellt (TA: SU01 etc.)
2) Man(n) wirft einen schnellen Blick in die Datenbank

Zu 1) muss ich glaube ich nichts schreiben, die Transaktion als eine der Standard Transkation im SAP sollte hinläufig bekannt sein.

Bei 2) sieht die Sache ggf. schon wieder ganz anders aus. Wir orientieren uns hier zunächst an der Tabelle USR02. Kurz mit der Datenbank verbinden und erst mal schauen was in der Tabelle so alles drin steht:

SQL> descr <SCHEMA>.USR02
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 MANDT                                     NOT NULL VARCHAR2(9)
 BNAME                                     NOT NULL VARCHAR2(36)
 BCODE                                              RAW(8)
 GLTGV                                     NOT NULL VARCHAR2(24)
 GLTGB                                     NOT NULL VARCHAR2(24)
 USTYP                                     NOT NULL VARCHAR2(3)
 CLASS                                     NOT NULL VARCHAR2(36)
 LOCNT                                     NOT NULL NUMBER(3)
 UFLAG                                     NOT NULL NUMBER(3)
 ACCNT                                     NOT NULL VARCHAR2(36)
 ANAME                                     NOT NULL VARCHAR2(36)
 ERDAT                                     NOT NULL VARCHAR2(24)
 TRDAT                                     NOT NULL VARCHAR2(24)
 LTIME                                     NOT NULL VARCHAR2(18)
 OCOD1                                              RAW(8)
 BCDA1                                     NOT NULL VARCHAR2(24)
 CODV1                                     NOT NULL VARCHAR2(3)
 OCOD2                                              RAW(8)
 BCDA2                                     NOT NULL VARCHAR2(24)
 CODV2                                     NOT NULL VARCHAR2(3)
 OCOD3                                              RAW(8)
 BCDA3                                     NOT NULL VARCHAR2(24)
 CODV3                                     NOT NULL VARCHAR2(3)
 OCOD4                                              RAW(8)
 BCDA4                                     NOT NULL VARCHAR2(24)
 CODV4                                     NOT NULL VARCHAR2(3)
 OCOD5                                              RAW(8)
 BCDA5                                     NOT NULL VARCHAR2(24)
 CODV5                                     NOT NULL VARCHAR2(3)
 VERSN                                     NOT NULL VARCHAR2(9)
 CODVN                                     NOT NULL VARCHAR2(3)
 TZONE                                     NOT NULL VARCHAR2(18)
 ZBVMASTER                                 NOT NULL VARCHAR2(3)
 PASSCODE                                           RAW(20)
 PWDCHGDATE                                NOT NULL VARCHAR2(24)
 PWDSTATE                                  NOT NULL NUMBER(3)
 RESERVED                                  NOT NULL NUMBER(3)
 PWDHISTORY                                NOT NULL NUMBER(3)
 PWDLGNDATE                                NOT NULL VARCHAR2(24)
 PWDSETDATE                                NOT NULL VARCHAR2(24)
 PWDINITIAL                                NOT NULL NUMBER(3)
 PWDLOCKDATE                               NOT NULL VARCHAR2(24)
 PWDSALTEDHASH                             NOT NULL VARCHAR2(765)
 SECURITY_POLICY                           NOT NULL VARCHAR2(120)

Sollte das Schema nicht bekannt sein in dem die Tabellen liegen hilft zumindest unter *nix-artigen Betriebssystem in der Regel immer ein:

hostname:<SID>adm 1> env |grep schema
dbs_ora_schema=SCHEM

Interessant an der USR02 Tabelle sind für uns folgende Felder, wobei die Bedeutung selbsterklärend sein sollte (UFLAG gibt an, ob der Account gesperrt ist und warum <>0 = Account gesperrt):

MANDT                                     NOT NULL VARCHAR2(9)
BNAME                                     NOT NULL VARCHAR2(36)
UFLAG                                     NOT NULL NUMBER(3)
PASSCODE                                           RAW(20)
PWDCHGDATE                                NOT NULL VARCHAR2(24)
PWDHISTORY                                NOT NULL NUMBER(3)
PWDLOCKDATE                               NOT NULL VARCHAR2(24)

Damit die Ausgabe nicht so elend umgebrochen wird setzen wir schnell noch LINES und PAGES:

SQL> SET LINES 200
SQL> SET PAGES 200

Jetzt wollen wir doch mal sehen wie es um den SAP* oder auch SAPSTAR User aussieht:

SQL>  select MANDT, BNAME, UFLAG, PASSCODE, PWDCHGDATE, PWDHISTORY, PWDLOCKDATE from SCHEMA.USR02 where BNAME = 'SAP*' and MANDT = '000';
BNAME                                     UFLAG PASSCODE                                 PWDCHGDATE
------------------------------------ ---------- ---------------------------------------- ------------------------
SAP*                                         64 F11111111111111111111111111111    20121026

Wir sehen, dass SAP* gesperrt wurde (UFLAG <> 0) und den PASSCODE (sein gehashtes Passwort) sowie das Änderungsdatum des Passwortes (PWDCHGDATE).

Wenn man sich jetzt die alten Passwörter ansehen will kann man das in der Tabelle <SCHEMA>.USRPWDHISTORY tun:

SQL> descr <SCHEMA>.USRPWDHISTORY
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 MANDT                                     NOT NULL VARCHAR2(9)
 BNAME                                     NOT NULL VARCHAR2(36)
 TIMESTAMP                                 NOT NULL NUMBER(15)
 PASSCODE                                  NOT NULL RAW(20)
 BCODE                                     NOT NULL RAW(8)
 CODVN                                     NOT NULL VARCHAR2(3)
 PWDSALTEDHASH                             NOT NULL VARCHAR2(765)

Ein passender select für das Beispiel wäre:

SQL> select PASSCODE, TIMESTAMP from SAPI14.USRPWDHISTORY where MANDT = '000' and BNAME = 'SAP*';
PASSCODE                                  TIMESTAMP
---------------------------------------- ----------
1111111111111111111111111110B924324E34 2.0080E+13
1111111111111111111111111AC0B924324E34 2.0080E+13

Natürlich sind die PASSCODE Hashes in diesem Beispiel verstümmelt. Und natürlich kann man auch hergehen und ein PASSCODE kopieren. Und so zum Beispiel das Passwort des Users im Mandanten 000 gleich dem Mandant 100 setzen. Und natürlich kann man auch hergehen und gesperrte User mittels des UFLAG eintrags wieder entsperren. Damit die Änderung auch übernommen wird nicht das commit vergessen.

SQL> update SCHEMA.USR02 set UFLAG = '000' where BNAME = 'SAP*' and MANDT = '100';
SQL>commit;

Mit dem PASSCODE geht es genau so. Per select den PASSCODE holen (sowas mache ich nicht inline 😉 ) und dann den PASSCODE-Update fahren:

SQL> update SCHEMA.USR02 set PASSCODE= 'NEUERPASSCODE' where BNAME = 'SAP*' and MANDT = '100';
SQL>commit;

An dieser Stelle sei noch erwähnt, dass es natürlich nicht die feine englische Art ist, einfach am ABAP vorbei Daten auf der Datenbank zu verändern. Aber manchmal, besonders wenn R3trans nicht verfügbar ist, ist dass die Möglichkeit sich wieder Zugriff zum System zu verschaffen…

About the author