TT Lab
Get started
Learn Learning paths Courses

Enterprise Authentication Integration

Generating an Account Audit Report Automatically

Continue in TT Lab

Goal

You reconcile the HR roster and the LDAP directory to extract ghost accounts, accounts not created, privileged ghost accounts, and long-inactive accounts with scripts, and after quarantine handling, write an audit report.

Why it matters

"Are departed employees' accounts disabled immediately?" is the first question of every security audit. And most organizations do this reconciliation once a quarter by hand in Excel. Incidents happen in between. Ghost accounts arise not from laziness but from structure — incremental synchronization cannot detect deletions, and without provisioning (SCIM), accounts remain as they are in individual systems. If you can run this reconciliation automatically every week, it becomes operations and not audit response.

Steps

  1. Preparation: start slapd on 1389 and load 00-base, 10-people, and 20-groups.
  2. Extract every inetOrgPerson in the directory and create /root/audit/ldap_users.csv. The first line is uid,cn,ou,title, sorted by uid in ascending order.
  3. Copy /opt/lab/fixtures/auth/audit/hr_roster.csv to /root/audit/hr.csv. (The contents must be identical)
  4. Save the uids that are in the directory but not in the HR roster to /root/audit/ghost.txt, one per line in ascending order.
  5. Save the uids that are in the HR roster but not in the directory to /root/audit/missing.txt in the same format.
  6. Among the ghost accounts, pick those that are members of the group cn=admins,ou=Groups,dc=labhub,dc=co,dc=kr and save them to /root/audit/critical.txt.
  7. Based on /opt/lab/fixtures/auth/audit/lastlogin.csv, save the uids with no login for 90 days or more as of 2026-08-01 to /root/audit/stale.txt in ascending order. (A uid that is not in the file is treated as "no login history" and included in the targets.)
  8. Move all the ghost accounts under ou=Disabled,dc=labhub,dc=co,dc=kr. (You must create the ou=Disabled entry first.) After the move, they must not be found in ou=People, and the number of entries in ou=Disabled must equal the number of ghost accounts.
  9. Write /root/audit/report.md. It must have six h2 headings, ## 총계, ## 유령 계정, ## 미생성 계정, ## 특권 계정, ## 휴면 후보, and ## 조치 계획 (in order: totals, ghost accounts, accounts not created, privileged accounts, dormancy candidates, action plan), and the following five lines must be included exactly.
    total=<디렉터리 전체 사용자 수(격리 포함)>
    ghost=<유령 계정 수>
    missing=<미생성 계정 수>
    critical=<특권 유령 계정 수>
    stale=<90일 미접속 계정 수>
    

Notes

Extract directory accounts

Extract every inetOrgPerson in the directory and create /root/audit/ldap_users.csv. The first line is uid,cn,ou,title, sorted by uid in ascending order.

Extract only the attributes you need. To match the output format to CSV you have to process the ldapsearch result, so start by cutting the clutter with -LLL.

Obtain the HR roster

Copy /opt/lab/fixtures/auth/audit/hr_roster.csv to /root/audit/hr.csv. (The contents must be identical)

Do not touch the original; work on a copy. If you count the rows first, you can check the results of the later set operations.

Extract ghost accounts

Save the uids that are in the directory but not in the HR roster to /root/audit/ghost.txt, one per line in ascending order.

Sort both uid lists and take the set difference. comm is accurate only when its inputs are sorted.

Extract accounts not created

Save the uids that are in the HR roster but not in the directory to /root/audit/missing.txt in the same format.

It is the same set difference in the opposite direction. Remember that this list is not a security issue but a work delay indicator.

Privileged ghost accounts

Among the ghost accounts, pick those that are members of the group cn=admins,ou=Groups,dc=labhub,dc=co,dc=kr and save them to /root/audit/critical.txt.

It is the intersection of the ghost account list and the administrator group member list. This is the part that becomes the top-priority action target in an audit.

Long-inactive accounts

Based on /opt/lab/fixtures/auth/audit/lastlogin.csv, save the uids with no login for 90 days or more as of 2026-08-01 to /root/audit/stale.txt in ascending order. (A uid that is not in the file is treated as "no login history" and included in the targets.)

The reference date must be fixed for the result to be reproducible. For date calculations, it is simple to convert to seconds with the date command and compare.

Quarantine handling

Move all the ghost accounts under ou=Disabled,dc=labhub,dc=co,dc=kr. (You must create the ou=Disabled entry first.) After the move, they must not be found in ou=People, and the number of entries in ou=Disabled must equal the number of ghost accounts.

Think about why you quarantine accounts instead of deleting them. The data must remain after the move, and they must drop out of the "active users" search.

Write the audit report

Write /root/audit/report.md. It must have six h2 headings, ## 총계, ## 유령 계정, ## 미생성 계정, ## 특권 계정, ## 휴면 후보, and ## 조치 계획 (in order: totals, ghost accounts, accounts not created, privileged accounts, dormancy candidates, action plan), and the following five lines must be included exactly.

total=<디렉터리 전체 사용자 수(격리 포함)>
ghost=<유령 계정 수>
missing=<미생성 계정 수>
critical=<특권 유령 계정 수>
stale=<90일 미접속 계정 수>

The value of a report is in the numbers and the trend. Quote the figures you obtained in the previous steps as they are, and attach an action plan to each item.