Example #1
0
File: api.py Project: nrensen/samba
    def test_binary_encode(self):
        encoded = ldb.binary_encode(b"test\\x")
        decoded = ldb.binary_decode(encoded)
        self.assertEqual(decoded, b"test\\x")

        encoded2 = ldb.binary_encode("test\\x")
        self.assertEqual(encoded2, encoded)
Example #2
0
File: gpo.py Project: rti7743/samba
def get_gpo_info(samdb, gpo=None, displayname=None, dn=None):
    '''Get GPO information using gpo, displayname or dn'''

    policies_dn = samdb.get_default_basedn()
    policies_dn.add_child(ldb.Dn(samdb, "CN=Policies,CN=System"))

    base_dn = policies_dn
    search_expr = "(objectClass=groupPolicyContainer)"
    search_scope = ldb.SCOPE_ONELEVEL

    if gpo is not None:
        search_expr = "(&(objectClass=groupPolicyContainer)(name=%s))" % ldb.binary_encode(gpo)

    if displayname is not None:
        search_expr = "(&(objectClass=groupPolicyContainer)(displayname=%s))" % ldb.binary_encode(displayname)

    if dn is not None:
        base_dn = dn
        search_scope = ldb.SCOPE_BASE

    try:
        msg = samdb.search(base=base_dn, scope=search_scope,
                            expression=search_expr,
                            attrs=['nTSecurityDescriptor',
                                    'versionNumber',
                                    'flags',
                                    'name',
                                    'displayName',
                                    'gPCFileSysPath'])
    except Exception, e:
        if gpo is not None:
            mesg = "Cannot get information for GPO %s" % gpo
        else:
            mesg = "Cannot get information for GPOs"
        raise CommandError(mesg, e)
Example #3
0
    def test_binary_encode(self):
        encoded = ldb.binary_encode(b'test\\x')
        decoded = ldb.binary_decode(encoded)
        self.assertEqual(decoded, b'test\\x')

        encoded2 = ldb.binary_encode('test\\x')
        self.assertEqual(encoded2, encoded)
Example #4
0
    def add_remove_group_members(self, groupname, listofmembers,
                                  add_members_operation=True):
        """Adds or removes group members

        :param groupname: Name of the target group
        :param listofmembers: Comma-separated list of group members
        :param add_members_operation: Defines if its an add or remove
            operation
        """

        groupfilter = "(&(sAMAccountName=%s)(objectCategory=%s,%s))" % (
            ldb.binary_encode(groupname), "CN=Group,CN=Schema,CN=Configuration", self.domain_dn())
        groupmembers = listofmembers.split(',')

        self.transaction_start()
        try:
            targetgroup = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE,
                               expression=groupfilter, attrs=['member'])
            if len(targetgroup) == 0:
                raise Exception('Unable to find group "%s"' % groupname)
            assert(len(targetgroup) == 1)

            modified = False

            addtargettogroup = """
dn: %s
changetype: modify
""" % (str(targetgroup[0].dn))

            for member in groupmembers:
                targetmember = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE,
                                    expression="(|(sAMAccountName=%s)(CN=%s))" % (
                    ldb.binary_encode(member), ldb.binary_encode(member)), attrs=[])

                if len(targetmember) != 1:
                    continue

                if add_members_operation is True and (targetgroup[0].get('member') is None or str(targetmember[0].dn) not in targetgroup[0]['member']):
                    modified = True
                    addtargettogroup += """add: member
member: %s
""" % (str(targetmember[0].dn))

                elif add_members_operation is False and (targetgroup[0].get('member') is not None and str(targetmember[0].dn) in targetgroup[0]['member']):
                    modified = True
                    addtargettogroup += """delete: member
member: %s
""" % (str(targetmember[0].dn))

            if modified is True:
                self.modify_ldif(addtargettogroup)

        except:
            self.transaction_cancel()
            raise
        else:
            self.transaction_commit()
Example #5
0
File: gpo.py Project: rti7743/samba
    def run(self, username, H=None, sambaopts=None, credopts=None, versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        self.url = dc_url(self.lp, self.creds, H)

        samdb_connect(self)

        try:
            msg = self.samdb.search(expression='(&(|(samAccountName=%s)(samAccountName=%s$))(objectClass=User))' %
                                                (ldb.binary_encode(username),ldb.binary_encode(username)))
            user_dn = msg[0].dn
        except Exception, e:
            raise CommandError("Failed to find account %s" % username, e)
Example #6
0
    def run(self, computername, credopts=None, sambaopts=None, versionopts=None,
            H=None, computer_attrs=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)

        attrs = None
        if computer_attrs:
            attrs = computer_attrs.split(",")

        samaccountname = computername
        if not computername.endswith('$'):
            samaccountname = "%s$" % computername

        filter = ("(&(sAMAccountType=%d)(sAMAccountName=%s))" %
                  (dsdb.ATYPE_WORKSTATION_TRUST,
                   ldb.binary_encode(samaccountname)))

        domaindn = samdb.domain_dn()

        try:
            res = samdb.search(base=domaindn, expression=filter,
                               scope=ldb.SCOPE_SUBTREE, attrs=attrs)
            computer_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find computer "%s"' %
                               samaccountname)

        for msg in res:
            computer_ldif = samdb.write_ldif(msg, ldb.CHANGETYPE_NONE)
            self.outf.write(computer_ldif)
Example #7
0
    def run(self,
            groupname,
            credopts=None,
            sambaopts=None,
            versionopts=None,
            H=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H,
                      session_info=system_session(),
                      credentials=creds,
                      lp=lp)

        filter = ("(&(sAMAccountName=%s)(objectClass=group))" %
                  ldb.binary_encode(groupname))

        try:
            res = samdb.search(base=samdb.domain_dn(),
                               scope=ldb.SCOPE_SUBTREE,
                               expression=filter,
                               attrs=["dn"])
            group_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find group "%s"' % (groupname))

        try:
            samdb.delete(group_dn)
        except Exception as e:
            # FIXME: catch more specific exception
            raise CommandError('Failed to remove group "%s"' % groupname, e)
        self.outf.write("Deleted group %s\n" % groupname)
Example #8
0
    def rename_domain_partition(self, logger, samdb, new_netbios_name):
        '''Renames the domain parition object and updates its nETBIOSName'''

        # lookup the crossRef object that holds the nETBIOSName (nCName has
        # already been updated by this point, but the netBIOS hasn't)
        base_dn = samdb.get_default_basedn()
        nc_name = ldb.binary_encode(str(base_dn))
        partitions_dn = samdb.get_partitions_dn()
        res = samdb.search(base=partitions_dn, scope=ldb.SCOPE_ONELEVEL,
                           attrs=["nETBIOSName"],
                           expression='ncName=%s' % nc_name)

        logger.info("Changing backup domain's NetBIOS name to %s" %
                    new_netbios_name)
        m = ldb.Message()
        m.dn = res[0].dn
        m["nETBIOSName"] = ldb.MessageElement(new_netbios_name,
                                              ldb.FLAG_MOD_REPLACE,
                                              "nETBIOSName")
        samdb.modify(m)

        # renames the object itself to reflect the change in domain
        new_dn = "CN=%s,%s" % (new_netbios_name, partitions_dn)
        logger.info("Renaming %s --> %s" % (res[0].dn, new_dn))
        samdb.rename(res[0].dn, new_dn, controls=['relax:0'])
Example #9
0
 def run(self, user, credopts=None, sambaopts=None, versionopts=None):
     lp = sambaopts.get_loadparm()
     creds = credopts.get_credentials(lp)
     paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
     sam = SamDB(paths.samdb, session_info=system_session(),
                 credentials=creds, lp=lp)
     # TODO once I understand how, use the domain info to naildown
     # to the correct domain
     (cleaneduser, realm, domain) = _get_user_realm_domain(user)
     self.outf.write(cleaneduser + "\n")
     res = sam.search(
         expression="samaccountname=%s" % ldb.binary_encode(cleaneduser),
         scope=ldb.SCOPE_SUBTREE, attrs=["servicePrincipalName"])
     if len(res) > 0:
         spns = res[0].get("servicePrincipalName")
         if spns is not None:
             self.outf.write(
                 "User %s has the following servicePrincipalName: \n" %
                 res[0].dn)
             for e in spns:
                 self.outf.write("\t %s\n" % e)
         else:
             self.outf.write("User %s has no servicePrincipalName\n" %
                             res[0].dn)
     else:
         raise CommandError("User %s not found" % user)
