# # SPDX-FileCopyrightText: 2024 Splunk, Inc. # SPDX-License-Identifier: LicenseRef-Splunk-8-2021 # # import csv import sys import log import logging # Map for possible property flags property_flags = { "1": "SCRIPT", "2": "ACCOUNTDISABLE", "8": "HOMEDIR_REQUIRED", "16": "LOCKOUT", "32": "PASSWD_NOTREQD", "64": "PASSWD_CANT_CHANGE", "128": "ENCRYPTED_TEXT_PWD_ALLOWED", "256": "TEMP_DUPLICATE_ACCOUNT", "512": "NORMAL_ACCOUNT", "2048": "INTERDOMAIN_TRUST_ACCOUNT", "4096": "WORKSTATION_TRUST_ACCOUNT", "8192": "SERVER_TRUST_ACCOUNT", "65536": "DONT_EXPIRE_PASSWORD", "131072": "MNS_LOGON_ACCOUNT", "262144": "SMARTCARD_REQUIRED", "524288": "TRUSTED_FOR_DELEGATION", "1048576": "NOT_DELEGATED", "2097152": "USE_DES_KEY_ONLY", "4194304": "DONT_REQ_PREAUTH", "8388608": "PASSWORD_EXPIRED", "16777216": "TRUSTED_TO_AUTH_FOR_DELEGATION", "67108864": "PARTIAL_SECRETS_ACCOUNT", } def main(): logger = log.Log().get_logger("user_account_control_property") logger.info("Lookup script started executing..") # prints usage of the lookup script if wrong number of arguments provided if len(sys.argv) != 3: logger.debug( "Usage: python user_account_control_property.py [userAccountControl] [userAccountPropertyFlag]" ) logger.debug("Lookup script stopped..") sys.exit(1) # Lookup Field names userAccountControl = sys.argv[1] userAccountPropertyFlag = sys.argv[2] infile = sys.stdin outfile = sys.stdout r = csv.DictReader(infile) w = csv.DictWriter(outfile, fieldnames=r.fieldnames) w.writeheader() # Decode flags for every 'userAccountControl' attribute value present in a search result for result in r: try: if result[userAccountControl].isdigit(): attribute_value = int(result[userAccountControl]) bit_cnt = 0 incorrect_result_flag = False flags = list() # Prepare flag list by decoding 'userAccountcontrol' decimal value # As 'userAccountControl' is decimal value, For each bit set to '1' a property flag can be denoted by using 'property_flags' map given above while attribute_value != 0: if attribute_value & 1 == 1: flags.append(str(1 << bit_cnt)) attribute_value = attribute_value >> 1 bit_cnt += 1 # If flag not present in 'property_flags' map, The 'userAccountPropertyFlag' won't be populated in search result for flag in flags: if flag not in list(property_flags.keys()): logger.debug( "'userAccountControl' attribute can not be decoded for value: {}".format( result[userAccountControl] ) ) incorrect_result_flag = True break if incorrect_result_flag: continue else: for flag in flags: result[userAccountPropertyFlag] = property_flags[flag] w.writerow(result) else: logger.debug( "'userAccountControl' attribute can not be decoded for value: {}".format( result[userAccountControl] ) ) except: logger.debug( "No results for 'userAccountControl' attribute value :{}".format( result[userAccountControl] ) ) if __name__ == "__main__": main()