One business risk to manage when new business logic is being promoted to production environments is how to plan for a rollback process, where prior state data is restored, especially for an application/endpoint that is critical for a business; and as important to users as their login credentials and access.
In this entry, we showcase how to use CA Directory to snapshot an endpoint on a scheduled basis (daily/hourly) and have the process prepare a rollback delta file for user’s entitlements.
Understanding how queries may be direct to an endpoint/application or via the CA Identity Manager provisioning tier, we can speed up this process rapidly for sites that have millions of identities in an endpoint.
#!/bin/bash ############################################################################## # # POC to demostrate process to snapshot endpoint data on a daily basis # and to allow a format for roll back # # 1. Review ADS with dxsearch/dxmodify # 2. Create ADS representative Router DSA with CA Directory # 3. Create ldif delta of snapshot data # 4. Convert 'replace' to 'add' to ensure Roll back process is a 'merge' # and NOT an 'overwrite' of entitlements # # # # A. Baugher, ANA, 11/2019 # ############################################################################## ########## Secure password for script ######## FILE=/tmp/.ads.hash.pwd #rm -rf $FILE $FILE.salt [[ -f $FILE ]] echo "Check if $FILE exists: $?" [[ -s $FILE ]] echo "Check if $FILE is populated: $?" if [[ ! -s $FILE && ! -s $FILE.salt ]] then # File did not have any data # Run script once with pwd then replace with junk data in script SALT=$RANDOM$RANDOM$RANDOM PWD=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ENCPWD=$(echo $PWD | openssl enc -aes-256-cbc -a -salt -pass pass:$SALT) echo $ENCPWD > $FILE echo $SALT > $FILE.salt chmod 600 $FILE $FILE.salt fi if [[ -s $FILE && -s $FILE.salt ]] then ENCPWD=`cat $FILE` SALT=`cat $FILE.salt` echo "$PWD and $SALT for $ENCPWD" MYPWD=$(echo "$ENCPWD" | openssl enc -aes-256-cbc -a -d -salt -pass pass:$SALT) echo "$PWD and $SALT for $MYPWD" else echo "Missing password encrypted data and salt" exit 1 fi #exit echo "" echo "##############################################################################" echo "Step 0 # Remove prior ads schema files" echo "##############################################################################" ADS_SCHEMA=ads_schema ADS_SUFFIX="dc=exchange,dc=lab" RANDOM_PORT=50389 rm -rf $DXHOME/config/knowledge/$ADS_SCHEMA.dxc rm -rf $DXHOME/config/servers/$ADS_SCHEMA.dxi rm -rf $DXHOME/config/schema/$ADS_SCHEMA.dxc echo "" echo "##############################################################################" echo "Step 1 # Create new router DSA" echo "##############################################################################" echo "dxnewdsa -t router $ADS_SCHEMA $RANDOM_PORT $ADS_SUFFIX" dxnewdsa -t router $ADS_SCHEMA $RANDOM_PORT $ADS_SUFFIX echo"" echo "##############################################################################" echo "Step 2 # Create temporary LDIF file of ADS schema" echo "##############################################################################" cd $DXHOME/config/schema ADS_BIND_DN="CN=Administrator,CN=Users,DC=exchange,DC=lab" ADS_BIND_PWD=$MYPWD ADS_PASSFILE=/tmp/.ads.pwd echo -n $MYPWD > $ADS_PASSFILE chmod 600 $ADS_PASSFILE ADS_SERVER=dc2016.exchange.lab ADS_PORT=389 echo "dxschemaldif -v -D $ADS_BIND_DN -w ADS_BIND_PASSWORD_HERE $ADS_SERVER:$ADS_PORT > $ADS_SCHEMA.ldif" dxschemaldif -v -D $ADS_BIND_DN -w $ADS_BIND_PWD $ADS_SERVER:$ADS_PORT > $ADS_SCHEMA.ldif echo "" echo "##############################################################################" echo "Step 3 # Replace unknown SYNTAX with closely related SYNTAX known by CA Directory r12.6.5" echo "##############################################################################" echo "sed -i 's|1.2.840.113556.1.4.1221|1.3.6.1.4.1.1466.115.121.1.26|g' $ADS_SCHEMA.ldif" sed -i 's|1.2.840.113556.1.4.1221|1.3.6.1.4.1.1466.115.121.1.26|g' $ADS_SCHEMA.ldif echo "" echo "##############################################################################" echo "Step 4 - # Create CA Directory Schema DXC File from LDIF Schema File" echo "##############################################################################" echo "ldif2dxc -f $ADS_SCHEMA.ldif -b bad.ldif -x default.dxg -v $ADS_SCHEMA.dxc" ldif2dxc -f $ADS_SCHEMA.ldif -b bad.ldif -x default.dxg -v $ADS_SCHEMA.dxc echo "" echo "##############################################################################" echo "Step 5 - # Update router DSA schema reference" echo "##############################################################################" echo "sed -i \"s|source \"../schema/default.dxg\";|source \"../schema/default.dxg\";\nsource \"../schema/$ADS_SCHEMA.dxc\"; |g\" $DXHOME/config /servers/$ADS_SCHEMA.dxi" sed -i "s|source \"../schema/default.dxg\";|source \"../schema/default.dxg\";\nsource \"../schema/$ADS_SCHEMA.dxc\"; |g" $DXHOME/config/servers /$ADS_SCHEMA.dxi echo "" echo "##############################################################################" echo "Step 6 - # Query ADS endpoint for snapshot 1 " echo "##############################################################################" echo "dxsearch -LLL -h $ADS_SERVER -p $ADS_PORT -x -D $ADS_BIND_DN -y $ADS_PASSFILE -b $ADS_SUFFIX '(objectClass=User)' memberOf > snapshot_1_ $ADS_SCHEMA.ldif " echo "ldifsort snapshot_1_$ADS_SCHEMA.ldif snapshot_1_sorted_$ADS_SCHEMA.ldif " dxsearch -LLL -h $ADS_SERVER -p $ADS_PORT -x -D $ADS_BIND_DN -y $ADS_PASSFILE -b $ADS_SUFFIX "(objectClass=User)" memberOf | perl -p00e 's/\r?\ n //g' > snapshot_1_$ADS_SCHEMA.ldif ldifsort snapshot_1_$ADS_SCHEMA.ldif snapshot_1_sorted_$ADS_SCHEMA.ldif echo "" echo "##############################################################################" echo "Step 7 - # Query ADS endpoint for snapshot 2" echo "##############################################################################" echo "dxsearch -LLL -h $ADS_SERVER -p $ADS_PORT -x -D $ADS_BIND_DN -y $ADS_PASSFILE -b $ADS_SUFFIX '(objectClass=User)' memberOf > snapshot_2_ $ADS_SCHEMA.ldif " echo "ldifsort snapshot_2_$ADS_SCHEMA.ldif snapshot_2_sorted_$ADS_SCHEMA.ldif " dxsearch -LLL -h $ADS_SERVER -p $ADS_PORT -x -D $ADS_BIND_DN -y $ADS_PASSFILE -b $ADS_SUFFIX "(objectClass=User)" memberOf | perl -p00e 's/\r?\ n //g' > snapshot_2_$ADS_SCHEMA.ldif ldifsort snapshot_2_$ADS_SCHEMA.ldif snapshot_2_sorted_$ADS_SCHEMA.ldif echo "" echo "##############################################################################" echo "Step 8 - # Find the delta for any removed objects" echo "##############################################################################" echo "ldifdelta -x -S $ADS_SCHEMA snapshot_2_sorted_$ADS_SCHEMA.ldif snapshot_1_sorted_$ADS_SCHEMA.ldif" ldifdelta -x -S $ADS_SCHEMA snapshot_2_sorted_$ADS_SCHEMA.ldif snapshot_1_sorted_$ADS_SCHEMA.ldif echo "" echo "##############################################################################" echo "Step 9a: Convert from User ldapmodify syntax of 'overwrite' of 'replace' " echo "##############################################################################" ldifdelta -S $ADS_SCHEMA snapshot_2_sorted_$ADS_SCHEMA.ldif snapshot_1_sorted_$ADS_SCHEMA.ldif user_mod_syntax_input.ldif >/dev/null 2>&1 cat user_mod_syntax_input.ldif | perl -p00e 's/\r?\n //g' > user_mod_syntax.ldif cat user_mod_syntax.ldif echo "##############################################################################" echo "Step 9b: Convert to ADS Group ldapmodify syntax with a 'merge' of 'add' for the group objects" echo "##############################################################################" perl /opt/CA/Directory/dxserver/samples/dxsoak/convert.pl user_mod_syntax.ldif > group_mod_syntax_input.ldif cat group_mod_syntax_input.ldif | perl -p00e 's/\r?\n //g' > group_mod_syntax.ldif cat group_mod_syntax.ldif echo "##############################################################################"
Example of output from above script:
[dsa@vapp0001]$ ./active_directory_user_delta_via_ca_dir_tools-lab.sh Check if /tmp/.ads.hash.pwd exists: 0 Check if /tmp/.ads.hash.pwd is populated: 0 /opt/CA/Directory/dxserver/samples/dxsoak and 31936904511291 for U2FsdGVkX195Ti6A8GdFTG6Kmrf6xDcOhrd2aPWVezc= /opt/CA/Directory/dxserver/samples/dxsoak and 31936904511291 for CAdemo123 20200427150345,505.0Z = Current OS UTC time stamp ############################################################################## Step 0 # Remove prior ads schema files ############################################################################## 20200427150345,509.0Z = Current OS UTC time stamp ############################################################################## Step 1 # Create new router DSA ############################################################################## dxnewdsa -t router ads_schema 50389 dc=exchange,dc=lab Writing the knowledge file... knowledge file written Writing the initialization file... Initialization file written Starting the DSA 'ads_schema'... ads_schema starting ads_schema started 20200427150345,513.0Z = Current OS UTC time stamp ############################################################################## Step 2 # Create temporary LDIF file of ADS schema ############################################################################## dxschemaldif -v -D CN=Administrator,CN=Users,DC=exchange,DC=lab -w ADS_BIND_PASSWORD_HERE dc2016.exchange.lab:389 > ads_schema.ldif >> Issuing LDAP v3 synchronous bind to 'dc2016.exchange.lab:389'... >> Fetching root DSE 'subschemaSubentry' attribute... >> Downloading schema from 'CN=Aggregate,CN=Schema,CN=Configuration,DC=exchange,DC=lab'... >> Received (4527) values >> Done. 20200427150345,539.0Z = Current OS UTC time stamp ############################################################################## Step 3 # Replace unknown SYNTAX with closely related SYNTAX known by CA Directory r12.6.5 ############################################################################## sed -i 's|1.2.840.113556.1.4.1221|1.3.6.1.4.1.1466.115.121.1.26|g' ads_schema.ldif 20200427150345,560.0Z = Current OS UTC time stamp ############################################################################## Step 4 - # Create CA Directory Schema DXC File from LDIF Schema File ############################################################################## ldif2dxc -f ads_schema.ldif -b bad.ldif -x default.dxg -v ads_schema.dxc >> Opening input file 'ads_schema.ldif' ... >> Opening existing dxserver schema file '/opt/CA/Directory/dxserver/config/schema/default.dxg' ... >> Opening bad file 'bad.ldif' ... >> Opening output file '/opt/CA/Directory/dxserver/config/schema/ads_schema.dxc' ... >> Processing dxserver schema group file '/opt/CA/Directory/dxserver/config/schema/default.dxg'... >> Processing dxserver schema config file '/opt/CA/Directory/dxserver/config/schema/x500.dxc'... >> Processing dxserver schema config file '/opt/CA/Directory/dxserver/config/schema/cosine.dxc'... >> Processing dxserver schema config file '/opt/CA/Directory/dxserver/config/schema/umich.dxc'... >> Processing dxserver schema config file '/opt/CA/Directory/dxserver/config/schema/inetop.dxc'... >> Processing dxserver schema config file '/opt/CA/Directory/dxserver/config/schema/dxserver.dxc'... >> Loaded (248) existing dxserver schema entries >> Loading LDIF records... >> Loading LDIF record number (1)... >> Skipping attr: 'objectClass' >> Skipping attr: 'objectClass' >> Processing loaded LDIF records... >> Moving objectClasses to end of list... >> Sorting attrs/objectClasses so parents precede their children... >> Processing attributeTypes... >> Defaulting 'directoryString' syntax without any (required) matching rules to 'caseIgnoreString'... [Remove repeating lines x 1000] >> Processing objectClasses... >> Skipping existing schema entry 'top' with oid '2.5.6.0'... >> Skipping existing schema entry 'locality' with oid '2.5.6.3'... >> Skipping existing schema entry 'device' with oid '2.5.6.14'... >> Skipping existing schema entry 'certificationAuthority' with oid '2.5.6.16'... >> Skipping existing schema entry 'groupOfNames' with oid '2.5.6.9'... >> Skipping existing schema entry 'organizationalRole' with oid '2.5.6.8'... >> Skipping existing schema entry 'organizationalUnit' with oid '2.5.6.5'... >> Skipping existing schema entry 'domain' with oid '1.2.840.113556.1.5.66'... >> Skipping existing schema entry 'rFC822LocalPart' with oid '0.9.2342.19200300.100.4.14'... >> Skipping existing schema entry 'applicationProcess' with oid '2.5.6.11'... >> Skipping existing schema entry 'document' with oid '0.9.2342.19200300.100.4.6'... >> Skipping existing schema entry 'room' with oid '0.9.2342.19200300.100.4.7'... >> Skipping existing schema entry 'domainRelatedObject' with oid '0.9.2342.19200300.100.4.17'... >> Skipping existing schema entry 'country' with oid '2.5.6.2'... >> Skipping existing schema entry 'friendlyCountry' with oid '0.9.2342.19200300.100.4.18'... >> Skipping existing schema entry 'groupOfUniqueNames' with oid '2.5.6.17'... >> Skipping existing schema entry 'organization' with oid '2.5.6.4'... >> Skipping existing schema entry 'simpleSecurityObject' with oid '0.9.2342.19200300.100.4.19'... >> Skipping existing schema entry 'person' with oid '2.5.6.6'... >> Skipping existing schema entry 'organizationalPerson' with oid '2.5.6.7'... >> Skipping existing schema entry 'inetOrgPerson' with oid '2.16.840.1.113730.3.2.2'... >> Skipping existing schema entry 'residentialPerson' with oid '2.5.6.10'... >> Skipping existing schema entry 'applicationEntity' with oid '2.5.6.12'... >> Skipping existing schema entry 'dSA' with oid '2.5.6.13'... >> Skipping existing schema entry 'cRLDistributionPoint' with oid '2.5.6.19'... >> Skipping existing schema entry 'documentSeries' with oid '0.9.2342.19200300.100.4.9'... >> Skipping existing schema entry 'account' with oid '0.9.2342.19200300.100.4.5'... >> Converting LDIF records to DXserver schema format... >> Converted (4398) of (4525) schema records 20200427150345,894.0Z = Current OS UTC time stamp ############################################################################## Step 5 - # Update router DSA schema reference ############################################################################## sed -i "s|source "../schema/default.dxg";|source "../schema/default.dxg";\nsource "../schema/ads_schema.dxc"; |g" /opt/CA/Directory/dxserver/config/servers/ads_schema.dxi 20200427150345,897.0Z = Current OS UTC time stamp ############################################################################## step 6 - # Update an ADS account with memberOf for testing with initial conditions ############################################################################## dxmodify -c -H ldap://dc2016.exchange.lab:389 -D CN=Administrator,CN=Users,DC=exchange,DC=lab -y /tmp/.ads.pwd << EOF >/dev/null 2>&1 modifying entry CN=Account Operators,CN=Builtin,DC=exchange,DC=lab modifying entry CN=Account Operators,CN=Builtin,DC=exchange,DC=lab ldap_modify: Already exists (68) additional info: 00000562: UpdErr: DSID-031A11E2, problem 6005 (ENTRY_EXISTS), data 0 modifying entry CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab ldap_modify: Already exists (68) additional info: 00000562: UpdErr: DSID-031A11E2, problem 6005 (ENTRY_EXISTS), data 0 adding new entry CN=alan-del-scenario,OU=o365,DC=exchange,DC=lab modifying entry CN=Account Operators,CN=Builtin,DC=exchange,DC=lab 20200427150345,909.0Z = Current OS UTC time stamp ############################################################################## Step 7 - # Query ADS endpoint for snapshot 1 ############################################################################## dxsearch -LLL -h dc2016.exchange.lab -p 389 -x -D CN=Administrator,CN=Users,DC=exchange,DC=lab -y /tmp/.ads.pwd -b dc=exchange,dc=lab '(&(objectClass=User)(memberOf=*))' memberOf | perl -p00e 's/\r?\n //g' > snapshot_1_ads_schema.ldif ldifsort snapshot_1_ads_schema.ldif snapshot_1_sorted_ads_schema.ldif creating buckets creating sort cluster 1 of size 200 sorting 0 records creating sort cluster 2 of size 200 sorting 200 records creating sort cluster 3 of size 200 sorting 400 records 3 buckets created sorting 588 records 588 records sorted, 0 bad records 20200427150345,940.0Z = Current OS UTC time stamp ############################################################################## Step 8 - # Update an ADS account with memberOf for testing after snapshot ############################################################################## dxmodify -c -H ldap://dc2016.exchange.lab:389 -D CN=Administrator,CN=Users,DC=exchange,DC=lab -y /tmp/.ads.pwd << EOF Ignore the error msg: DSID-031A1254, problem 5003 (WILL_NOT_PERFORM) This error will occur if a non-existant value is removed from the group's member attribute ############################################################################## ldap_initialize( ldap://dc2016.exchange.lab:389 ) delete member: CN=Test User 001,CN=Users,DC=exchange,DC=lab modifying entry CN=Account Operators,CN=Builtin,DC=exchange,DC=lab modify complete delete member: CN=eeeee,CN=Users,DC=exchange,DC=lab modifying entry CN=Account Operators,CN=Builtin,DC=exchange,DC=lab modify complete delete member: CN=Test User 001,CN=Users,DC=exchange,DC=lab modifying entry CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab modify complete ldap_modify: Server is unwilling to perform (53) additional info: 00000561: SvcErr: DSID-031A1254, problem 5003 (WILL_NOT_PERFORM), data 0 delete member: CN=alantest,CN=Users,DC=exchange,DC=lab modifying entry CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab modify complete delete member: CN=eeeee,CN=Users,DC=exchange,DC=lab modifying entry CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab modify complete ldap_modify: Server is unwilling to perform (53) additional info: 00000561: SvcErr: DSID-031A1254, problem 5003 (WILL_NOT_PERFORM), data 0 add member: CN=alantest,CN=Users,DC=exchange,DC=lab modifying entry CN=Account Operators,CN=Builtin,DC=exchange,DC=lab modify complete deleting entry "CN=alan-del-scenario,OU=o365,DC=exchange,DC=lab" delete complete 20200427150345,954.0Z = Current OS UTC time stamp ############################################################################## Step 9 - # Query ADS endpoint for snapshot 2 ############################################################################## dxsearch -LLL -h dc2016.exchange.lab -p 389 -x -D CN=Administrator,CN=Users,DC=exchange,DC=lab -y /tmp/.ads.pwd -b dc=exchange,dc=lab '(&(objectClass=User)(memberOf=*))' memberOf | perl -p00e 's/\r?\n //g' > snapshot_2_ads_schema.ldif ldifsort snapshot_2_ads_schema.ldif snapshot_2_sorted_ads_schema.ldif creating buckets creating sort cluster 1 of size 200 sorting 0 records creating sort cluster 2 of size 200 sorting 200 records creating sort cluster 3 of size 200 sorting 400 records 3 buckets created sorting 587 records 587 records sorted, 0 bad records 20200427150345,985.0Z = Current OS UTC time stamp ############################################################################## Step 10 - # Find the delta for any removed objects ############################################################################## ldifdelta -x -S ads_schema snapshot_2_sorted_ads_schema.ldif snapshot_1_sorted_ads_schema.ldif dn: CN=eeeee,CN=Users,DC=exchange,DC=lab changetype: modify replace: memberOf memberOf: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab - dn: CN=alantest,CN=Users,DC=exchange,DC=lab changetype: modify replace: memberOf memberOf: CN=Backup Operators,CN=Builtin,DC=exchange,DC=lab memberOf: CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab memberOf: CN=Help Desk,OU=Microsoft Exchange Security Groups,DC=exchange,DC=la b - dn: CN=Test User 001,CN=Users,DC=exchange,DC=lab changetype: modify replace: memberOf memberOf: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab - dn: CN=alan-del-scenario,OU=o365,DC=exchange,DC=lab changetype: add memberOf: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab ldifdelta summary: 587 entries in old file 588 entries in new file Produced: 1 add entry records 0 delete entry records 3 modify entry records 20200427150346,070.0Z = Current OS UTC time stamp ############################################################################## Step 11a: Convert from User ldapmodify syntax of 'overwrite' of 'replace' ############################################################################## dn: CN=eeeee,CN=Users,DC=exchange,DC=lab changetype: modify replace: memberOf memberOf: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab - dn: CN=alantest,CN=Users,DC=exchange,DC=lab changetype: modify replace: memberOf memberOf: CN=Backup Operators,CN=Builtin,DC=exchange,DC=lab memberOf: CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab memberOf: CN=Help Desk,OU=Microsoft Exchange Security Groups,DC=exchange,DC=lab - dn: CN=Test User 001,CN=Users,DC=exchange,DC=lab changetype: modify replace: memberOf memberOf: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab - dn: CN=alan-del-scenario,OU=o365,DC=exchange,DC=lab changetype: add memberOf: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab 20200427150346,163.0Z = Current OS UTC time stamp ############################################################################## Step 11b: Convert to ADS Group ldapmodify syntax with a 'merge' of 'add' for the group objects ############################################################################## dn: CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab changetype: modify add: member member: CN=alantest,CN=Users,DC=exchange,DC=lab dn: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab changetype: modify add: member member: CN=eeeee,CN=Users,DC=exchange,DC=lab member: CN=Test User 001,CN=Users,DC=exchange,DC=lab dn: CN=Backup Operators,CN=Builtin,DC=exchange,DC=lab changetype: modify add: member member: CN=alantest,CN=Users,DC=exchange,DC=lab dn: CN=Help Desk,OU=Microsoft Exchange Security Groups,DC=exchange,DC=lab changetype: modify add: member member: CN=alantest,CN=Users,DC=exchange,DC=lab # Ignoring Users: [CN=alan-del-scenario,OU=o365,DC=exchange,DC=lab <-> CN=Account Operators,CN=Builtin,DC=exchange,DC=lab] Reason: User NOT present in the latest Snapshot! Cannot add to group. 20200427150346,172.0Z = Current OS UTC time stamp ############################################################################## Step 11c: Query ADS Group member(s) before Roll back process ############################################################################## dn: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab member: CN=alantest,CN=Users,DC=exchange,DC=lab dn: CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab 20200427150346,185.0Z = Current OS UTC time stamp ############################################################################## Step 12: Roll back change to ADS User membershipOf to ADS ############################################################################## Ignore the false positive warning message of: (ENTRY_EXISTS) - This is the 'merge' process ############################################################################## dxmodify -c -H ldap://dc2016.exchange.lab:389 -D CN=Administrator,CN=Users,DC=exchange,DC=lab -y /tmp/.ads.pwd -f group_mod_syntax.ldif modifying entry CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab modifying entry CN=Account Operators,CN=Builtin,DC=exchange,DC=lab modifying entry CN=Backup Operators,CN=Builtin,DC=exchange,DC=lab ldap_modify: Already exists (68) additional info: 00000562: UpdErr: DSID-031A11E2, problem 6005 (ENTRY_EXISTS), data 0 modifying entry CN=Help Desk,OU=Microsoft Exchange Security Groups,DC=exchange,DC=lab ldap_modify: Already exists (68) additional info: 00000562: UpdErr: DSID-031A11E2, problem 6005 (ENTRY_EXISTS), data 0 20200427150346,194.0Z = Current OS UTC time stamp ############################################################################## Step 13: Query ADS Group member after Roll back process ############################################################################## dn: CN=Account Operators,CN=Builtin,DC=exchange,DC=lab member: CN=eeeee,CN=Users,DC=exchange,DC=lab member: CN=Test User 001,CN=Users,DC=exchange,DC=lab member: CN=alantest,CN=Users,DC=exchange,DC=lab dn: CN=Access Control Assistance Operators,CN=Builtin,DC=exchange,DC=lab member: CN=alantest,CN=Users,DC=exchange,DC=lab dn: CN=Backup Operators,CN=Builtin,DC=exchange,DC=lab member: CN=alantest,CN=Users,DC=exchange,DC=lab dn: CN=Help Desk,OU=Microsoft Exchange Security Groups,DC=exchange,DC=lab member: CN=alantest,CN=Users,DC=exchange,DC=lab