Example #10
0
    def run(self, groupname, new_parent_dn, credopts=None, sambaopts=None,
            versionopts=None, H=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)
        domain_dn = ldb.Dn(samdb, samdb.domain_dn())

        filter = ("(&(sAMAccountName=%s)(objectClass=group))" %
                  ldb.binary_encode(groupname))
        try:
            res = samdb.search(base=domain_dn,
                               expression=filter,
                               scope=ldb.SCOPE_SUBTREE)
            group_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find group "%s"' % (groupname))

        try:
            full_new_parent_dn = samdb.normalize_dn_in_domain(new_parent_dn)
        except Exception as e:
            raise CommandError('Invalid new_parent_dn "%s": %s' %
                               (new_parent_dn, e.message))

        full_new_group_dn = ldb.Dn(samdb, str(group_dn))
        full_new_group_dn.remove_base_components(len(group_dn) - 1)
        full_new_group_dn.add_base(full_new_parent_dn)

        try:
            samdb.rename(group_dn, full_new_group_dn)
        except Exception as e:
            raise CommandError('Failed to move group "%s"' % groupname, e)
        self.outf.write('Moved group "%s" into "%s"\n' %
                        (groupname, full_new_parent_dn))
Example #11
0
def remove_dc(samdb, logger, dc_name):

    # TODO: Check if this is the last server (covered mostly by
    # refusing to remove our own name)

    samdb.transaction_start()

    server_dn = None

    # Allow the name to be a the nTDS-DSA GUID
    try:
        ntds_guid = uuid.UUID(hex=dc_name)
        ntds_dn = "<GUID=%s>" % ntds_guid
    except ValueError:
        try:
            server_msgs = samdb.search(base=samdb.get_config_basedn(),
                                       attrs=[],
                                       expression="(&(objectClass=server)"
                                       "(cn=%s))" % ldb.binary_encode(dc_name))
        except LdbError as (enum, estr):
            raise DemoteException(
                "Failure checking if %s is an server "
                "object in %s: " % (dc_name, samdb.domain_dns_name()), estr)

        if (len(server_msgs) == 0):
            raise DemoteException("%s is not an AD DC in %s" %
                                  (dc_name, samdb.domain_dns_name()))
        server_dn = server_msgs[0].dn

        ntds_dn = ldb.Dn(samdb, "CN=NTDS Settings")
        ntds_dn.add_base(server_dn)
        pass
Example #12
0
    def run(self, computername, new_ou_dn, credopts=None, sambaopts=None,
            versionopts=None, H=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)
        domain_dn = ldb.Dn(samdb, samdb.domain_dn())

        samaccountname = computername
        if not computername.endswith('$'):
            samaccountname = "%s$" % computername

        filter = ("(&(sAMAccountName=%s)(sAMAccountType=%u))" %
                  (ldb.binary_encode(samaccountname),
                   dsdb.ATYPE_WORKSTATION_TRUST))
        try:
            res = samdb.search(base=domain_dn,
                               expression=filter,
                               scope=ldb.SCOPE_SUBTREE)
            computer_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find computer "%s"' % (computername))

        full_new_ou_dn = ldb.Dn(samdb, new_ou_dn)
        if not full_new_ou_dn.is_child_of(domain_dn):
            full_new_ou_dn.add_base(domain_dn)
        new_computer_dn = ldb.Dn(samdb, str(computer_dn))
        new_computer_dn.remove_base_components(len(computer_dn) -1)
        new_computer_dn.add_base(full_new_ou_dn)
        try:
            samdb.rename(computer_dn, new_computer_dn)
        except Exception as e:
            raise CommandError('Failed to move computer "%s"' % computername, e)
        self.outf.write('Moved computer "%s" to "%s"\n' %
                        (computername, new_ou_dn))
Example #13
0
    def run(self, computername, credopts=None, sambaopts=None, versionopts=None,
            H=None, computer_attrs=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)

        attrs = None
        if computer_attrs:
            attrs = computer_attrs.split(",")

        samaccountname = computername
        if not computername.endswith('$'):
            samaccountname = "%s$" % computername

        filter = ("(&(sAMAccountType=%d)(sAMAccountName=%s))" %
                  (dsdb.ATYPE_WORKSTATION_TRUST,
                   ldb.binary_encode(samaccountname)))

        domaindn = samdb.domain_dn()

        try:
            res = samdb.search(base=domaindn, expression=filter,
                               scope=ldb.SCOPE_SUBTREE, attrs=attrs)
            computer_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find computer "%s"' %
                               samaccountname)

        for msg in res:
            computer_ldif = common.get_ldif_for_editor(samdb, msg)
            self.outf.write(computer_ldif)
Example #14
0
    def run(self,
            username=None,
            sambaopts=None,
            credopts=None,
            versionopts=None,
            H=None,
            filter=None,
            days=None,
            noexpiry=None):
        if username is None and filter is None:
            raise CommandError(
                "Either the username or '--filter' must be specified!")

        if filter is None:
            filter = "(&(objectClass=user)(sAMAccountName=%s))" % (
                ldb.binary_encode(username))

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        samdb = SamDB(url=H,
                      session_info=system_session(),
                      credentials=creds,
                      lp=lp)

        try:
            samdb.setexpiry(filter, days * 24 * 3600, no_expiry_req=noexpiry)
        except Exception, msg:
            # FIXME: Catch more specific exception
            raise CommandError("Failed to set expiry for user '%s': %s" %
                               (username or filter, msg))
Example #15
0
    def run(self, computername, new_ou_dn, credopts=None, sambaopts=None,
            versionopts=None, H=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)
        domain_dn = ldb.Dn(samdb, samdb.domain_dn())

        samaccountname = computername
        if not computername.endswith('$'):
            samaccountname = "%s$" % computername

        filter = ("(&(sAMAccountName=%s)(sAMAccountType=%u))" %
                  (ldb.binary_encode(samaccountname),
                   dsdb.ATYPE_WORKSTATION_TRUST))
        try:
            res = samdb.search(base=domain_dn,
                               expression=filter,
                               scope=ldb.SCOPE_SUBTREE)
            computer_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find computer "%s"' % (computername))

        full_new_ou_dn = ldb.Dn(samdb, new_ou_dn)
        if not full_new_ou_dn.is_child_of(domain_dn):
            full_new_ou_dn.add_base(domain_dn)
        new_computer_dn = ldb.Dn(samdb, str(computer_dn))
        new_computer_dn.remove_base_components(len(computer_dn)-1)
        new_computer_dn.add_base(full_new_ou_dn)
        try:
            samdb.rename(computer_dn, new_computer_dn)
        except Exception as e:
            raise CommandError('Failed to move computer "%s"' % computername, e)
        self.outf.write('Moved computer "%s" to "%s"\n' %
                        (computername, new_ou_dn))
Example #16
0
    def run(self, groupname, credopts=None, sambaopts=None, versionopts=None,
            H=None, group_attrs=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)

        attrs = None
        if group_attrs:
            attrs = group_attrs.split(",")

        filter = ("(&(objectCategory=group)(sAMAccountName=%s))" %
                   ldb.binary_encode(groupname))

        domaindn = samdb.domain_dn()

        try:
            res = samdb.search(base=domaindn, expression=filter,
                               scope=ldb.SCOPE_SUBTREE, attrs=attrs)
            user_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find group "%s"' % (groupname))

        for msg in res:
            group_ldif = common.get_ldif_for_editor(samdb, msg)
            self.outf.write(group_ldif)
Example #17
0
    def run(self,
            username=None,
            sambaopts=None,
            credopts=None,
            versionopts=None,
            filter=None,
            H=None):
        if username is None and filter is None:
            raise CommandError(
                "Either the username or '--filter' must be specified!")

        if filter is None:
            filter = "(&(objectClass=user)(sAMAccountName=%s))" % (
                ldb.binary_encode(username))

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)

        samdb = SamDB(url=H,
                      session_info=system_session(),
                      credentials=creds,
                      lp=lp)
        try:
            samdb.enable_account(filter)
        except Exception, msg:
            raise CommandError("Failed to enable user '%s': %s" %
                               (username or filter, msg))
Example #18
0
def remove_dc(samdb, logger, dc_name):

    # TODO: Check if this is the last server (covered mostly by
    # refusing to remove our own name)

    samdb.transaction_start()

    server_dn = None

    # Allow the name to be a the nTDS-DSA GUID
    try:
        ntds_guid = uuid.UUID(hex=dc_name)
        ntds_dn = "<GUID=%s>" % ntds_guid
    except ValueError:
        try:
            server_msgs = samdb.search(base=samdb.get_config_basedn(),
                                       attrs=[],
                                       expression="(&(objectClass=server)"
                                       "(cn=%s))"
                                    % ldb.binary_encode(dc_name))
        except LdbError as (enum, estr):
            raise DemoteException("Failure checking if %s is an server "
                                  "object in %s: "
                                  % (dc_name, samdb.domain_dns_name()), estr)

        if (len(server_msgs) == 0):
            raise DemoteException("%s is not an AD DC in %s"
                                  % (dc_name, samdb.domain_dns_name()))
        server_dn = server_msgs[0].dn

        ntds_dn = ldb.Dn(samdb, "CN=NTDS Settings")
        ntds_dn.add_base(server_dn)
        pass
Example #19
0
File: user.py Project: sYnfo/samba
    def run(self, username=None, sambaopts=None, credopts=None,
            versionopts=None, H=None, filter=None, days=None, noexpiry=None):
        if username is None and filter is None:
            raise CommandError("Either the username or '--filter' must be specified!")

        if filter is None:
            filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        samdb = SamDB(url=H, session_info=system_session(),
            credentials=creds, lp=lp)

        try:
            samdb.setexpiry(filter, days*24*3600, no_expiry_req=noexpiry)
        except Exception as msg:
            # FIXME: Catch more specific exception
            raise CommandError("Failed to set expiry for user '%s': %s" % (
                username or filter, msg))
        if noexpiry:
            self.outf.write("Expiry for user '%s' disabled.\n" % (
                username or filter))
        else:
            self.outf.write("Expiry for user '%s' set to %u days.\n" % (
                username or filter, days))
Example #20
0
    def run(self, accountname, principal, H=None, credopts=None, sambaopts=None,
            versionopts=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        if H == None:
            path = paths.samdb
        else:
            path = H

        sam = SamDB(path, session_info=system_session(),
                    credentials=creds, lp=lp)
        # TODO once I understand how, use the domain info to naildown
        # to the correct domain
        (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)

        res = sam.search(expression="sAMAccountName=%s" %
                         ldb.binary_encode(cleanedaccount),
                         scope=ldb.SCOPE_SUBTREE,
                         attrs=["msDS-AllowedToDelegateTo"])
        if len(res) == 0:
            raise CommandError("Unable to find account name '%s'" % accountname)
        assert(len(res) == 1)

        msg = ldb.Message()
        msg.dn = res[0].dn
        msg["msDS-AllowedToDelegateTo"] = ldb.MessageElement([principal],
                                          ldb.FLAG_MOD_DELETE,
                                          "msDS-AllowedToDelegateTo")
        try:
            sam.modify(msg)
        except Exception as err:
            raise CommandError(err)
Example #21
0
    def run(self, groupname, credopts=None, sambaopts=None, versionopts=None,
            H=None, group_attrs=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)

        attrs = None
        if group_attrs:
            attrs = group_attrs.split(",")

        filter = ("(&(sAMAccountType=%d)(sAMAccountName=%s))" %
                     ( ATYPE_SECURITY_GLOBAL_GROUP,
                       ldb.binary_encode(groupname)))

        domaindn = samdb.domain_dn()

        try:
            res = samdb.search(base=domaindn, expression=filter,
                               scope=ldb.SCOPE_SUBTREE, attrs=attrs)
            user_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find group "%s"' % (groupname))

        for msg in res:
            user_ldif = samdb.write_ldif(msg, ldb.CHANGETYPE_NONE)
            self.outf.write(user_ldif)
Example #22
0
    def run(self, username=None, filter=None, credopts=None, sambaopts=None,
            versionopts=None, H=None, newpassword=None,
            must_change_at_next_login=False, random_password=False,
            smartcard_required=False, clear_smartcard_required=False):
        if filter is None and username is None:
            raise CommandError("Either the username or '--filter' must be specified!")

        password = newpassword

        if smartcard_required:
            if password is not None and password is not '':
                raise CommandError('It is not allowed to specifiy '
                                   '--newpassword '
                                   'together with --smartcard-required.')
            if must_change_at_next_login:
                raise CommandError('It is not allowed to specifiy '
                                   '--must-change-at-next-login '
                                   'together with --smartcard-required.')
            if clear_smartcard_required:
                raise CommandError('It is not allowed to specifiy '
                                   '--clear-smartcard-required '
                                   'together with --smartcard-required.')

        if random_password and not smartcard_required:
            password = generate_random_password(128, 255)

        while True:
            if smartcard_required:
                break
            if password is not None and password is not '':
                break
            password = getpass("New Password: "******"Retype Password: "******"Sorry, passwords do not match.\n")

        if filter is None:
            filter = "(&(objectClass=user)(sAMAccountName=%s))" % (ldb.binary_encode(username))

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)

        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)

        if smartcard_required:
            command = ""
            try:
                command = "Failed to set UF_SMARTCARD_REQUIRED for user '%s'" % (username or filter)
                flags = dsdb.UF_SMARTCARD_REQUIRED
                samdb.toggle_userAccountFlags(filter, flags, on=True)
                command = "Failed to enable account for user '%s'" % (username or filter)
                samdb.enable_account(filter)
            except Exception, msg:
                # FIXME: catch more specific exception
                raise CommandError("%s: %s" % (command, msg))
            self.outf.write("Added UF_SMARTCARD_REQUIRED OK\n")
Example #23
0
File: user.py Project: runt18/samba
    def run(self, username=None, filter=None, credopts=None, sambaopts=None,
            versionopts=None, H=None, newpassword=None,
            must_change_at_next_login=False, random_password=False):
        if filter is None and username is None:
            raise CommandError("Either the username or '--filter' must be specified!")

        if random_password:
            password = generate_random_password(128, 255)
        else:
            password = newpassword

        while 1:
            if password is not None and password is not '':
                break
            password = getpass("New Password: "******"(&(objectClass=user)(sAMAccountName={0!s}))".format((ldb.binary_encode(username)))

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)

        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)

        try:
            samdb.setpassword(filter, password,
                              force_change_at_next_login=must_change_at_next_login,
                              username=username)
        except Exception, msg:
            # FIXME: catch more specific exception
            raise CommandError("Failed to set password for user '{0!s}': {1!s}".format(username or filter, msg))
Example #24
0
    def run(self, accountname, onoff, credopts=None, sambaopts=None, versionopts=None):

        on = False
        if onoff == "on":
            on = True
        elif onoff == "off":
            on = False
        else:
            raise CommandError("Invalid argument [%s]" % onoff)

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        sam = SamDB(paths.samdb, session_info=system_session(),
                    credentials=creds, lp=lp)
        # TODO once I understand how, use the domain info to naildown
        # to the correct domain
        (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)

        search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
        flag = dsdb.UF_TRUSTED_FOR_DELEGATION
        try:
            sam.toggle_userAccountFlags(search_filter, flag, on=on, strict=True)
        except Exception, err:
            raise CommandError(err)
Example #25
0
    def run(self, accountname, credopts=None, sambaopts=None, versionopts=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        sam = SamDB(paths.samdb, session_info=system_session(),
                    credentials=creds, lp=lp)
        # TODO once I understand how, use the domain info to naildown
        # to the correct domain
        (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)
        print "Searching for: %s" % (cleanedaccount)
        res = sam.search(expression="sAMAccountName=%s" % ldb.binary_encode(cleanedaccount),
                            scope=ldb.SCOPE_SUBTREE,
                            attrs=["userAccountControl", "msDS-AllowedToDelegateTo"])
        if len(res) != 1:
            raise CommandError("Account %s found %d times" % (accountname, len(res)))

        uac = int(res[0].get("userAccountControl")[0])
        allowed = res[0].get("msDS-AllowedToDelegateTo")

        print "Account-DN: %s" %  str(res[0].dn)

        if uac & dsdb.UF_TRUSTED_FOR_DELEGATION:
            print "UF_TRUSTED_FOR_DELEGATION: 1"
        else:
            print "UF_TRUSTED_FOR_DELEGATION: 0"

        if uac & dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION:
            print "UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: 1"
        else:
            print "UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: 0"

        if allowed != None:
            for a in allowed:
                print "msDS-AllowedToDelegateTo: %s" % (str(a))
 def invalid_user(self, username):
     ret = self.samdb.search(
         base=self.samdb.domain_dn(),
         scope=ldb.SCOPE_SUBTREE,
         expression="(sAMAccountName=%s)" % ldb.binary_encode(username),
     )
     return len(ret) != 1
Example #27
0
    def run(self, accountname, credopts=None, sambaopts=None, versionopts=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        sam = SamDB(paths.samdb, session_info=system_session(),
                    credentials=creds, lp=lp)
        # TODO once I understand how, use the domain info to naildown
        # to the correct domain
        (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)

        res = sam.search(expression="sAMAccountName=%s" %
                    ldb.binary_encode(cleanedaccount),
                    scope=ldb.SCOPE_SUBTREE,
                    attrs=["userAccountControl", "msDS-AllowedToDelegateTo"])
        if len(res) == 0:
            raise CommandError("Unable to find account name '%s'" % accountname)
        assert(len(res) == 1)

        uac = int(res[0].get("userAccountControl")[0])
        allowed = res[0].get("msDS-AllowedToDelegateTo")

        self.outf.write("Account-DN: %s\n" %  str(res[0].dn))
        self.outf.write("UF_TRUSTED_FOR_DELEGATION: %s\n"
            % bool(uac & dsdb.UF_TRUSTED_FOR_DELEGATION))
        self.outf.write("UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION: %s\n" %
              bool(uac & dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION))

        if allowed is not None:
            for a in allowed:
                self.outf.write("msDS-AllowedToDelegateTo: %s\n" % a)
Example #28
0
 def run(self, user, credopts=None, sambaopts=None, versionopts=None):
     lp = sambaopts.get_loadparm()
     creds = credopts.get_credentials(lp)
     paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
     sam = SamDB(paths.samdb, session_info=system_session(),
                 credentials=creds, lp=lp)
     # TODO once I understand how, use the domain info to naildown
     # to the correct domain
     (cleaneduser, realm, domain) = _get_user_realm_domain(user)
     self.outf.write(cleaneduser+"\n")
     res = sam.search(expression="samaccountname=%s" % ldb.binary_encode(cleaneduser),
                         scope=ldb.SCOPE_SUBTREE,
                         attrs=["servicePrincipalName"])
     if len(res) >0:
         spns = res[0].get("servicePrincipalName")
         found = False
         flag = ldb.FLAG_MOD_ADD
         if spns != None:
             self.outf.write(
                 "User %s has the following servicePrincipalName: \n" %
                 res[0].dn)
             for e in spns:
                 self.outf.write("\t %s\n" % e)
         else:
             self.outf.write("User %s has no servicePrincipalName" %
                 res[0].dn)
     else:
         raise CommandError("User %s not found" % user)
Example #29
0
    def run(self, accountname, onoff, H=None, credopts=None, sambaopts=None,
            versionopts=None):

        on = False
        if onoff == "on":
            on = True
        elif onoff == "off":
            on = False
        else:
            raise CommandError("invalid argument: '%s' (choose from 'on', 'off')" % onoff)

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        if H == None:
            path = paths.samdb
        else:
            path = H

        sam = SamDB(path, session_info=system_session(),
                    credentials=creds, lp=lp)
        # TODO once I understand how, use the domain info to naildown
        # to the correct domain
        (cleanedaccount, realm, domain) = _get_user_realm_domain(accountname)

        search_filter = "sAMAccountName=%s" % ldb.binary_encode(cleanedaccount)
        flag = dsdb.UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION
        try:
            sam.toggle_userAccountFlags(search_filter, flag,
                        flags_str="Trusted-to-Authenticate-for-Delegation",
                        on=on, strict=True)
        except Exception as err:
            raise CommandError(err)
Example #30
0
    def run(self,
            groupname,
            gidnumber,
            credopts=None,
            sambaopts=None,
            versionopts=None,
            H=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        samdb = SamDB(url=H,
                      session_info=system_session(),
                      credentials=creds,
                      lp=lp)

        domaindn = samdb.domain_dn()

        # Check group exists and doesn't have a gidNumber
        filter = "(samaccountname={})".format(ldb.binary_encode(groupname))
        res = samdb.search(domaindn,
                           scope=ldb.SCOPE_SUBTREE,
                           expression=filter)
        if (len(res) == 0):
            raise CommandError("Unable to find group '{}'".format(groupname))

        group_dn = res[0].dn

        if "gidNumber" in res[0]:
            raise CommandError("Group {} is a Unix group.".format(groupname))

        # Check if supplied gidnumber isn't already being used
        filter = "(&(objectClass=group)(gidNumber={}))".format(gidnumber)
        res = samdb.search(domaindn,
                           scope=ldb.SCOPE_SUBTREE,
                           expression=filter)
        if (len(res) != 0):
            raise CommandError('gidNumber {} already used.'.format(gidnumber))

        if not lp.get("idmap_ldb:use rfc2307"):
            self.outf.write("You are setting a Unix/RFC2307 GID. "
                            "You may want to set 'idmap_ldb:use rfc2307 = Yes'"
                            " in smb.conf to use the attributes for "
                            "XID/SID-mapping.\n")

        group_mod = """
dn: {0}
changetype: modify
add: gidNumber
gidNumber: {1}
""".format(group_dn, gidnumber)

        try:
            samdb.modify_ldif(group_mod)
        except ldb.LdbError as e:
            raise CommandError("Failed to modify group '{0}': {1}".format(
                groupname, e))

        self.outf.write("Modified Group '{}' successfully\n".format(groupname))
Example #31
0
    def newcomputer(self, computername, computerou=None, description=None,
                    prepare_oldjoin=False, ip_address_list=None,
                    service_principal_name_list=None):
        """Adds a new user with additional parameters

        :param computername: Name of the new computer
        :param computerou: Object container for new computer
        :param description: Description of the new computer
        :param prepare_oldjoin: Preset computer password for oldjoin mechanism
        :param ip_address_list: ip address list for DNS A or AAAA record
        :param service_principal_name_list: string list of servicePincipalName
        """

        cn = re.sub(r"\$$", "", computername)
        if cn.count('$'):
            raise Exception('Illegal computername "%s"' % computername)
        samaccountname = "%s$" % cn

        computercontainer_dn = "CN=Computers,%s" % self.domain_dn()
        if computerou:
            computercontainer_dn = self.normalize_dn_in_domain(computerou)

        computer_dn = "CN=%s,%s" % (cn, computercontainer_dn)

        ldbmessage = {"dn": computer_dn,
                      "sAMAccountName": samaccountname,
                      "objectClass": "computer",
                      }

        if description is not None:
            ldbmessage["description"] = description

        if service_principal_name_list:
            ldbmessage["servicePrincipalName"] = service_principal_name_list

        accountcontrol = str(dsdb.UF_WORKSTATION_TRUST_ACCOUNT |
                             dsdb.UF_ACCOUNTDISABLE)
        if prepare_oldjoin:
            accountcontrol = str(dsdb.UF_WORKSTATION_TRUST_ACCOUNT)
        ldbmessage["userAccountControl"] = accountcontrol

        if ip_address_list:
            ldbmessage['dNSHostName'] = '{}.{}'.format(
                cn, self.domain_dns_name())

        self.transaction_start()
        try:
            self.add(ldbmessage)

            if prepare_oldjoin:
                password = cn.lower()
                self.setpassword(("(distinguishedName=%s)" %
                                  ldb.binary_encode(computer_dn)),
                                 password, False)
        except:
            self.transaction_cancel()
            raise
        else:
            self.transaction_commit()
 def find_email_of(self, username):
     ret = self.samdb.search(
         base=self.samdb.domain_dn(),
         scope=ldb.SCOPE_SUBTREE,
         attrs=["mail"],
         expression="(sAMAccountName=%s)" % ldb.binary_encode(username),
     )
     return ret[0]["mail"][0]
Example #33
0
File: user.py Project: GSam/samba
 def _find_user(self, name):
     search_filter = "(&(sAMAccountName=%s)(objectCategory=%s,%s))" % (ldb.binary_encode(name), "CN=Person,CN=Schema,CN=Configuration", self.samdb.domain_dn())
     userlist = self.samdb.search(base=self.samdb.domain_dn(),
                               scope=ldb.SCOPE_SUBTREE,
                               expression=search_filter, attrs=[])
     if userlist:
         return userlist[0]
     else:
         return None
Example #34
0
 def _find_user(self, name):
     search_filter = "(&(sAMAccountName=%s)(objectCategory=%s,%s))" % (ldb.binary_encode(name), "CN=Person,CN=Schema,CN=Configuration", self.samdb.domain_dn())
     userlist = self.samdb.search(base=self.samdb.domain_dn(),
                                  scope=ldb.SCOPE_SUBTREE,
                                  expression=search_filter)
     if userlist:
         return userlist[0]
     else:
         return None
Example #35
0
    def delete(self, **kwargs):
        try:
            con = self.connection_service.connection()
        except Exception as e:
            return ResponseStatus(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                  'Invalid server details "%s": ' % (e), None)
        samaccountname = kwargs['computer_name'] + "$"
        print(samaccountname)
        exp = (
            "(&(sAMAccountType=%d)(sAMAccountName=%s))" %
            (dsdb.ATYPE_WORKSTATION_TRUST, ldb.binary_encode(samaccountname)))
        domain_dn = con.domain_dn()

        try:
            res = con.search(base=domain_dn,
                             scope=ldb.SCOPE_SUBTREE,
                             expression=exp,
                             attrs=[])
            print(str(res))
            if len(res) == 0:
                return ResponseStatus(
                    status.HTTP_404_NOT_FOUND,
                    'Unable to find computer  "%s"\n' % computer_name, None)

            computer_dn = res[0].dn
            print("comp_dn: " + str(computer_dn))
            computer_ac = int(res[0]["userAccountControl"][0])
            if "dNSHostName" in res[0]:
                computer_dns_host_name = str(res[0]["dNSHostName"][0])
            else:
                computer_dns_host_name = None
        except Exception as e:
            return ResponseStatus(
                status.HTTP_404_NOT_FOUND,
                'Unable to find computer  "%s"\n' % samaccountname, None)

        computer_is_workstation = (computer_ac
                                   & dsdb.UF_WORKSTATION_TRUST_ACCOUNT)
        if not computer_is_workstation:
            print("Computer is not a workstation")
            return ResponseStatus(
                status.HTTP_409_CONFLICT,
                'Failed to remove computer "%s": ' % samaccountname)

        try:
            con.delete(computer_dn)
            if computer_dns_host_name:
                remove_dns_references(con,
                                      self.get_logger(),
                                      computer_dns_host_name,
                                      ignore_no_name=True)
        except Exception as e:
            return ResponseStatus(
                status.HTTP_409_CONFLICT,
                'Failed to delete computer "%s": %s' % (samaccountname, e),
                None)
        return ResponseStatus(status.HTTP_204_NO_CONTENT, None, None)
Example #36
0
    def cleanup_old_join(ctx):
        '''remove any DNs from a previous join'''
        try:
            # find the krbtgt link
            print("checking samaccountname")
            if ctx.subdomain:
                res = None
            else:
                res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
                                       expression='samAccountName=%s' %
                                       ldb.binary_encode(ctx.samname),
                                       attrs=["msDS-krbTgtLink"])
                if res:
                    ctx.del_noerror(res[0].dn, recursive=True)
            if ctx.connection_dn is not None:
                ctx.del_noerror(ctx.connection_dn)
            if ctx.krbtgt_dn is not None:
                ctx.del_noerror(ctx.krbtgt_dn)
            ctx.del_noerror(ctx.ntds_dn)
            ctx.del_noerror(ctx.server_dn, recursive=True)
            if ctx.topology_dn:
                ctx.del_noerror(ctx.topology_dn)
            if ctx.partition_dn:
                ctx.del_noerror(ctx.partition_dn)
            if res:
                ctx.new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0]
                ctx.del_noerror(ctx.new_krbtgt_dn)

            if ctx.subdomain:
                binding_options = "sign"
                lsaconn = lsa.lsarpc(
                    "ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options),
                    ctx.lp, ctx.creds)

                objectAttr = lsa.ObjectAttribute()
                objectAttr.sec_qos = lsa.QosInfo()

                pol_handle = lsaconn.OpenPolicy2(
                    ''.decode('utf-8'), objectAttr,
                    security.SEC_FLAG_MAXIMUM_ALLOWED)

                name = lsa.String()
                name.string = ctx.realm
                info = lsaconn.QueryTrustedDomainInfoByName(
                    pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)

                lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)

                name = lsa.String()
                name.string = ctx.forest_domain_name
                info = lsaconn.QueryTrustedDomainInfoByName(
                    pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)

                lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)

        except Exception:
            pass
Example #37
0
def get_gpo_info(samdb,
                 gpo=None,
                 displayname=None,
                 dn=None,
                 sd_flags=security.SECINFO_OWNER | security.SECINFO_GROUP
                 | security.SECINFO_DACL | security.SECINFO_SACL):
    '''Get GPO information using gpo, displayname or dn'''

    policies_dn = samdb.get_default_basedn()
    policies_dn.add_child(ldb.Dn(samdb, "CN=Policies,CN=System"))

    base_dn = policies_dn
    search_expr = "(objectClass=groupPolicyContainer)"
    search_scope = ldb.SCOPE_ONELEVEL

    if gpo is not None:
        search_expr = "(&(objectClass=groupPolicyContainer)(name=%s))" % ldb.binary_encode(
            gpo)

    if displayname is not None:
        search_expr = "(&(objectClass=groupPolicyContainer)(displayname=%s))" % ldb.binary_encode(
            displayname)

    if dn is not None:
        base_dn = dn
        search_scope = ldb.SCOPE_BASE

    try:
        msg = samdb.search(base=base_dn,
                           scope=search_scope,
                           expression=search_expr,
                           attrs=[
                               'nTSecurityDescriptor', 'versionNumber',
                               'flags', 'name', 'displayName', 'gPCFileSysPath'
                           ],
                           controls=['sd_flags:1:%d' % sd_flags])
    except Exception as e:
        if gpo is not None:
            mesg = "Cannot get information for GPO %s" % gpo
        else:
            mesg = "Cannot get information for GPOs"
        raise CommandError(mesg, e)

    return msg
Example #38
0
    def set_password(self, **kwargs):
        try:
            con = self.connection_service.connection()
        except Exception as e:
            return ResponseStatus(status.HTTP_500_INTERNAL_SERVER_ERROR,
                                  'Invalid server details "%s": ' % (e), None)
        request = kwargs['request']
        username = request['username']
        password = request['password']
        random_password = request['random_password']
        must_change_at_next_login = False

        if random_password == True:
            password = generate_random_password(128, 255)
            must_change_at_next_login = True
        print(must_change_at_next_login)
        filter = "(&(objectClass=user)(sAMAccountName=%s))" % (
            ldb.binary_encode(username))
        exp = ("(&(sAMAccountName=%s)(sAMAccountType=805306368))" %
               ldb.binary_encode(username))
        domain_dn = con.domain_dn()

        try:
            res = con.search(base=domain_dn,
                             scope=ldb.SCOPE_SUBTREE,
                             expression=exp,
                             attrs=["dn"])
            if (len(res) == 0):
                return ResponseStatus(status.HTTP_404_NOT_FOUND,
                                      'no user "%s"' % username, None)
        except Exception as e:
            return ResponseStatus(
                status.HTTP_400_BAD_REQUEST,
                'unable to find user "%s": %s' % (username, e), None)

        try:
            con.setpassword(
                filter,
                password,
                force_change_at_next_login=must_change_at_next_login,
                username=username)
        except Exception as e:
            return ResponseStatus(status.HTTP_409_CONFLICT, None, None)
        return ResponseStatus(status.HTTP_200_OK, None, None)
Example #39
0
    def run(self, groupname, credopts=None, sambaopts=None, versionopts=None,
            H=None, editor=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H, session_info=system_session(),
                      credentials=creds, lp=lp)

        filter = ("(&(sAMAccountName=%s)(objectClass=group))" %
                  ldb.binary_encode(groupname))

        domaindn = samdb.domain_dn()

        try:
            res = samdb.search(base=domaindn,
                               expression=filter,
                               scope=ldb.SCOPE_SUBTREE)
            group_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find group "%s"' % (groupname))

        if len(res) != 1:
            raise CommandError('Invalid number of results: for "%s": %d' %
                               ((groupname), len(res)))

        msg = res[0]
        result_ldif = common.get_ldif_for_editor(samdb, msg)

        if editor is None:
            editor = os.environ.get('EDITOR')
            if editor is None:
                editor = 'vi'

        with tempfile.NamedTemporaryFile(suffix=".tmp") as t_file:
            t_file.write(get_bytes(result_ldif))
            t_file.flush()
            try:
                check_call([editor, t_file.name])
            except CalledProcessError as e:
                raise CalledProcessError("ERROR: ", e)
            with open(t_file.name) as edited_file:
                edited_message = edited_file.read()

        msgs_edited = samdb.parse_ldif(edited_message)
        msg_edited = next(msgs_edited)[1]

        res_msg_diff = samdb.msg_diff(msg, msg_edited)
        if len(res_msg_diff) == 0:
            self.outf.write("Nothing to do\n")
            return

        try:
            samdb.modify(res_msg_diff)
        except Exception as e:
            raise CommandError("Failed to modify group '%s': " % groupname, e)

        self.outf.write("Modified group '%s' successfully\n" % groupname)
Example #40
0
File: spn.py Project: szaydel/samba
    def run(self, name, user, H=None,
            credopts=None,
            sambaopts=None,
            versionopts=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        sam = SamDB(H, session_info=system_session(),
                    credentials=creds, lp=lp)
        res = sam.search(
            expression="servicePrincipalName=%s" % ldb.binary_encode(name),
            scope=ldb.SCOPE_SUBTREE)
        if len(res) != 0:
            raise CommandError("Service principal %s already"
                               " affected to another user" % name)

        (cleaneduser, realm, domain) = _get_user_realm_domain(user)
        res = sam.search(
            expression="samaccountname=%s" % ldb.binary_encode(cleaneduser),
            scope=ldb.SCOPE_SUBTREE, attrs=["servicePrincipalName"])
        if len(res) > 0:
            res[0].dn
            msg = ldb.Message()
            spns = res[0].get("servicePrincipalName")
            tab = []
            found = False
            flag = ldb.FLAG_MOD_ADD
            if spns is not None:
                for e in spns:
                    if str(e) == name:
                        found = True
                    tab.append(str(e))
                flag = ldb.FLAG_MOD_REPLACE
            tab.append(name)
            msg.dn = res[0].dn
            msg["servicePrincipalName"] = ldb.MessageElement(tab, flag,
                                                             "servicePrincipalName")
            if not found:
                sam.modify(msg)
            else:
                raise CommandError("Service principal %s already"
                                   " affected to %s" % (name, user))
        else:
            raise CommandError("User %s not found" % user)
Example #41
0
File: spn.py Project: sYnfo/samba
    def run(self, name, user,  force=False, credopts=None, sambaopts=None,
            versionopts=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        sam = SamDB(paths.samdb, session_info=system_session(),
                    credentials=creds, lp=lp)
        res = sam.search(
            expression="servicePrincipalName=%s" % ldb.binary_encode(name),
            scope=ldb.SCOPE_SUBTREE)
        if len(res) != 0 and not force:
            raise CommandError("Service principal %s already"
                                   " affected to another user" % name)

        (cleaneduser, realm, domain) = _get_user_realm_domain(user)
        res = sam.search(
            expression="samaccountname=%s" % ldb.binary_encode(cleaneduser),
            scope=ldb.SCOPE_SUBTREE, attrs=["servicePrincipalName"])
        if len(res) >0:
            res[0].dn
            msg = ldb.Message()
            spns = res[0].get("servicePrincipalName")
            tab = []
            found = False
            flag = ldb.FLAG_MOD_ADD
            if spns is not None:
                for e in spns:
                    if str(e) == name:
                        found = True
                    tab.append(str(e))
                flag = ldb.FLAG_MOD_REPLACE
            tab.append(name)
            msg.dn = res[0].dn
            msg["servicePrincipalName"] = ldb.MessageElement(tab, flag,
                                                "servicePrincipalName")
            if not found:
                sam.modify(msg)
            else:
                raise CommandError("Service principal %s already"
                                       " affected to %s" % (name, user))
        else:
            raise CommandError("User %s not found" % user)
Example #42
0
def set_admin_password(logger, samdb, username):
    """Sets a randomly generated password for the backup DB's admin user"""

    adminpass = samba.generate_random_password(12, 32)
    logger.info("Setting %s password in backup to: %s" % (username, adminpass))
    logger.info("Run 'samba-tool user setpassword %s' after restoring DB" %
                username)
    samdb.setpassword("(&(objectClass=user)(sAMAccountName=%s))"
                      % ldb.binary_encode(username), adminpass,
                      force_change_at_next_login=False,
                      username=username)
Example #43
0
    def run(self,
            groupname,
            credopts=None,
            sambaopts=None,
            versionopts=None,
            H=None,
            full_dn=False):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)

        try:
            samdb = SamDB(url=H,
                          session_info=system_session(),
                          credentials=creds,
                          lp=lp)

            search_filter = ("(&(objectClass=group)(sAMAccountName=%s))" %
                             ldb.binary_encode(groupname))
            try:
                res = samdb.search(samdb.domain_dn(),
                                   scope=ldb.SCOPE_SUBTREE,
                                   expression=(search_filter),
                                   attrs=["objectSid"])
                group_sid_binary = res[0].get('objectSid', idx=0)
            except IndexError:
                raise CommandError('Unable to find group "%s"' % (groupname))

            group_sid = ndr_unpack(security.dom_sid, group_sid_binary)
            (group_dom_sid, rid) = group_sid.split()
            group_sid_dn = "<SID=%s>" % (group_sid)

            search_filter = ("(|(primaryGroupID=%s)(memberOf=%s))" %
                             (rid, group_sid_dn))
            res = samdb.search(samdb.domain_dn(),
                               scope=ldb.SCOPE_SUBTREE,
                               expression=(search_filter),
                               attrs=["samAccountName", "cn"])

            if (len(res) == 0):
                return

            for msg in res:
                if full_dn:
                    self.outf.write("%s\n" % msg.get("dn"))
                    continue

                member_name = msg.get("samAccountName", idx=0)
                if member_name is None:
                    member_name = msg.get("cn", idx=0)
                self.outf.write("%s\n" % member_name)

        except Exception as e:
            raise CommandError('Failed to list members of "%s" group - %s' %
                               (groupname, e))
Example #44
0
File: ou.py Project: szaydel/samba
 def _find_ou(self, name):
     search_filter = ("(&(name=%s)(objectCategory=%s,%s))" %
                      (ldb.binary_encode(name),
                       "CN=Organizational-Unit,CN=Schema,CN=Configuration",
                       self.samdb.domain_dn()))
     oulist = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE,
                                expression=search_filter)
     if oulist:
         return oulist[0]
     else:
         return None
Example #45
0
def create_subnet(samdb, configDn, subnet_name, site_name):
    """Create a subnet and associate it with a site.

    :param samdb: A samdb connection
    :param configDn: The DN of the configuration partition
    :param subnet_name: name of the subnet to create (a CIDR range)
    :return: None
    :raise SubnetAlreadyExists: if the subnet to be created already exists.
    :raise SiteNotFound: if the site does not exist.
    """
    ret = samdb.search(base=configDn,
                       scope=ldb.SCOPE_SUBTREE,
                       expression='(&(objectclass=Site)(cn=%s))' %
                       ldb.binary_encode(site_name))
    if len(ret) != 1:
        raise SiteNotFound('A site with the name %s does not exist' %
                           site_name)
    dn_site = ret[0].dn

    if not isinstance(subnet_name, str):
        raise SubnetInvalid("%s is not a valid subnet (not a string)" %
                            subnet_name)

    dnsubnet = ldb.Dn(samdb, "CN=Subnets,CN=Sites")
    if dnsubnet.add_base(configDn) == False:
        raise SubnetException("dnsubnet.add_base() failed")
    if dnsubnet.add_child("CN=X") == False:
        raise SubnetException("dnsubnet.add_child() failed")
    dnsubnet.set_component(0, "CN", subnet_name)

    try:
        m = ldb.Message()
        m.dn = dnsubnet
        m["objectclass"] = ldb.MessageElement("subnet", FLAG_MOD_ADD,
                                              "objectclass")
        m["siteObject"] = ldb.MessageElement(str(dn_site), FLAG_MOD_ADD,
                                             "siteObject")
        samdb.add(m)
    except ldb.LdbError as e:
        (enum, estr) = e.args
        if enum == ldb.ERR_INVALID_DN_SYNTAX:
            raise SubnetInvalid("%s is not a valid subnet: %s" %
                                (subnet_name, estr))
        elif enum == ldb.ERR_ENTRY_ALREADY_EXISTS:
            # Subnet collisions are checked by exact match only, not
            # overlapping range. This won't stop you creating
            # 10.1.1.0/24 when there is already 10.1.0.0/16, or
            # prevent you from having numerous IPv6 subnets that refer
            # to the same range (e.g 5::0/16, 5::/16, 5:0:0::/16).
            raise SubnetAlreadyExists(
                'A subnet with the CIDR %s already exists' % subnet_name)
        else:
            raise
Example #46
0
File: spn.py Project: auralic/Samba
    def run(self,
            name,
            user=None,
            credopts=None,
            sambaopts=None,
            versionopts=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        sam = SamDB(paths.samdb,
                    session_info=system_session(),
                    credentials=creds,
                    lp=lp)
        res = sam.search(expression="servicePrincipalName=%s" %
                         ldb.binary_encode(name),
                         scope=ldb.SCOPE_SUBTREE,
                         attrs=["servicePrincipalName", "samAccountName"])
        if len(res) > 0:
            result = None
            if user is not None:
                (cleaneduser, realm, domain) = _get_user_realm_domain(user)
                for elem in res:
                    if str(elem["samAccountName"]).lower() == cleaneduser:
                        result = elem
                if result is None:
                    raise CommandError("Unable to find user %s with"
                                       " spn %s" % (user, name))
            else:
                if len(res) != 1:
                    listUser = ""
                    for r in res:
                        listUser = "******" % (listUser, str(r.dn))
                    raise CommandError(
                        "More than one user has the spn %s "
                        "and no specific user was specified, list of users"
                        " with this spn:%s" % (name, listUser))
                else:
                    result = res[0]

            msg = ldb.Message()
            spns = result.get("servicePrincipalName")
            tab = []
            if spns is not None:
                for e in spns:
                    if str(e) != name:
                        tab.append(str(e))
                flag = ldb.FLAG_MOD_REPLACE
            msg.dn = result.dn
            msg["servicePrincipalName"] = ldb.MessageElement(
                tab, flag, "servicePrincipalName")
            sam.modify(msg)
        else:
            raise CommandError("Service principal %s not affected" % name)
Example #47
0
    def run(self,
            computername,
            credopts=None,
            sambaopts=None,
            versionopts=None,
            H=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)

        samdb = SamDB(url=H,
                      session_info=system_session(),
                      credentials=creds,
                      lp=lp)

        samaccountname = computername
        if not computername.endswith('$'):
            samaccountname = "%s$" % computername

        filter = (
            "(&(sAMAccountName=%s)(sAMAccountType=%u))" %
            (ldb.binary_encode(samaccountname), dsdb.ATYPE_WORKSTATION_TRUST))
        try:
            res = samdb.search(base=samdb.domain_dn(),
                               scope=ldb.SCOPE_SUBTREE,
                               expression=filter,
                               attrs=["userAccountControl", "dNSHostName"])
            computer_dn = res[0].dn
            computer_ac = int(res[0]["userAccountControl"][0])
            if "dNSHostName" in res[0]:
                computer_dns_host_name = res[0]["dNSHostName"][0]
            else:
                computer_dns_host_name = None
        except IndexError:
            raise CommandError('Unable to find computer "%s"' % computername)

        computer_is_workstation = (computer_ac
                                   & dsdb.UF_WORKSTATION_TRUST_ACCOUNT)
        if not computer_is_workstation:
            raise CommandError(
                'Failed to remove computer "%s": '
                'Computer is not a workstation - removal denied' %
                computername)
        try:
            samdb.delete(computer_dn)
            if computer_dns_host_name:
                remove_dns_references(samdb,
                                      self.get_logger(),
                                      computer_dns_host_name,
                                      ignore_no_name=True)
        except Exception as e:
            raise CommandError(
                'Failed to remove computer "%s"' % samaccountname, e)
        self.outf.write("Deleted computer %s\n" % computername)
Example #48
0
    def run(self,
            contactname,
            sambaopts=None,
            credopts=None,
            versionopts=None,
            H=None,
            contact_attrs=None):

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        samdb = SamDB(url=H,
                      session_info=system_session(),
                      credentials=creds,
                      lp=lp)
        base_dn = samdb.domain_dn()
        scope = ldb.SCOPE_SUBTREE

        attrs = None
        if contact_attrs:
            attrs = contact_attrs.split(",")

        filter = ("(&(objectClass=contact)(name=%s))" %
                  ldb.binary_encode(contactname))

        if contactname.upper().startswith("CN="):
            # contact is specified by DN
            filter = "(objectClass=contact)"
            scope = ldb.SCOPE_BASE
            try:
                base_dn = samdb.normalize_dn_in_domain(contactname)
            except Exception as e:
                raise CommandError('Invalid dn "%s": %s' %
                                   (contactname, e))

        try:
            res = samdb.search(base=base_dn,
                               expression=filter,
                               scope=scope,
                               attrs=attrs)
            contact_dn = res[0].dn
        except IndexError:
            raise CommandError('Unable to find contact "%s"' % (contactname))

        if len(res) > 1:
            for msg in sorted(res, key=attrgetter('dn')):
                self.outf.write("found: %s\n" % msg.dn)
            raise CommandError("Multiple results for contact '%s'\n"
                               "Please specify the contact's DN" %
                               contactname)

        for msg in res:
            contact_ldif = common.get_ldif_for_editor(samdb, msg)
            self.outf.write(contact_ldif)
Example #49
0
 def _find_contact(self, name):
     contactname = name
     search_filter = ("(&(objectClass=contact)(name=%s))" %
                      ldb.binary_encode(contactname))
     contactlist = self.samdb.search(base=self.samdb.domain_dn(),
                                     scope=ldb.SCOPE_SUBTREE,
                                     expression=search_filter,
                                     attrs=[])
     if contactlist:
         return contactlist[0]
     else:
         return None
Example #50
0
    def cleanup_old_join(ctx):
        """remove any DNs from a previous join"""
        try:
            # find the krbtgt link
            print ("checking sAMAccountName")
            if ctx.subdomain:
                res = None
            else:
                res = ctx.samdb.search(
                    base=ctx.samdb.get_default_basedn(),
                    expression="sAMAccountName=%s" % ldb.binary_encode(ctx.samname),
                    attrs=["msDS-krbTgtLink"],
                )
                if res:
                    ctx.del_noerror(res[0].dn, recursive=True)
            if ctx.connection_dn is not None:
                ctx.del_noerror(ctx.connection_dn)
            if ctx.krbtgt_dn is not None:
                ctx.del_noerror(ctx.krbtgt_dn)
            ctx.del_noerror(ctx.ntds_dn)
            ctx.del_noerror(ctx.server_dn, recursive=True)
            if ctx.topology_dn:
                ctx.del_noerror(ctx.topology_dn)
            if ctx.partition_dn:
                ctx.del_noerror(ctx.partition_dn)
            if res:
                ctx.new_krbtgt_dn = res[0]["msDS-Krbtgtlink"][0]
                ctx.del_noerror(ctx.new_krbtgt_dn)

            if ctx.subdomain:
                binding_options = "sign"
                lsaconn = lsa.lsarpc("ncacn_ip_tcp:%s[%s]" % (ctx.server, binding_options), ctx.lp, ctx.creds)

                objectAttr = lsa.ObjectAttribute()
                objectAttr.sec_qos = lsa.QosInfo()

                pol_handle = lsaconn.OpenPolicy2("".decode("utf-8"), objectAttr, security.SEC_FLAG_MAXIMUM_ALLOWED)

                name = lsa.String()
                name.string = ctx.realm
                info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)

                lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)

                name = lsa.String()
                name.string = ctx.forest_domain_name
                info = lsaconn.QueryTrustedDomainInfoByName(pol_handle, name, lsa.LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)

                lsaconn.DeleteTrustedDomain(pol_handle, info.info_ex.sid)

        except Exception:
            pass
Example #51
0
 def _find_group(self, name):
     search_filter = (
         "(&(sAMAccountName=%s)(objectCategory=%s,%s))" %
         (ldb.binary_encode(name), "CN=Group,CN=Schema,CN=Configuration",
          self.samdb.domain_dn()))
     grouplist = self.samdb.search(base=self.samdb.domain_dn(),
                                   scope=ldb.SCOPE_SUBTREE,
                                   expression=search_filter,
                                   attrs=[])
     if grouplist:
         return grouplist[0]
     else:
         return None
Example #52
0
 def _find_ou(self, name):
     search_filter = ("(&(name=%s)(objectCategory=%s,%s))" %
                      (ldb.binary_encode(name),
                      "CN=Organizational-Unit,CN=Schema,CN=Configuration",
                      self.samdb.domain_dn()))
     oulist = self.samdb.search(base=self.samdb.domain_dn(),
                                scope=ldb.SCOPE_SUBTREE,
                                expression=search_filter,
                                attrs=[])
     if oulist:
         return oulist[0]
     else:
         return None
Example #53
0
    def run(self,
            username,
            H=None,
            sambaopts=None,
            credopts=None,
            versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        self.url = dc_url(self.lp, self.creds, H)

        samdb_connect(self)

        try:
            msg = self.samdb.search(
                expression=
                '(&(|(samAccountName=%s)(samAccountName=%s$))(objectClass=User))'
                % (ldb.binary_encode(username), ldb.binary_encode(username)))
            user_dn = msg[0].dn
        except Exception, e:
            raise CommandError("Failed to find account %s" % username, e)
Example #54
0
def create_subnet(samdb, configDn, subnet_name, site_name):
    """Create a subnet and associate it with a site.

    :param samdb: A samdb connection
    :param configDn: The DN of the configuration partition
    :param subnet_name: name of the subnet to create (a CIDR range)
    :return: None
    :raise SubnetAlreadyExists: if the subnet to be created already exists.
    :raise SiteNotFound: if the site does not exist.
    """
    ret = samdb.search(base=configDn, scope=ldb.SCOPE_SUBTREE,
                       expression='(&(objectclass=Site)(cn=%s))' %
                       ldb.binary_encode(site_name))
    if len(ret) != 1:
        raise SiteNotFound('A site with the name %s does not exist' %
                           site_name)
    dn_site = ret[0].dn

    if not isinstance(subnet_name, str):
        raise SubnetInvalid("%s is not a valid subnet (not a string)" % subnet_name)

    dnsubnet = ldb.Dn(samdb, "CN=Subnets,CN=Sites")
    if dnsubnet.add_base(configDn) == False:
        raise SubnetException("dnsubnet.add_base() failed")
    if dnsubnet.add_child("CN=X") == False:
        raise SubnetException("dnsubnet.add_child() failed")
    dnsubnet.set_component(0, "CN", subnet_name)

    try:
        m = ldb.Message()
        m.dn = dnsubnet
        m["objectclass"] = ldb.MessageElement("subnet", FLAG_MOD_ADD,
                                              "objectclass")
        m["siteObject"] = ldb.MessageElement(str(dn_site), FLAG_MOD_ADD,
                                             "siteObject")
        samdb.add(m)
    except ldb.LdbError as e:
        (enum, estr) = e.args
        if enum == ldb.ERR_INVALID_DN_SYNTAX:
            raise SubnetInvalid("%s is not a valid subnet: %s" % (subnet_name, estr))
        elif enum == ldb.ERR_ENTRY_ALREADY_EXISTS:
            # Subnet collisions are checked by exact match only, not
            # overlapping range. This won't stop you creating
            # 10.1.1.0/24 when there is already 10.1.0.0/16, or
            # prevent you from having numerous IPv6 subnets that refer
            # to the same range (e.g 5::0/16, 5::/16, 5:0:0::/16).
            raise SubnetAlreadyExists('A subnet with the CIDR %s already exists'
                                      % subnet_name)
        else:
            raise
Example #55
0
    def run(self,
            username=None,
            filter=None,
            credopts=None,
            sambaopts=None,
            versionopts=None,
            H=None,
            newpassword=None,
            must_change_at_next_login=False,
            random_password=False):
        if filter is None and username is None:
            raise CommandError(
                "Either the username or '--filter' must be specified!")

        if random_password:
            password = generate_random_password(128, 255)
        else:
            password = newpassword

        while 1:
            if password is not None and password is not '':
                break
            password = getpass("New Password: "******"(&(objectClass=user)(sAMAccountName=%s))" % (
                ldb.binary_encode(username))

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        creds.set_gensec_features(creds.get_gensec_features()
                                  | gensec.FEATURE_SEAL)

        samdb = SamDB(url=H,
                      session_info=system_session(),
                      credentials=creds,
                      lp=lp)

        try:
            samdb.setpassword(
                filter,
                password,
                force_change_at_next_login=must_change_at_next_login,
                username=username)
        except Exception, msg:
            # FIXME: catch more specific exception
            raise CommandError("Failed to set password for user '%s': %s" %
                               (username or filter, msg))
Example #56
0
 def _find_computer(self, name):
     samaccountname = name
     if not name.endswith('$'):
         samaccountname = "%s$" % name
     search_filter = ("(&(sAMAccountName=%s)(objectCategory=%s,%s))" %
                      (ldb.binary_encode(samaccountname),
                      "CN=Computer,CN=Schema,CN=Configuration",
                      self.samdb.domain_dn()))
     computerlist = self.samdb.search(base=self.samdb.domain_dn(),
                               scope=ldb.SCOPE_SUBTREE,
                               expression=search_filter, attrs=[])
     if computerlist:
         return computerlist[0]
     else:
         return None
Example #57
0
File: spn.py Project: sYnfo/samba
    def run(self, name, user=None, credopts=None, sambaopts=None,
            versionopts=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        paths = provision.provision_paths_from_lp(lp, lp.get("realm"))
        sam = SamDB(paths.samdb, session_info=system_session(),
                    credentials=creds, lp=lp)
        res = sam.search(
            expression="servicePrincipalName=%s" % ldb.binary_encode(name),
            scope=ldb.SCOPE_SUBTREE,
            attrs=["servicePrincipalName", "samAccountName"])
        if len(res) >0:
            result = None
            if user is not None:
                (cleaneduser, realm, domain) = _get_user_realm_domain(user)
                for elem in res:
                    if str(elem["samAccountName"]).lower() == cleaneduser:
                        result = elem
                if result is None:
                    raise CommandError("Unable to find user %s with"
                                           " spn %s" % (user, name))
            else:
                if len(res) != 1:
                    listUser = ""
                    for r in res:
                        listUser = "******" % (listUser, str(r.dn))
                    raise CommandError("More than one user has the spn %s "
                           "and no specific user was specified, list of users"
                           " with this spn:%s" % (name, listUser))
                else:
                    result=res[0]


            msg = ldb.Message()
            spns = result.get("servicePrincipalName")
            tab = []
            if spns is not None:
                for e in spns:
                    if str(e) != name:
                        tab.append(str(e))
                flag = ldb.FLAG_MOD_REPLACE
            msg.dn = result.dn
            msg["servicePrincipalName"] = ldb.MessageElement(tab, flag,
                                            "servicePrincipalName")
            sam.modify(msg)
        else:
            raise CommandError("Service principal %s not affected" % name)
Example #58
0
 def _find_service_principal_name(self, name, expected_service_principal_names):
     """Find all servicePrincipalName values and compare with expected_service_principal_names"""
     samaccountname = name.strip('$') + '$'
     search_filter = ("(&(sAMAccountName=%s)(objectCategory=%s,%s))" %
                      (ldb.binary_encode(samaccountname),
                       "CN=Computer,CN=Schema,CN=Configuration",
                       self.samdb.domain_dn()))
     computer_list = self.samdb.search(
         base=self.samdb.domain_dn(),
         scope=ldb.SCOPE_SUBTREE,
         expression=search_filter,
         attrs=['servicePrincipalName'])
     names = set()
     for computer in computer_list:
         for name in computer.get('servicePrincipalName', []):
             names.add(name)
     return names == set(expected_service_principal_names)
Example #59
0
File: user.py Project: runt18/samba
    def run(self, username=None, sambaopts=None, credopts=None,
            versionopts=None, filter=None, H=None):
        if username is None and filter is None:
            raise CommandError("Either the username or '--filter' must be specified!")

        if filter is None:
            filter = "(&(objectClass=user)(sAMAccountName={0!s}))".format((ldb.binary_encode(username)))

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)

        samdb = SamDB(url=H, session_info=system_session(),
            credentials=creds, lp=lp)
        try:
            samdb.disable_account(filter)
        except Exception, msg:
            raise CommandError("Failed to disable user '{0!s}': {1!s}".format(username or filter, msg))
Example #60
0
    def promote_possible(ctx):
        """confirm that the account is just a bare NT4 BDC or a member server, so can be safely promoted"""
        if ctx.subdomain:
            # This shouldn't happen
            raise Exception("Can not promote into a subdomain")

        res = ctx.samdb.search(base=ctx.samdb.get_default_basedn(),
                               expression='sAMAccountName=%s' % ldb.binary_encode(ctx.samname),
                               attrs=["msDS-krbTgtLink", "userAccountControl", "serverReferenceBL", "rIDSetReferences"])
        if len(res) == 0:
            raise Exception("Could not find domain member account '%s' to promote to a DC, use 'samba-tool domain join' instead'" % ctx.samname)
        if "msDS-krbTgtLink" in res[0] or "serverReferenceBL" in res[0] or "rIDSetReferences" in res[0]:
            raise Exception("Account '%s' appears to be an active DC, use 'samba-tool domain join' if you must re-create this account" % ctx.samname)
        if (int(res[0]["userAccountControl"][0]) & (samba.dsdb.UF_WORKSTATION_TRUST_ACCOUNT|samba.dsdb.UF_SERVER_TRUST_ACCOUNT) == 0):
            raise Exception("Account %s is not a domain member or a bare NT4 BDC, use 'samba-tool domain join' instead'" % ctx.samname)

        ctx.promote_from_dn = res[0].dn