Example #1
0
    def run(self, username, password=None, credopts=None, sambaopts=None,
            versionopts=None, H=None, must_change_at_next_login=False, random_password=False,
            use_username_as_cn=False, userou=None, surname=None, given_name=None, initials=None,
            profile_path=None, script_path=None, home_drive=None, home_directory=None,
            job_title=None, department=None, company=None, description=None,
            mail_address=None, internet_address=None, telephone_number=None, physical_delivery_office=None):

        if random_password:
            password = generate_random_password(128, 255)

        while 1:
            if password is not None and password is not '':
                break
            password = getpass("New Password: "******"Failed to add user '%s': " % username, e)
Example #2
0
    def test_ldap_change_password(self):
        def isLastExpectedMessage(msg):
            return (msg["type"] == "Authentication" and
                    msg["Authentication"]["status"]
                        == "NT_STATUS_OK" and
                    msg["Authentication"]["serviceDescription"]
                        == "LDAP Password Change" and
                    msg["Authentication"]["authDescription"]
                        == "LDAP Modify")

        new_password = samba.generate_random_password(32,32)
        self.ldb.modify_ldif(
            "dn: cn=" + USER_NAME + ",cn=users," + self.base_dn + "\n" +
            "changetype: modify\n" +
            "delete: userPassword\n" +
            "userPassword: "******"\n" +
            "add: userPassword\n" +
            "userPassword: "******"\n"
        )

        messages = self.waitForMessages(isLastExpectedMessage)
        print "Received %d messages" % len(messages)
        self.assertEquals(4,
                          len(messages),
                          "Did not receive the expected number of messages")
Example #3
0
    def create_user_account(self):
        self.user_pass = samba.generate_random_password(32, 32)
        self.user_name = USER_NAME
        self.user_dn = "cn=%s,%s" % (self.user_name, self.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(self.ldb, self.user_dn)

        utf16pw = unicode('"' + self.user_pass.encode('utf-8') + '"',
                          'utf-8').encode('utf-16-le')
        self.ldb.add({
            "dn": self.user_dn,
            "objectclass": "user",
            "sAMAccountName": "%s" % self.user_name,
            "userAccountControl": str(UF_NORMAL_ACCOUNT),
            "unicodePwd": utf16pw
        })

        self.user_creds = Credentials()
        self.user_creds.guess(self.get_loadparm())
        self.user_creds.set_password(self.user_pass)
        self.user_creds.set_username(self.user_name)
        self.user_creds.set_workstation(self.machine_name)
        pass
Example #4
0
    def create_machine_account(self):
        self.machine_pass = samba.generate_random_password(32, 32)
        self.machine_name = MACHINE_NAME
        self.machine_dn = "cn=%s,%s" % (self.machine_name,
                                        self.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(self.ldb, self.machine_dn)

        utf16pw = unicode('"' + self.machine_pass.encode('utf-8') + '"',
                          'utf-8').encode('utf-16-le')
        self.ldb.add({
            "dn":
            self.machine_dn,
            "objectclass":
            "computer",
            "sAMAccountName":
            "%s$" % self.machine_name,
            "userAccountControl":
            str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
            "unicodePwd":
            utf16pw
        })

        self.machine_creds = Credentials()
        self.machine_creds.guess(self.get_loadparm())
        self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
        self.machine_creds.set_password(self.machine_pass)
        self.machine_creds.set_username(self.machine_name + "$")
        self.machine_creds.set_workstation(self.machine_name)
Example #5
0
    def create_user_account(self):
        self.user_pass = samba.generate_random_password(32, 32)
        self.user_name = USER_NAME
        self.user_dn = "cn=%s,%s" % (self.user_name, self.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(self.ldb, self.user_dn)

        utf16pw = unicode(
            '"' + self.user_pass.encode('utf-8') + '"', 'utf-8'
        ).encode('utf-16-le')
        self.ldb.add({
            "dn": self.user_dn,
            "objectclass": "user",
            "sAMAccountName": "%s" % self.user_name,
            "userAccountControl": str(UF_NORMAL_ACCOUNT),
            "unicodePwd": utf16pw})

        self.user_creds = Credentials()
        self.user_creds.guess(self.get_loadparm())
        self.user_creds.set_password(self.user_pass)
        self.user_creds.set_username(self.user_name)
        self.user_creds.set_workstation(self.machine_name)
        pass
Example #6
0
    def create_machine_account(self):
        self.machine_pass = samba.generate_random_password(32, 32)
        self.machine_name = MACHINE_NAME
        self.machine_dn = "cn=%s,%s" % (self.machine_name, self.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(self.ldb, self.machine_dn)

        utf16pw = unicode(
            '"' + self.machine_pass.encode('utf-8') + '"', 'utf-8'
        ).encode('utf-16-le')
        self.ldb.add({
            "dn": self.machine_dn,
            "objectclass": "computer",
            "sAMAccountName": "%s$" % self.machine_name,
            "userAccountControl":
                str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
            "unicodePwd": utf16pw})

        self.machine_creds = Credentials()
        self.machine_creds.guess(self.get_loadparm())
        self.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
        self.machine_creds.set_kerberos_state(DONT_USE_KERBEROS)
        self.machine_creds.set_password(self.machine_pass)
        self.machine_creds.set_username(self.machine_name + "$")
        self.machine_creds.set_workstation(self.machine_name)
Example #7
0
    def test_ldap_replace_password(self):

        dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn
        self.discardSetupMessages(dn)

        new_password = samba.generate_random_password(32, 32)
        self.ldb.modify_ldif("dn: " + dn + "\n" + "changetype: modify\n" +
                             "replace: userPassword\n" + "userPassword: "******"\n")

        messages = self.waitForMessages(1, dn=dn)
        print("Received %d messages" % len(messages))
        self.assertEquals(1, len(messages),
                          "Did not receive the expected number of messages")

        audit = messages[0]["dsdbChange"]
        self.assertEquals("Modify", audit["operation"])
        self.assertFalse(audit["performedAsSystem"])
        self.assertTrue(dn.lower(), audit["dn"].lower())
        self.assertRegexpMatches(audit["remoteAddress"], self.remoteAddress)
        self.assertTrue(self.is_guid(audit["sessionId"]))
        session_id = self.get_session()
        self.assertEquals(session_id, audit["sessionId"])
        service_description = self.get_service_description()
        self.assertEquals(service_description, "LDAP")
        self.assertTrue(self.is_guid(audit["transactionId"]))

        attributes = audit["attributes"]
        self.assertEquals(1, len(attributes))
        actions = attributes["userPassword"]["actions"]
        self.assertEquals(1, len(actions))
        self.assertTrue(actions[0]["redacted"])
        self.assertEquals("replace", actions[0]["action"])
Example #8
0
    def do_Netr_ServerPasswordSet2(self):
        c = self.get_netlogon_connection()
        (authenticator, subsequent) = self.get_authenticator(c)
        PWD_LEN = 32
        DATA_LEN = 512
        newpass = samba.generate_random_password(PWD_LEN, PWD_LEN)
        encoded = newpass.encode('utf-16-le')
        pwd_len = len(encoded)
        filler = [
            x if isinstance(x, int) else ord(x)
            for x in os.urandom(DATA_LEN - pwd_len)
        ]
        pwd = netlogon.netr_CryptPassword()
        pwd.length = pwd_len
        pwd.data = filler + [
            x if isinstance(x, int) else ord(x) for x in encoded
        ]
        self.machine_creds.encrypt_netr_crypt_password(pwd)
        c.netr_ServerPasswordSet2(self.server,
                                  self.machine_creds.get_workstation(),
                                  SEC_CHAN_WKSTA, self.machine_name,
                                  authenticator, pwd)

        self.machine_pass = newpass
        self.machine_creds.set_password(newpass)
Example #9
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 #10
0
    def test_ldap_change_password_bad_original_password(self):
        def isLastExpectedMessage(msg):
            return (
                (msg["type"] == "Authentication") and
                (msg["Authentication"]["status"] == "NT_STATUS_WRONG_PASSWORD")
                and (msg["Authentication"]["serviceDescription"]
                     == "LDAP Password Change")
                and (msg["Authentication"]["authDescription"] == "LDAP Modify")
                and
                (msg["Authentication"]["eventId"] == EVT_ID_UNSUCCESSFUL_LOGON)
                and (msg["Authentication"]["logonType"] == EVT_LOGON_NETWORK))

        new_password = samba.generate_random_password(32, 32)
        try:
            self.ldb.modify_ldif("dn: cn=" + USER_NAME + ",cn=users," +
                                 self.base_dn + "\n" + "changetype: modify\n" +
                                 "delete: userPassword\n" + "userPassword: "******"badPassword" + "\n" + "add: userPassword\n" +
                                 "userPassword: "******"\n")
            self.fail()
        except LdbError as e1:
            (num, msg) = e1.args
            pass

        messages = self.waitForMessages(isLastExpectedMessage)
        print("Received %d messages" % len(messages))
        self.assertEquals(4, len(messages),
                          "Did not receive the expected number of messages")
Example #11
0
    def test_ldap_change_password(self):
        def isLastExpectedMessage(msg):
            return (msg["type"] == "Authentication" and
                    msg["Authentication"]["status"]
                        == "NT_STATUS_OK" and
                    msg["Authentication"]["serviceDescription"]
                        == "LDAP Password Change" and
                    msg["Authentication"]["authDescription"]
                        == "LDAP Modify")

        new_password = samba.generate_random_password(32,32)
        self.ldb.modify_ldif(
            "dn: cn=" + USER_NAME + ",cn=users," + self.base_dn + "\n" +
            "changetype: modify\n" +
            "delete: userPassword\n" +
            "userPassword: "******"\n" +
            "add: userPassword\n" +
            "userPassword: "******"\n"
        )

        messages = self.waitForMessages(isLastExpectedMessage)
        print "Received %d messages" % len(messages)
        self.assertEquals(4,
                          len(messages),
                          "Did not receive the expected number of messages")
Example #12
0
    def test_ldap_change_password_bad_original_password(self):
        def isLastExpectedMessage(msg):
            return ((msg["type"] == "Authentication") and
                    (msg["Authentication"]["status"] ==
                        "NT_STATUS_WRONG_PASSWORD") and
                    (msg["Authentication"]["serviceDescription"] ==
                        "LDAP Password Change") and
                    (msg["Authentication"]["authDescription"] ==
                        "LDAP Modify"))

        new_password = samba.generate_random_password(32, 32)
        try:
            self.ldb.modify_ldif(
                "dn: cn=" + USER_NAME + ",cn=users," + self.base_dn + "\n" +
                "changetype: modify\n" +
                "delete: userPassword\n" +
                "userPassword: "******"badPassword" + "\n" +
                "add: userPassword\n" +
                "userPassword: "******"\n")
            self.fail()
        except LdbError as e1:
            (num, msg) = e1.args
            pass

        messages = self.waitForMessages(isLastExpectedMessage)
        print("Received %d messages" % len(messages))
        self.assertEquals(4,
                          len(messages),
                          "Did not receive the expected number of messages")
Example #13
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 #14
0
    def run(self, username, password=None, credopts=None, sambaopts=None,
            versionopts=None, H=None, must_change_at_next_login=False,
            random_password=False, use_username_as_cn=False, userou=None,
            surname=None, given_name=None, initials=None, profile_path=None,
            script_path=None, home_drive=None, home_directory=None,
            job_title=None, department=None, company=None, description=None,
            mail_address=None, internet_address=None, telephone_number=None,
            physical_delivery_office=None):

        if random_password:
            password = generate_random_password(128, 255)

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

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

        try:
            samdb = SamDB(url=H, session_info=system_session(),
                          credentials=creds, lp=lp)
            samdb.newuser(username, password, force_password_change_at_next_login_req=must_change_at_next_login,
                          useusernameascn=use_username_as_cn, userou=userou, surname=surname, givenname=given_name, initials=initials,
                          profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
                          jobtitle=job_title, department=department, company=company, description=description,
                          mailaddress=mail_address, internetaddress=internet_address,
                          telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office)
        except Exception, e:
            raise CommandError("Failed to add user '%s': " % username, e)
Example #15
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 #16
0
def join_subdomain(server=None, creds=None, lp=None, site=None, netbios_name=None,
                   targetdir=None, parent_domain=None, dnsdomain=None, netbios_domain=None):
    """join as a DC"""
    ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, parent_domain)
    ctx.subdomain = True
    ctx.parent_domain_name = ctx.domain_name
    ctx.domain_name = netbios_domain
    ctx.realm = dnsdomain
    ctx.parent_dnsdomain = ctx.dnsdomain
    ctx.parent_partition_dn = ctx.get_parent_partition_dn()
    ctx.dnsdomain = dnsdomain
    ctx.partition_dn = "CN=%s,CN=Partitions,%s" % (ctx.domain_name, ctx.config_dn)
    ctx.base_dn = samba.dn_from_dns_name(dnsdomain)
    ctx.domsid = str(security.random_sid())
    ctx.acct_dn = None
    ctx.dnshostname = "%s.%s" % (ctx.myname, ctx.dnsdomain)
    ctx.trustdom_pass = samba.generate_random_password(128, 128)

    ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION

    ctx.SPNs.append('E3514235-4B06-11D1-AB04-00C04FC2DCD2/$NTDSGUID/%s' % ctx.dnsdomain)
    ctx.secure_channel_type = misc.SEC_CHAN_BDC

    ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP |
                         drsuapi.DRSUAPI_DRS_INIT_SYNC |
                         drsuapi.DRSUAPI_DRS_PER_SYNC |
                         drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS |
                         drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
    ctx.domain_replica_flags = ctx.replica_flags

    ctx.do_join()
    print "Created domain %s (SID %s) as a DC" % (ctx.domain_name, ctx.domsid)
Example #17
0
def update_dns_account_password(samdb, secrets_ldb, names):
    """Update (change) the password of the dns both in the SAM db and in
       secret one

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param secrets_ldb: An LDB object related to the secrets.ldb file of a given
                        provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=dns-%s" % names.netbiosname
    secrets_msg = secrets_ldb.search(expression=expression)
    if len(secrets_msg) == 1:
        res = samdb.search(expression=expression, attrs=[])
        assert len(res) == 1

        msg = ldb.Message(res[0].dn)
        machinepass = samba.generate_random_password(128, 255)
        mputf16 = machinepass.encode("utf-16-le")
        msg["clearTextPassword"] = ldb.MessageElement(mputf16, ldb.FLAG_MOD_REPLACE, "clearTextPassword")

        samdb.modify(msg)

        res = samdb.search(expression=expression, attrs=["msDs-keyVersionNumber"])
        assert len(res) == 1
        kvno = str(res[0]["msDs-keyVersionNumber"])

        msg = ldb.Message(secrets_msg[0].dn)
        msg["secret"] = ldb.MessageElement(machinepass, ldb.FLAG_MOD_REPLACE, "secret")
        msg["msDS-KeyVersionNumber"] = ldb.MessageElement(kvno, ldb.FLAG_MOD_REPLACE, "msDS-KeyVersionNumber")

        secrets_ldb.modify(msg)
    def create_machine_account(cls):
        cls.machine_pass = samba.generate_random_password(32, 32)
        cls.machine_name = MACHINE_NAME
        cls.machine_dn = "cn=%s,%s" % (cls.machine_name, cls.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(cls.ldb, cls.machine_dn)

        utf16pw = ('"%s"' % cls.machine_pass).encode('utf-16-le')
        cls.ldb.add({
            "dn":
            cls.machine_dn,
            "objectclass":
            "computer",
            "sAMAccountName":
            "%s$" % cls.machine_name,
            "userAccountControl":
            str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
            "unicodePwd":
            utf16pw
        })

        cls.machine_creds = Credentials()
        cls.machine_creds.guess(cls.lp)
        cls.machine_creds.set_realm(cls.ldb.domain_dns_name().upper())
        cls.machine_creds.set_domain(cls.ldb.domain_netbios_name().upper())
        cls.machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
        cls.machine_creds.set_kerberos_state(DONT_USE_KERBEROS)
        cls.machine_creds.set_password(cls.machine_pass)
        cls.machine_creds.set_username(cls.machine_name + "$")
        cls.machine_creds.set_workstation(cls.machine_name)
Example #19
0
    def test_ldap_change_password_bad_user(self):
        def isLastExpectedMessage(msg):
            return (msg["type"] == "Authorization" and
                    msg["Authorization"]["serviceDescription"] == "LDAP" and
                    msg["Authorization"]["authType"] == "krb5")

        new_password = samba.generate_random_password(32, 32)
        try:
            self.ldb.modify_ldif(
                "dn: cn=" + "badUser" + ",cn=users," + self.base_dn + "\n" +
                "changetype: modify\n" +
                "delete: userPassword\n" +
                "userPassword: "******"\n" +
                "add: userPassword\n" +
                "userPassword: "******"\n")
            self.fail()
        except LdbError as e:
            (num, msg) = e.args
            pass

        messages = self.waitForMessages(isLastExpectedMessage)
        print("Received %d messages" % len(messages))
        self.assertEquals(3,
                          len(messages),
                          "Did not receive the expected number of messages")
Example #20
0
    def SetPassword(self):
        if not self._check_session():
            return json.dumps(self.AuthErr);

        try:

            rid = request.params.get("rid",self.rid)
            username = request.params.get("account","")
            password = request.params.get("password",samba.generate_random_password(7,15))


            #response.write(password);
            if(self.model.isAuthenticate()):
                if(not self.model.SetPassword(username,password)):
                    raise Exception(self.model.LastErrorNumber,self.model.LastErrorStr)

            UnlockUserAccount = request.params.get("UnlockUserAccount",False)
            if(UnlockUserAccount != False):
                if(not self.model.EnableAccount(rid,username,True)):
                    raise Exception(self.model.LastErrorNumber,self.model.LastErrorStr)

            ForcePasswordChange = request.params.get("ForcePasswordChange","off").strip();
            if(ForcePasswordChange == "on"):
                if(not self.model.ForcePasswordChangeAtNextLogin(rid,username)):
                    raise Exception(self.model.LastErrorNumber,self.model.LastErrorStr)
            else:
                if(not self.model.ForcePasswordChangeAtNextLogin(rid,username,False)):
                    raise Exception(self.model.LastErrorNumber,self.model.LastErrorStr)

        except Exception,e:
            if(len(e.args)>1):
                return json.dumps({'success': False, 'msg': e.args[1],'num':e.args[0]})
            else:
                return json.dumps({'success': False, 'msg': e.args,'num':-1})
    def create_user_account(cls):
        cls.user_pass = samba.generate_random_password(32, 32)
        cls.user_name = USER_NAME
        cls.user_dn = "cn=%s,%s" % (cls.user_name, cls.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(cls.ldb, cls.user_dn)

        utf16pw = ('"%s"' % cls.user_pass).encode('utf-16-le')
        cls.ldb.add({
            "dn": cls.user_dn,
            "objectclass": "user",
            "sAMAccountName": "%s" % cls.user_name,
            "userAccountControl": str(UF_NORMAL_ACCOUNT),
            "unicodePwd": utf16pw
        })

        cls.user_creds = Credentials()
        cls.user_creds.guess(cls.lp)
        cls.user_creds.set_realm(cls.ldb.domain_dns_name().upper())
        cls.user_creds.set_domain(cls.ldb.domain_netbios_name().upper())
        cls.user_creds.set_password(cls.user_pass)
        cls.user_creds.set_username(cls.user_name)
        cls.user_creds.set_workstation(cls.machine_name)
Example #22
0
    def test_supplementalCredentials_cleartext_pso(self):
        """Checks that a PSO's cleartext setting can override the domain's"""

        # create a user that stores plain-text passwords
        self.add_user(clear_text=True)

        # check that clear-text is present in the supplementary-credentials
        self.assert_cleartext(expect_cleartext=True, password=USER_PASS)

        # create a PSO overriding the plain-text setting & apply it to the user
        no_plaintext_pso = PasswordSettings("no-plaintext-PSO",
                                            self.ldb,
                                            precedence=200,
                                            store_plaintext=False)
        self.addCleanup(self.ldb.delete, no_plaintext_pso.dn)
        userdn = "cn=" + USER_NAME + ",cn=users," + self.base_dn
        no_plaintext_pso.apply_to(userdn)

        # set the password to update the cleartext password stored
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)

        # this time cleartext shouldn't be in the supplementary creds
        self.assert_cleartext(expect_cleartext=False)

        # unapply PSO, update password, and check we get the cleartext again
        no_plaintext_pso.unapply(userdn)
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
        self.assert_cleartext(expect_cleartext=True, password=new_password)

        # Now update the domain setting and check we no longer get cleartext
        self.set_store_cleartext(False)
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
        self.assert_cleartext(expect_cleartext=False)

        # create a PSO overriding the domain setting & apply it to the user
        plaintext_pso = PasswordSettings("plaintext-PSO",
                                         self.ldb,
                                         precedence=100,
                                         store_plaintext=True)
        self.addCleanup(self.ldb.delete, plaintext_pso.dn)
        plaintext_pso.apply_to(userdn)
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
        self.assert_cleartext(expect_cleartext=True, password=new_password)
Example #23
0
    def test_supplementalCredentials_cleartext_pso(self):
        """Checks that a PSO's cleartext setting can override the domain's"""

        # create a user that stores plain-text passwords
        self.add_user(clear_text=True)

        # check that clear-text is present in the supplementary-credentials
        self.assert_cleartext(expect_cleartext=True, password=USER_PASS)

        # create a PSO overriding the plain-text setting & apply it to the user
        no_plaintext_pso = PasswordSettings("no-plaintext-PSO", self.ldb,
                                            precedence=200,
                                            store_plaintext=False)
        self.addCleanup(self.ldb.delete, no_plaintext_pso.dn)
        userdn = "cn=" + USER_NAME + ",cn=users," + self.base_dn
        no_plaintext_pso.apply_to(userdn)

        # set the password to update the cleartext password stored
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)

        # this time cleartext shouldn't be in the supplementary creds
        self.assert_cleartext(expect_cleartext=False)

        # unapply PSO, update password, and check we get the cleartext again
        no_plaintext_pso.unapply(userdn)
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
        self.assert_cleartext(expect_cleartext=True, password=new_password)

        # Now update the domain setting and check we no longer get cleartext
        self.set_store_cleartext(False)
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
        self.assert_cleartext(expect_cleartext=False)

        # create a PSO overriding the domain setting & apply it to the user
        plaintext_pso = PasswordSettings("plaintext-PSO", self.ldb,
                                         precedence=100, store_plaintext=True)
        self.addCleanup(self.ldb.delete, plaintext_pso.dn)
        plaintext_pso.apply_to(userdn)
        new_password = samba.generate_random_password(32, 32)
        self.ldb.setpassword("(sAMAccountName=%s)" % USER_NAME, new_password)
        self.assert_cleartext(expect_cleartext=True, password=new_password)
Example #24
0
 def setUp(self):
     super(DirsyncBaseTests, self).setUp()
     self.ldb_admin = SamDB(ldapshost, credentials=creds, session_info=system_session(lp), lp=lp)
     self.base_dn = self.ldb_admin.domain_dn()
     self.domain_sid = security.dom_sid(self.ldb_admin.get_domain_sid())
     self.user_pass = samba.generate_random_password(12, 16)
     self.configuration_dn = self.ldb_admin.get_config_basedn().get_linearized()
     self.sd_utils = sd_utils.SDUtils(self.ldb_admin)
     #used for anonymous login
     print("baseDN: %s" % self.base_dn)
Example #25
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 #26
0
File: user.py Project: hef/samba
    def run(self, username, password=None, credopts=None, sambaopts=None,
            versionopts=None, H=None, must_change_at_next_login=False,
            random_password=False, use_username_as_cn=False, userou=None,
            surname=None, given_name=None, initials=None, profile_path=None,
            script_path=None, home_drive=None, home_directory=None,
            job_title=None, department=None, company=None, description=None,
            mail_address=None, internet_address=None, telephone_number=None,
            physical_delivery_office=None, rfc2307_from_nss=False,
            uid=None, uid_number=None, gid_number=None, gecos=None, login_shell=None):

        if random_password:
            password = generate_random_password(128, 255)

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

        if rfc2307_from_nss:
                pwent = pwd.getpwnam(username)
                if uid is None:
                    uid = username
                if uid_number is None:
                    uid_number = pwent[2]
                if gid_number is None:
                    gid_number = pwent[3]
                if gecos is None:
                    gecos = pwent[4]
                if login_shell is None:
                    login_shell = pwent[6]

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

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

        try:
            samdb = SamDB(url=H, session_info=system_session(),
                          credentials=creds, lp=lp)
            samdb.newuser(username, password, force_password_change_at_next_login_req=must_change_at_next_login,
                          useusernameascn=use_username_as_cn, userou=userou, surname=surname, givenname=given_name, initials=initials,
                          profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
                          jobtitle=job_title, department=department, company=company, description=description,
                          mailaddress=mail_address, internetaddress=internet_address,
                          telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office,
                          uid=uid, uidnumber=uid_number, gidnumber=gid_number, gecos=gecos, loginshell=login_shell)
        except Exception, e:
            raise CommandError("Failed to add user '%s': " % username, e)
Example #27
0
    def create_user_account(self, user_id):
        self.user_name = ("SAMR_USER_%d" % user_id)
        self.user_pass = generate_random_password(32, 32)
        self.user_dn = "cn=%s,cn=users,%s" % (self.user_name, self.samdb.domain_dn())

        samba.tests.delete_force(self.samdb, self.user_dn)

        self.samdb.newuser(self.user_name,
                           self.user_pass,
                           description="Password for " + self.user_name + " is " + self.user_pass,
                           givenname=self.user_name,
                           surname=self.user_name)
Example #28
0
    def join_ad_full_credentials(self, realm, realm_server, realm_admin, realm_passwd):
        if not self.configured:
            return None

        self.__populate_remote_domain(realm, realm_server, realm_admin, realm_passwd)
        if not self.remote_domain.read_only:
            trustdom_pass = samba.generate_random_password(128, 128)
            self.remote_domain.establish_trust(self.local_domain, trustdom_pass)
            self.local_domain.establish_trust(self.remote_domain, trustdom_pass)
            result = self.remote_domain.verify_trust(self.local_domain)
            return dict(local=self.local_domain, remote=self.remote_domain, verified=result)
        return None
Example #29
0
def join_subdomain(server=None,
                   creds=None,
                   lp=None,
                   site=None,
                   netbios_name=None,
                   targetdir=None,
                   parent_domain=None,
                   dnsdomain=None,
                   netbios_domain=None,
                   machinepass=None):
    """join as a DC"""
    ctx = dc_join(server, creds, lp, site, netbios_name, targetdir,
                  parent_domain, machinepass)
    ctx.subdomain = True
    ctx.parent_domain_name = ctx.domain_name
    ctx.domain_name = netbios_domain
    ctx.realm = dnsdomain
    ctx.parent_dnsdomain = ctx.dnsdomain
    ctx.parent_partition_dn = ctx.get_parent_partition_dn()
    ctx.dnsdomain = dnsdomain
    ctx.partition_dn = "CN=%s,CN=Partitions,%s" % (ctx.domain_name,
                                                   ctx.config_dn)
    ctx.naming_master = ctx.get_naming_master()
    if ctx.naming_master != ctx.server:
        print("Reconnecting to naming master %s" % ctx.naming_master)
        ctx.server = ctx.naming_master
        ctx.samdb = SamDB(url="ldap://%s" % ctx.server,
                          session_info=system_session(),
                          credentials=ctx.creds,
                          lp=ctx.lp)

    ctx.base_dn = samba.dn_from_dns_name(dnsdomain)
    ctx.domsid = str(security.random_sid())
    ctx.acct_dn = None
    ctx.dnshostname = "%s.%s" % (ctx.myname, ctx.dnsdomain)
    ctx.trustdom_pass = samba.generate_random_password(128, 128)

    ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION

    ctx.SPNs.append('E3514235-4B06-11D1-AB04-00C04FC2DCD2/$NTDSGUID/%s' %
                    ctx.dnsdomain)
    ctx.secure_channel_type = misc.SEC_CHAN_BDC

    ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP
                         | drsuapi.DRSUAPI_DRS_INIT_SYNC
                         | drsuapi.DRSUAPI_DRS_PER_SYNC
                         | drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS
                         | drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
    ctx.domain_replica_flags = ctx.replica_flags

    ctx.do_join()
    print "Created domain %s (SID %s) as a DC" % (ctx.domain_name, ctx.domsid)
Example #30
0
 def setUp(self):
     super(DirsyncBaseTests, self).setUp()
     self.ldb_admin = SamDB(ldapshost,
                            credentials=creds,
                            session_info=system_session(lp),
                            lp=lp)
     self.base_dn = self.ldb_admin.domain_dn()
     self.domain_sid = security.dom_sid(self.ldb_admin.get_domain_sid())
     self.user_pass = samba.generate_random_password(12, 16)
     self.configuration_dn = self.ldb_admin.get_config_basedn(
     ).get_linearized()
     self.sd_utils = sd_utils.SDUtils(self.ldb_admin)
     #used for anonymous login
     print("baseDN: %s" % self.base_dn)
Example #31
0
    def create_account(self, name, machine_account=False, spn=None, upn=None):
        '''Create an account for testing.
           The dn of the created account is added to self.accounts,
           which is used by tearDown to clean up the created accounts.
        '''
        dn = "cn=%s,%s" % (name, self.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(self.ldb, dn)
        if machine_account:
            object_class = "computer"
            account_name = "%s$" % name
            account_control = str(UF_WORKSTATION_TRUST_ACCOUNT)
        else:
            object_class = "user"
            account_name = name
            account_control = str(UF_NORMAL_ACCOUNT)

        password = generate_random_password(32, 32)
        utf16pw = ('"%s"' % password).encode('utf-16-le')

        details = {
            "dn": dn,
            "objectclass": object_class,
            "sAMAccountName": account_name,
            "userAccountControl": account_control,
            "unicodePwd": utf16pw
        }
        if spn is not None:
            details["servicePrincipalName"] = spn
        if upn is not None:
            details["userPrincipalName"] = upn
        self.ldb.add(details)

        creds = Credentials()
        creds.guess(self.lp)
        creds.set_realm(self.ldb.domain_dns_name().upper())
        creds.set_domain(self.ldb.domain_netbios_name().upper())
        creds.set_password(password)
        creds.set_username(account_name)
        if machine_account:
            creds.set_workstation(name)
        #
        # Save the account name so it can be deleted in the tearDown
        self.accounts.append(dn)

        return (creds, dn)
Example #32
0
def update_krbtgt_account_password(samdb, names):
    """Update (change) the password of the krbtgt account

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=krbtgt"
    res = samdb.search(expression=expression, attrs=[])
    assert len(res) == 1

    msg = ldb.Message(res[0].dn)
    machinepass = samba.generate_random_password(128, 255)
    mputf16 = machinepass.encode("utf-16-le")
    msg["clearTextPassword"] = ldb.MessageElement(mputf16, ldb.FLAG_MOD_REPLACE, "clearTextPassword")

    samdb.modify(msg)
Example #33
0
def update_krbtgt_account_password(samdb, names):
    """Update (change) the password of the krbtgt account

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=krbtgt"
    res = samdb.search(expression=expression, attrs=[])
    assert(len(res) == 1)

    msg = ldb.Message(res[0].dn)
    machinepass = samba.generate_random_password(128, 255)
    mputf16 = machinepass.encode('utf-16-le')
    msg["clearTextPassword"] = ldb.MessageElement(mputf16,
                                                  ldb.FLAG_MOD_REPLACE,
                                                  "clearTextPassword")

    samdb.modify(msg)
Example #34
0
    def join_ad_full_credentials(self, realm, realm_server, realm_admin,
                                 realm_passwd):
        if not self.configured:
            return None

        self.__populate_remote_domain(realm, realm_server, realm_admin,
                                      realm_passwd)
        if not self.remote_domain.read_only:
            trustdom_pass = samba.generate_random_password(128, 128)
            self.remote_domain.establish_trust(self.local_domain,
                                               trustdom_pass)
            self.local_domain.establish_trust(self.remote_domain,
                                              trustdom_pass)
            result = self.remote_domain.verify_trust(self.local_domain)
            return dict(local=self.local_domain,
                        remote=self.remote_domain,
                        verified=result)
        return None
Example #35
0
    def do_Netr_ServerPasswordSet2(self):
        c = self.get_netlogon_connection()
        (authenticator, subsequent) = self.get_authenticator(c)
        PWD_LEN = 32
        DATA_LEN = 512
        newpass = samba.generate_random_password(PWD_LEN, PWD_LEN)
        filler = [ord(x) for x in os.urandom(DATA_LEN - PWD_LEN)]
        pwd = netlogon.netr_CryptPassword()
        pwd.length = PWD_LEN
        pwd.data = filler + [ord(x) for x in newpass]
        self.machine_creds.encrypt_netr_crypt_password(pwd)
        c.netr_ServerPasswordSet2(self.server,
                                  self.machine_creds.get_workstation(),
                                  SEC_CHAN_WKSTA, self.machine_name,
                                  authenticator, pwd)

        self.machine_pass = newpass
        self.machine_creds.set_password(newpass)
Example #36
0
    def netlogon(self):
        server = os.environ["SERVER"]
        host = os.environ["SERVER_IP"]
        lp = self.get_loadparm()

        credentials = self.get_credentials()

        session = system_session()
        ldb = SamDB(url="ldap://%s" % host,
                    session_info=session,
                    credentials=credentials,
                    lp=lp)
        machine_pass = samba.generate_random_password(32, 32)
        machine_name = MACHINE_NAME
        machine_dn = "cn=%s,%s" % (machine_name, ldb.domain_dn())

        delete_force(ldb, machine_dn)

        utf16pw = ('"%s"' % get_string(machine_pass)).encode('utf-16-le')
        ldb.add({
            "dn":
            machine_dn,
            "objectclass":
            "computer",
            "sAMAccountName":
            "%s$" % machine_name,
            "userAccountControl":
            str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
            "unicodePwd":
            utf16pw
        })

        machine_creds = Credentials()
        machine_creds.guess(lp)
        machine_creds.set_secure_channel_type(SEC_CHAN_WKSTA)
        machine_creds.set_kerberos_state(DONT_USE_KERBEROS)
        machine_creds.set_password(machine_pass)
        machine_creds.set_username(machine_name + "$")
        machine_creds.set_workstation(machine_name)

        netlogon.netlogon("ncacn_ip_tcp:%s[schannel,seal]" % server, lp,
                          machine_creds)

        delete_force(ldb, machine_dn)
Example #37
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 #38
0
def update_machine_account_password(samdb, secrets_ldb, names):
    """Update (change) the password of the current DC both in the SAM db and in
       secret one

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param secrets_ldb: An LDB object related to the secrets.ldb file of a given
                        provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=%s$" % names.netbiosname
    secrets_msg = secrets_ldb.search(expression=expression,
                                     attrs=["secureChannelType"])
    if int(secrets_msg[0]["secureChannelType"][0]) == SEC_CHAN_BDC:
        res = samdb.search(expression=expression, attrs=[])
        assert (len(res) == 1)

        msg = ldb.Message(res[0].dn)
        machinepass = samba.generate_random_password(128, 255)
        mputf16 = machinepass.encode('utf-16-le')
        msg["clearTextPassword"] = ldb.MessageElement(mputf16,
                                                      ldb.FLAG_MOD_REPLACE,
                                                      "clearTextPassword")
        samdb.modify(msg)

        res = samdb.search(expression=("samAccountName=%s$" %
                                       names.netbiosname),
                           attrs=["msDs-keyVersionNumber"])
        assert (len(res) == 1)
        kvno = int(str(res[0]["msDs-keyVersionNumber"]))
        secChanType = int(secrets_msg[0]["secureChannelType"][0])

        secretsdb_self_join(secrets_ldb,
                            domain=names.domain,
                            realm=names.realm,
                            domainsid=names.domainsid,
                            dnsdomain=names.dnsdomain,
                            netbiosname=names.netbiosname,
                            machinepass=machinepass,
                            key_version_number=kvno,
                            secure_channel_type=secChanType)
    else:
        raise ProvisioningError("Unable to find a Secure Channel"
                                "of type SEC_CHAN_BDC")
Example #39
0
def join_subdomain(server=None, creds=None, lp=None, site=None,
        netbios_name=None, targetdir=None, parent_domain=None, dnsdomain=None,
        netbios_domain=None, machinepass=None, use_ntvfs=False,
        dns_backend=None):
    """Join as a DC."""
    ctx = dc_join(server, creds, lp, site, netbios_name, targetdir, parent_domain,
                  machinepass, use_ntvfs, dns_backend)
    ctx.subdomain = True
    ctx.parent_domain_name = ctx.domain_name
    ctx.domain_name = netbios_domain
    ctx.realm = dnsdomain
    ctx.parent_dnsdomain = ctx.dnsdomain
    ctx.parent_partition_dn = ctx.get_parent_partition_dn()
    ctx.dnsdomain = dnsdomain
    ctx.partition_dn = "CN=%s,CN=Partitions,%s" % (ctx.domain_name, ctx.config_dn)
    ctx.naming_master = ctx.get_naming_master()
    if ctx.naming_master != ctx.server:
        print("Reconnecting to naming master %s" % ctx.naming_master)
        ctx.server = ctx.naming_master
        ctx.samdb = SamDB(url="ldap://%s" % ctx.server,
                          session_info=system_session(),
                          credentials=ctx.creds, lp=ctx.lp)

    ctx.base_dn = samba.dn_from_dns_name(dnsdomain)
    ctx.domsid = str(security.random_sid())
    ctx.acct_dn = None
    ctx.dnshostname = "%s.%s" % (ctx.myname, ctx.dnsdomain)
    ctx.trustdom_pass = samba.generate_random_password(128, 128)

    ctx.userAccountControl = samba.dsdb.UF_SERVER_TRUST_ACCOUNT | samba.dsdb.UF_TRUSTED_FOR_DELEGATION

    ctx.SPNs.append('E3514235-4B06-11D1-AB04-00C04FC2DCD2/$NTDSGUID/%s' % ctx.dnsdomain)
    ctx.secure_channel_type = misc.SEC_CHAN_BDC

    ctx.replica_flags = (drsuapi.DRSUAPI_DRS_WRIT_REP |
                         drsuapi.DRSUAPI_DRS_INIT_SYNC |
                         drsuapi.DRSUAPI_DRS_PER_SYNC |
                         drsuapi.DRSUAPI_DRS_FULL_SYNC_IN_PROGRESS |
                         drsuapi.DRSUAPI_DRS_NEVER_SYNCED)
    ctx.domain_replica_flags = ctx.replica_flags

    ctx.do_join()
    print "Created domain %s (SID %s) as a DC" % (ctx.domain_name, ctx.domsid)
Example #40
0
    def test_ldap_change_password_bad_user(self):
        def isLastExpectedMessage(msg):
            return (msg["type"] == "Authorization" and
                    msg["Authorization"]["serviceDescription"]
                        == "LDAP" and
                    msg["Authorization"]["authType"] == "krb5")

        new_password = samba.generate_random_password(32,32)
        try:
            self.ldb.modify_ldif(
                "dn: cn=" + "badUser" + ",cn=users," + self.base_dn + "\n" +
                "changetype: modify\n" +
                "delete: userPassword\n" +
                "userPassword: "******"\n" +
                "add: userPassword\n" +
                "userPassword: "******"\n"
            )
            self.fail()
        except LdbError, (num, msg):
            pass
Example #41
0
    def test_ldap_change_password(self):
        def isLastExpectedMessage(msg):
            return ((msg["type"] == "Authentication")
                    and (msg["Authentication"]["status"] == "NT_STATUS_OK")
                    and (msg["Authentication"]["serviceDescription"]
                         == "LDAP Password Change") and
                    (msg["Authentication"]["authDescription"] == "LDAP Modify")
                    and (msg["Authentication"]["eventId"]
                         == EVT_ID_SUCCESSFUL_LOGON) and
                    (msg["Authentication"]["logonType"] == EVT_LOGON_NETWORK))

        new_password = samba.generate_random_password(32, 32)
        self.ldb.modify_ldif("dn: cn=" + USER_NAME + ",cn=users," +
                             self.base_dn + "\n" + "changetype: modify\n" +
                             "delete: userPassword\n" + "userPassword: "******"\n" + "add: userPassword\n" +
                             "userPassword: "******"\n")

        self.assertTrue(self.waitForMessages(isLastExpectedMessage),
                        "Did not receive the expected message")
Example #42
0
def set_admin_password(logger, samdb):
    """Sets a randomly generated password for the backup DB's admin user"""

    # match the admin user by RID
    domainsid = samdb.get_domain_sid()
    match_admin = "(objectsid=%s-%s)" % (domainsid,
                                         security.DOMAIN_RID_ADMINISTRATOR)
    search_expr = "(&(objectClass=user)%s)" % (match_admin,)

    # retrieve the admin username (just in case it's been renamed)
    res = samdb.search(base=samdb.domain_dn(), scope=ldb.SCOPE_SUBTREE,
                       expression=search_expr)
    username = str(res[0]['samaccountname'])

    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(search_expr, adminpass, force_change_at_next_login=False,
                      username=username)
Example #43
0
    def test_ldap_change_password_bad_user(self):
        def isLastExpectedMessage(msg):
            return (msg["type"] == "Authorization" and
                    msg["Authorization"]["serviceDescription"]
                        == "LDAP" and
                    msg["Authorization"]["authType"] == "krb5")

        new_password = samba.generate_random_password(32,32)
        try:
            self.ldb.modify_ldif(
                "dn: cn=" + "badUser" + ",cn=users," + self.base_dn + "\n" +
                "changetype: modify\n" +
                "delete: userPassword\n" +
                "userPassword: "******"\n" +
                "add: userPassword\n" +
                "userPassword: "******"\n"
            )
            self.fail()
        except LdbError, (num, msg):
            pass
Example #44
0
    def setUp(self):
        super(DsdbTests, self).setUp()
        self.lp = samba.tests.env_loadparm()
        self.creds = Credentials()
        self.creds.guess(self.lp)
        self.session = system_session()
        self.samdb = SamDB(session_info=self.session,
                           credentials=self.creds,
                           lp=self.lp)

        # Create a test user
        user_name = "dsdb-user-" + str(uuid.uuid4().hex[0:6])
        user_pass = samba.generate_random_password(32, 32)
        user_description = "Test user for dsdb test"

        base_dn = self.samdb.domain_dn()

        self.account_dn = "CN=" + user_name + ",CN=Users," + base_dn
        self.samdb.newuser(username=user_name,
                           password=user_pass,
                           description=user_description)
        # Cleanup (teardown)
        self.addCleanup(delete_force, self.samdb, self.account_dn)

        # Get server reference DN
        res = self.samdb.search(base=ldb.Dn(self.samdb,
                                            self.samdb.get_serverName()),
                                scope=ldb.SCOPE_BASE,
                                attrs=["serverReference"])
        # Get server reference
        self.server_ref_dn = ldb.Dn(
            self.samdb, res[0]["serverReference"][0].decode("utf-8"))

        # Get RID Set DN
        res = self.samdb.search(base=self.server_ref_dn,
                                scope=ldb.SCOPE_BASE,
                                attrs=["rIDSetReferences"])
        rid_set_refs = res[0]
        self.assertIn("rIDSetReferences", rid_set_refs)
        rid_set_str = rid_set_refs["rIDSetReferences"][0].decode("utf-8")
        self.rid_set_dn = ldb.Dn(self.samdb, rid_set_str)
Example #45
0
    def test_ldap_change_password(self):

        dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn
        self.discardSetupMessages(dn)

        new_password = samba.generate_random_password(32, 32)
        dn = "cn=" + USER_NAME + ",cn=users," + self.base_dn
        self.ldb.modify_ldif(
            "dn: " + dn + "\n" +
            "changetype: modify\n" +
            "delete: userPassword\n" +
            "userPassword: "******"\n" +
            "add: userPassword\n" +
            "userPassword: "******"\n")

        messages = self.waitForMessages(1)
        print("Received %d messages" % len(messages))
        self.assertEquals(1,
                          len(messages),
                          "Did not receive the expected number of messages")

        audit = messages[0]["dsdbChange"]
        self.assertEquals("Modify", audit["operation"])
        self.assertFalse(audit["performedAsSystem"])
        self.assertEquals(dn, audit["dn"])
        self.assertRegexpMatches(audit["remoteAddress"],
                                 self.remoteAddress)
        self.assertTrue(self.is_guid(audit["sessionId"]))
        session_id = self.get_session()
        self.assertEquals(session_id, audit["sessionId"])
        service_description = self.get_service_description()
        self.assertEquals(service_description, "LDAP")

        attributes = audit["attributes"]
        self.assertEquals(1, len(attributes))
        actions = attributes["userPassword"]["actions"]
        self.assertEquals(2, len(actions))
        self.assertTrue(actions[0]["redacted"])
        self.assertEquals("delete", actions[0]["action"])
        self.assertTrue(actions[1]["redacted"])
        self.assertEquals("add", actions[1]["action"])
Example #46
0
def update_dns_account_password(samdb, secrets_ldb, names):
    """Update (change) the password of the dns both in the SAM db and in
       secret one

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param secrets_ldb: An LDB object related to the secrets.ldb file of a given
                        provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=dns-%s" % names.netbiosname
    secrets_msg = secrets_ldb.search(expression=expression)
    if len(secrets_msg) == 1:
        res = samdb.search(expression=expression, attrs=[])
        assert(len(res) == 1)

        msg = ldb.Message(res[0].dn)
        machinepass = samba.generate_random_password(128, 255)
        mputf16 = machinepass.encode('utf-16-le')
        msg["clearTextPassword"] = ldb.MessageElement(mputf16,
                                                ldb.FLAG_MOD_REPLACE,
                                                "clearTextPassword")

        samdb.modify(msg)

        res = samdb.search(expression=expression,
                     attrs=["msDs-keyVersionNumber"])
        assert(len(res) == 1)
        kvno = str(res[0]["msDs-keyVersionNumber"])

        msg = ldb.Message(secrets_msg[0].dn)
        msg["secret"] = ldb.MessageElement(machinepass,
                                                ldb.FLAG_MOD_REPLACE,
                                                "secret")
        msg["msDS-KeyVersionNumber"] = ldb.MessageElement(kvno,
                                                ldb.FLAG_MOD_REPLACE,
                                                "msDS-KeyVersionNumber")

        secrets_ldb.modify(msg)
    else:
        raise ProvisioningError("Unable to find an object"
                                " with %s" % expression )
Example #47
0
def update_machine_account_password(samdb, secrets_ldb, names):
    """Update (change) the password of the current DC both in the SAM db and in
       secret one

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param secrets_ldb: An LDB object related to the secrets.ldb file of a given
                        provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=%s$" % names.netbiosname
    secrets_msg = secrets_ldb.search(expression=expression,
                                        attrs=["secureChannelType"])
    if int(secrets_msg[0]["secureChannelType"][0]) == SEC_CHAN_BDC:
        res = samdb.search(expression=expression, attrs=[])
        assert(len(res) == 1)

        msg = ldb.Message(res[0].dn)
        machinepass = samba.generate_random_password(128, 255)
        mputf16 = machinepass.encode('utf-16-le')
        msg["clearTextPassword"] = ldb.MessageElement(mputf16,
                                                ldb.FLAG_MOD_REPLACE,
                                                "clearTextPassword")
        samdb.modify(msg)

        res = samdb.search(expression=("samAccountName=%s$" % names.netbiosname),
                     attrs=["msDs-keyVersionNumber"])
        assert(len(res) == 1)
        kvno = int(str(res[0]["msDs-keyVersionNumber"]))
        secChanType = int(secrets_msg[0]["secureChannelType"][0])

        secretsdb_self_join(secrets_ldb, domain=names.domain,
                    realm=names.realm,
                    domainsid=names.domainsid,
                    dnsdomain=names.dnsdomain,
                    netbiosname=names.netbiosname,
                    machinepass=machinepass,
                    key_version_number=kvno,
                    secure_channel_type=secChanType)
    else:
        raise ProvisioningError("Unable to find a Secure Channel"
                                "of type SEC_CHAN_BDC")
Example #48
0
    def create(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']
        print(username)
        userou = "OU=" + request['userou']
        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)

        try:
            con.newuser(username,
                        password,
                        force_password_change_at_next_login_req=
                        must_change_at_next_login,
                        userou=userou,
                        surname=request['surname'],
                        givenname=request['name'],
                        company=request['company'],
                        telephonenumber=request['telephone'],
                        description=request['description'],
                        mailaddress=request['mail_address'])
        except Exception as e:
            return ResponseStatus(
                status.HTTP_409_CONFLICT,
                'Failed to create user "%s": %s' % (request['username'], e),
                None)

        return ResponseStatus(status.HTTP_201_CREATED, request['username'],
                              None)
Example #49
0
    def do_Netr_ServerPasswordSet2(self):
        c = self.get_netlogon_connection()
        (authenticator, subsequent) = self.get_authenticator(c)
        PWD_LEN  = 32
        DATA_LEN = 512
        newpass = samba.generate_random_password(PWD_LEN, PWD_LEN)
        encoded = newpass.encode('utf-16-le')
        pwd_len = len(encoded)
        filler  = [ord(x) for x in os.urandom(DATA_LEN-pwd_len)]
        pwd = netlogon.netr_CryptPassword()
        pwd.length = pwd_len
        pwd.data = filler + [ord(x) for x in encoded]
        self.machine_creds.encrypt_netr_crypt_password(pwd)
        c.netr_ServerPasswordSet2(self.server,
                                  self.machine_creds.get_workstation(),
                                  SEC_CHAN_WKSTA,
                                  self.machine_name,
                                  authenticator,
                                  pwd)

        self.machine_pass = newpass
        self.machine_creds.set_password(newpass)
Example #50
0
    def setUp(self):
        super(DsdbTests, self).setUp()
        self.lp = samba.tests.env_loadparm()
        self.creds = Credentials()
        self.creds.guess(self.lp)
        self.session = system_session()
        self.samdb = SamDB(session_info=self.session,
                           credentials=self.creds,
                           lp=self.lp)

        # Create a test user
        user_name = "samdb-testuser"
        user_pass = samba.generate_random_password(32, 32)
        user_description = "Test user for dsdb test"

        base_dn = self.samdb.domain_dn()

        self.account_dn = "cn=" + user_name + ",cn=Users," + base_dn
        delete_force(self.samdb, self.account_dn)
        self.samdb.newuser(username=user_name,
                           password=user_pass,
                           description=user_description)
Example #51
0
    def test_ldap_change_password_bad_original_password(self):
        def isLastExpectedMessage(msg):
            return (msg["type"] == "Authentication" and
                    msg["Authentication"]["status"]
                        == "NT_STATUS_WRONG_PASSWORD" and
                    msg["Authentication"]["serviceDescription"]
                        == "LDAP Password Change" and
                    msg["Authentication"]["authDescription"]
                        == "LDAP Modify")

        new_password = samba.generate_random_password(32,32)
        try:
            self.ldb.modify_ldif(
                "dn: cn=" + USER_NAME + ",cn=users," + self.base_dn + "\n" +
                "changetype: modify\n" +
                "delete: userPassword\n" +
                "userPassword: "******"badPassword" + "\n" +
                "add: userPassword\n" +
                "userPassword: "******"\n"
            )
            self.fail()
        except LdbError, (num, msg):
            pass
Example #52
0
    def setUp(self):
        super(DsdbTests, self).setUp()
        self.lp = samba.tests.env_loadparm()
        self.creds = Credentials()
        self.creds.guess(self.lp)
        self.session = system_session()
        self.samdb = SamDB(session_info=self.session,
                           credentials=self.creds,
                           lp=self.lp)

        # Create a test user
        user_name = "dsdb-user-" + str(uuid.uuid4().hex[0:6])
        user_pass = samba.generate_random_password(32, 32)
        user_description = "Test user for dsdb test"

        base_dn = self.samdb.domain_dn()

        self.account_dn = "cn=" + user_name + ",cn=Users," + base_dn
        self.samdb.newuser(username=user_name,
                           password=user_pass,
                           description=user_description)
        # Cleanup (teardown)
        self.addCleanup(delete_force, self.samdb, self.account_dn)
Example #53
0
    def create_machine_account(self):
        self.machine_pass = samba.generate_random_password(32, 32)
        self.machine_name = MACHINE_NAME
        self.machine_dn = "cn=%s,%s" % (self.machine_name, self.ldb.domain_dn())

        # remove the account if it exists, this will happen if a previous test
        # run failed
        delete_force(self.ldb, self.machine_dn)
        # get unicode str for both py2 and py3
        pass_unicode = self.machine_pass.encode('utf-8').decode('utf-8')
        utf16pw = u'"{}"'.format(pass_unicode).encode('utf-16-le')
        self.ldb.add({
            "dn": self.machine_dn,
            "objectclass": "computer",
            "sAMAccountName": "%s$" % self.machine_name,
            "userAccountControl":
                str(UF_WORKSTATION_TRUST_ACCOUNT | UF_PASSWD_NOTREQD),
            "unicodePwd": utf16pw})

        self.machine_creds = Credentials()
        self.machine_creds.guess(self.get_loadparm())
        self.machine_creds.set_password(self.machine_pass)
        self.machine_creds.set_username(self.machine_name + "$")
        self.machine_creds.set_workstation(self.machine_name)
Example #54
0
    def run(self, username, password=None, credopts=None, sambaopts=None,
            versionopts=None, H=None, must_change_at_next_login=False,
            random_password=False, use_username_as_cn=False, userou=None,
            surname=None, given_name=None, initials=None, profile_path=None,
            script_path=None, home_drive=None, home_directory=None,
            job_title=None, department=None, company=None, description=None,
            mail_address=None, internet_address=None, telephone_number=None,
            physical_delivery_office=None, rfc2307_from_nss=False,
            nis_domain=None, unix_home=None, uid=None, uid_number=None,
            gid_number=None, gecos=None, login_shell=None,
            smartcard_required=False):

        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 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 rfc2307_from_nss:
                pwent = pwd.getpwnam(username)
                if uid is None:
                    uid = username
                if uid_number is None:
                    uid_number = pwent[2]
                if gid_number is None:
                    gid_number = pwent[3]
                if gecos is None:
                    gecos = pwent[4]
                if login_shell is None:
                    login_shell = pwent[6]

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

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

        if nis_domain is not None:
            if None in (uid_number, login_shell, unix_home, gid_number):
                raise CommandError('Missing parameters. To enable NIS features, '
                                   'the following options have to be given: '
                                   '--nis-domain=, --uidNumber=, --login-shell='
                                   ', --unix-home=, --gid-number= Operation '
                                   'cancelled.')

        try:
            samdb = SamDB(url=H, session_info=system_session(),
                          credentials=creds, lp=lp)
            samdb.newuser(username, password, force_password_change_at_next_login_req=must_change_at_next_login,
                          useusernameascn=use_username_as_cn, userou=userou, surname=surname, givenname=given_name, initials=initials,
                          profilepath=profile_path, homedrive=home_drive, scriptpath=script_path, homedirectory=home_directory,
                          jobtitle=job_title, department=department, company=company, description=description,
                          mailaddress=mail_address, internetaddress=internet_address,
                          telephonenumber=telephone_number, physicaldeliveryoffice=physical_delivery_office,
                          nisdomain=nis_domain, unixhome=unix_home, uid=uid,
                          uidnumber=uid_number, gidnumber=gid_number,
                          gecos=gecos, loginshell=login_shell,
                          smartcard_required=smartcard_required)
        except Exception, e:
            raise CommandError("Failed to add user '%s': " % username, e)
Example #55
0
    def AddUser(self):
        try:
            if not self._check_session():
                return json.dumps(self.AuthErr);


            username = request.params.get("username","")
            password = request.params.get("password",samba.generate_random_password(7,15))
            fullname = request.params.get("fullname","")
            description = request.params.get("description","")
            iscopy = request.params.get("iscopy","false")

            changepassword = request.params.get("changepassword","false");
            if(changepassword!="false"):
                changepassword = True
            else:
                changepassword = False

            cannotchangepassword = request.params.get("cannotchangepassword","false");
            if(cannotchangepassword!="false"):
                cannotchangepassword = True
            else:
                cannotchangepassword = False

            passwordexpires = request.params.get("passwordexpires","false");
            if(passwordexpires!="false"):
                passwordexpires = True
            else:
                passwordexpires = False

            disable = request.params.get("disable","false");
            if(disable!="false"):
                disable = True
            else:
                disable = False

            rid = self.model.AddUser(username);

            if rid == False:
                raise Exception(self.model.LastErrorNumber,self.model.LastErrorStr)

            if(iscopy!="false"):
                self.iscopy=True;
                self.rid=rid;
                self.UpdateUser();
            else:
                user = User(username,fullname,description,rid);

                user.must_change_password = changepassword;
                user.cannot_change_password = cannotchangepassword;
                user.password_never_expires = passwordexpires;
                user.account_disabled = disable;

                if not self.model.UpdateUser(user):
                    raise Exception(self.model.LastErrorNumber,self.model.LastErrorStr)

                if(not self.model.SetPassword(username,password)):
                    raise Exception(self.model.LastErrorNumber,self.model.LastErrorStr)


        except Exception,e:
            if(len(e.args)>1):
                return json.dumps({'success': False, 'msg': e.args[1],'num':e.args[0]})
            else:
                return json.dumps({'success': False, 'msg': e.args,'num':-1})
Example #56
0
def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, useeadb=False, dns_backend=None, use_ntvfs=False):
    """Upgrade from samba3 database to samba4 AD database

    :param samba3: samba3 object
    :param logger: Logger object
    :param targetdir: samba4 database directory
    :param session_info: Session information
    """
    serverrole = samba3.lp.server_role()

    domainname = samba3.lp.get("workgroup")
    realm = samba3.lp.get("realm")
    netbiosname = samba3.lp.get("netbios name")

    if samba3.lp.get("ldapsam:trusted") is None:
        samba3.lp.set("ldapsam:trusted", "yes")

    # secrets db
    try:
        secrets_db = samba3.get_secrets_db()
    except IOError as e:
        raise ProvisioningError(
            "Could not open '%s', the Samba3 secrets database: %s.  Perhaps you specified the incorrect smb.conf, --testparm or --dbdir option?"
            % (samba3.privatedir_path("secrets.tdb"), str(e))
        )

    if not domainname:
        domainname = secrets_db.domains()[0]
        logger.warning("No workgroup specified in smb.conf file, assuming '%s'", domainname)

    if not realm:
        if serverrole == "ROLE_DOMAIN_BDC" or serverrole == "ROLE_DOMAIN_PDC":
            raise ProvisioningError(
                "No realm specified in smb.conf file and being a DC. That upgrade path doesn't work! Please add a 'realm' directive to your old smb.conf to let us know which one you want to use (it is the DNS name of the AD domain you wish to create."
            )
        else:
            realm = domainname.upper()
            logger.warning("No realm specified in smb.conf file, assuming '%s'", realm)

    # Find machine account and password
    next_rid = 1000

    try:
        machinepass = secrets_db.get_machine_password(netbiosname)
    except KeyError:
        machinepass = None

    if samba3.lp.get("passdb backend").split(":")[0].strip() == "ldapsam":
        base_dn = samba3.lp.get("ldap suffix")
        ldapuser = samba3.lp.get("ldap admin dn")
        ldappass = secrets_db.get_ldap_bind_pw(ldapuser)
        if ldappass is None:
            raise ProvisioningError(
                "ldapsam passdb backend detected but no LDAP Bind PW found in secrets.tdb for user %s.  Please point this tool at the secrets.tdb that was used by the previous installation."
            )
        ldappass = ldappass.strip("\x00")
        ldap = True
    else:
        ldapuser = None
        ldappass = None
        ldap = False

    # We must close the direct pytdb database before the C code loads it
    secrets_db.close()

    # Connect to old password backend
    passdb.set_secrets_dir(samba3.lp.get("private dir"))
    s3db = samba3.get_sam_db()

    # Get domain sid
    try:
        domainsid = passdb.get_global_sam_sid()
    except passdb.error:
        raise Exception("Can't find domain sid for '%s', Exiting." % domainname)

    # Get machine account, sid, rid
    try:
        machineacct = s3db.getsampwnam("%s$" % netbiosname)
    except passdb.error:
        machinerid = None
        machinesid = None
    else:
        machinesid, machinerid = machineacct.user_sid.split()

    # Export account policy
    logger.info("Exporting account policy")
    policy = s3db.get_account_policy()

    # Export groups from old passdb backend
    logger.info("Exporting groups")
    grouplist = s3db.enum_group_mapping()
    groupmembers = {}
    for group in grouplist:
        sid, rid = group.sid.split()
        if sid == domainsid:
            if rid >= next_rid:
                next_rid = rid + 1

        # Get members for each group/alias
        if group.sid_name_use == lsa.SID_NAME_ALIAS:
            try:
                members = s3db.enum_aliasmem(group.sid)
                groupmembers[str(group.sid)] = members
            except passdb.error as e:
                logger.warn("Ignoring group '%s' %s listed but then not found: %s", group.nt_name, group.sid, e)
                continue
        elif group.sid_name_use == lsa.SID_NAME_DOM_GRP:
            try:
                members = s3db.enum_group_members(group.sid)
                groupmembers[str(group.sid)] = members
            except passdb.error as e:
                logger.warn("Ignoring group '%s' %s listed but then not found: %s", group.nt_name, group.sid, e)
                continue
        elif group.sid_name_use == lsa.SID_NAME_WKN_GRP:
            (group_dom_sid, rid) = group.sid.split()
            if group_dom_sid != security.dom_sid(security.SID_BUILTIN):
                logger.warn(
                    "Ignoring 'well known' group '%s' (should already be in AD, and have no members)", group.nt_name
                )
                continue
            # A number of buggy databases mix up well known groups and aliases.
            try:
                members = s3db.enum_aliasmem(group.sid)
                groupmembers[str(group.sid)] = members
            except passdb.error as e:
                logger.warn("Ignoring group '%s' %s listed but then not found: %s", group.nt_name, group.sid, e)
                continue
        else:
            logger.warn("Ignoring group '%s' %s with sid_name_use=%d", group.nt_name, group.sid, group.sid_name_use)
            continue

    # Export users from old passdb backend
    logger.info("Exporting users")
    userlist = s3db.search_users(0)
    userdata = {}
    uids = {}
    admin_user = None
    for entry in userlist:
        if machinerid and machinerid == entry["rid"]:
            continue
        username = entry["account_name"]
        if entry["rid"] < 1000:
            logger.info("  Skipping wellknown rid=%d (for username=%s)", entry["rid"], username)
            continue
        if entry["rid"] >= next_rid:
            next_rid = entry["rid"] + 1

        user = s3db.getsampwnam(username)
        acct_type = user.acct_ctrl & (samr.ACB_NORMAL | samr.ACB_WSTRUST | samr.ACB_SVRTRUST | samr.ACB_DOMTRUST)
        if acct_type == samr.ACB_SVRTRUST:
            logger.warn(
                "  Demoting BDC account trust for %s, this DC must be elevated to an AD DC using 'samba-tool domain dcpromo'"
                % username[:-1]
            )
            user.acct_ctrl = (user.acct_ctrl & ~samr.ACB_SVRTRUST) | samr.ACB_WSTRUST

        elif acct_type == samr.ACB_DOMTRUST:
            logger.warn(
                "  Skipping inter-domain trust from domain %s, this trust must be re-created as an AD trust"
                % username[:-1]
            )
            continue

        elif acct_type == (samr.ACB_WSTRUST) and username[-1] != "$":
            logger.warn(
                "  Skipping account %s that has ACB_WSTRUST (W) set but does not end in $.  This account can not have worked, and is probably left over from a misconfiguration."
                % username
            )
            continue

        elif acct_type == (samr.ACB_NORMAL | samr.ACB_WSTRUST) and username[-1] == "$":
            logger.warn(
                "  Fixing account %s which had both ACB_NORMAL (U) and ACB_WSTRUST (W) set.  Account will be marked as ACB_WSTRUST (W), i.e. as a domain member"
                % username
            )
            user.acct_ctrl = user.acct_ctrl & ~samr.ACB_NORMAL

        elif acct_type == (samr.ACB_NORMAL | samr.ACB_SVRTRUST) and username[-1] == "$":
            logger.warn(
                "  Fixing account %s which had both ACB_NORMAL (U) and ACB_SVRTRUST (S) set.  Account will be marked as ACB_WSTRUST (S), i.e. as a domain member"
                % username
            )
            user.acct_ctrl = user.acct_ctrl & ~samr.ACB_NORMAL

        elif acct_type == 0 and username[-1] != "$":
            user.acct_ctrl = user.acct_ctrl | samr.ACB_NORMAL

        elif acct_type == samr.ACB_NORMAL or acct_type == samr.ACB_WSTRUST:
            pass

        else:
            raise ProvisioningError(
                """Failed to upgrade due to invalid account %s, account control flags 0x%08X must have exactly one of
ACB_NORMAL (N, 0x%08X), ACB_WSTRUST (W 0x%08X), ACB_SVRTRUST (S 0x%08X) or ACB_DOMTRUST (D 0x%08X).

Please fix this account before attempting to upgrade again
"""
                % (username, user.acct_ctrl, samr.ACB_NORMAL, samr.ACB_WSTRUST, samr.ACB_SVRTRUST, samr.ACB_DOMTRUST)
            )

        userdata[username] = user
        try:
            uids[username] = s3db.sid_to_id(user.user_sid)[0]
        except passdb.error:
            try:
                uids[username] = pwd.getpwnam(username).pw_uid
            except KeyError:
                pass

        if not admin_user and username.lower() == "root":
            admin_user = username
        if username.lower() == "administrator":
            admin_user = username

        try:
            group_memberships = s3db.enum_group_memberships(user)
            for group in group_memberships:
                if str(group) in groupmembers:
                    if user.user_sid not in groupmembers[str(group)]:
                        groupmembers[str(group)].append(user.user_sid)
                else:
                    groupmembers[str(group)] = [user.user_sid]
        except passdb.error as e:
            logger.warn("Ignoring group memberships of '%s' %s: %s", username, user.user_sid, e)

    logger.info("Next rid = %d", next_rid)

    # Check for same username/groupname
    group_names = set([g.nt_name for g in grouplist])
    user_names = set([u["account_name"] for u in userlist])
    common_names = group_names.intersection(user_names)
    if common_names:
        logger.error("Following names are both user names and group names:")
        for name in common_names:
            logger.error("   %s" % name)
        raise ProvisioningError("Please remove common user/group names before upgrade.")

    # Check for same user sid/group sid
    group_sids = set([str(g.sid) for g in grouplist])
    if len(grouplist) != len(group_sids):
        raise ProvisioningError("Please remove duplicate group sid entries before upgrade.")
    user_sids = set(["%s-%u" % (domainsid, u["rid"]) for u in userlist])
    if len(userlist) != len(user_sids):
        raise ProvisioningError("Please remove duplicate user sid entries before upgrade.")
    common_sids = group_sids.intersection(user_sids)
    if common_sids:
        logger.error("Following sids are both user and group sids:")
        for sid in common_sids:
            logger.error("   %s" % str(sid))
        raise ProvisioningError("Please remove duplicate sid entries before upgrade.")

    # Get posix attributes from ldap or the os
    homes = {}
    shells = {}
    pgids = {}
    if ldap:
        creds = Credentials()
        creds.guess(samba3.lp)
        creds.set_bind_dn(ldapuser)
        creds.set_password(ldappass)
        urls = samba3.lp.get("passdb backend").split(":", 1)[1].strip('"')
        for url in urls.split():
            try:
                ldb_object = Ldb(url, credentials=creds)
            except ldb.LdbError as e:
                raise ProvisioningError("Could not open ldb connection to %s, the error message is: %s" % (url, e))
            else:
                break
    logger.info("Exporting posix attributes")
    userlist = s3db.search_users(0)
    for entry in userlist:
        username = entry["account_name"]
        if username in uids.keys():
            try:
                if ldap:
                    homes[username] = get_posix_attr_from_ldap_backend(
                        logger, ldb_object, base_dn, username, "homeDirectory"
                    )
                else:
                    homes[username] = pwd.getpwnam(username).pw_dir
            except KeyError:
                pass
            except IndexError:
                pass

            try:
                if ldap:
                    shells[username] = get_posix_attr_from_ldap_backend(
                        logger, ldb_object, base_dn, username, "loginShell"
                    )
                else:
                    shells[username] = pwd.getpwnam(username).pw_shell
            except KeyError:
                pass
            except IndexError:
                pass

            try:
                if ldap:
                    pgids[username] = get_posix_attr_from_ldap_backend(
                        logger, ldb_object, base_dn, username, "gidNumber"
                    )
                else:
                    pgids[username] = pwd.getpwnam(username).pw_gid
            except KeyError:
                pass
            except IndexError:
                pass

    logger.info("Reading WINS database")
    samba3_winsdb = None
    try:
        samba3_winsdb = samba3.get_wins_db()
    except IOError as e:
        logger.warn("Cannot open wins database, Ignoring: %s", str(e))

    if not (serverrole == "ROLE_DOMAIN_BDC" or serverrole == "ROLE_DOMAIN_PDC"):
        dns_backend = "NONE"

    # If we found an admin user, set a fake pw that we will override.
    # This avoids us printing out an admin password that we won't actually
    # set.
    if admin_user:
        adminpass = generate_random_password(12, 32)
    else:
        adminpass = None

    # Do full provision
    result = provision(
        logger,
        session_info,
        targetdir=targetdir,
        realm=realm,
        domain=domainname,
        domainsid=domainsid,
        next_rid=next_rid,
        dc_rid=machinerid,
        adminpass=adminpass,
        dom_for_fun_level=dsdb.DS_DOMAIN_FUNCTION_2003,
        hostname=netbiosname.lower(),
        machinepass=machinepass,
        serverrole=serverrole,
        samdb_fill=FILL_FULL,
        useeadb=useeadb,
        dns_backend=dns_backend,
        use_rfc2307=True,
        use_ntvfs=use_ntvfs,
        skip_sysvolacl=True,
    )
    result.report_logger(logger)

    # Import WINS database
    logger.info("Importing WINS database")

    if samba3_winsdb:
        import_wins(Ldb(result.paths.winsdb), samba3_winsdb)

    # Set Account policy
    logger.info("Importing Account policy")
    import_sam_policy(result.samdb, policy, logger)

    # Migrate IDMAP database
    logger.info("Importing idmap database")
    import_idmap(result.idmap, samba3, logger)

    # Set the s3 context for samba4 configuration
    new_lp_ctx = s3param.get_context()
    new_lp_ctx.load(result.lp.configfile)
    new_lp_ctx.set("private dir", result.lp.get("private dir"))
    new_lp_ctx.set("state directory", result.lp.get("state directory"))
    new_lp_ctx.set("lock directory", result.lp.get("lock directory"))

    # Connect to samba4 backend
    s4_passdb = passdb.PDB(new_lp_ctx.get("passdb backend"))

    # Start a new transaction (should speed this up a little, due to index churn)
    result.samdb.transaction_start()

    logger.info("Adding groups")
    try:
        # Export groups to samba4 backend
        logger.info("Importing groups")
        for g in grouplist:
            # Ignore uninitialized groups (gid = -1)
            if g.gid != -1:
                add_group_from_mapping_entry(result.samdb, g, logger)
                add_ad_posix_idmap_entry(result.samdb, g.sid, g.gid, "ID_TYPE_GID", logger)
                add_posix_attrs(
                    samdb=result.samdb,
                    sid=g.sid,
                    name=g.nt_name,
                    nisdomain=domainname.lower(),
                    xid_type="ID_TYPE_GID",
                    logger=logger,
                )

    except:
        # We need this, so that we do not give even more errors due to not cancelling the transaction
        result.samdb.transaction_cancel()
        raise

    logger.info("Committing 'add groups' transaction to disk")
    result.samdb.transaction_commit()

    logger.info("Adding users")
    # Start a new transaction (should speed this up a little, due to index churn)
    result.samdb.transaction_start()

    try:
        # Export users to samba4 backend
        logger.info("Importing users")
        for username in userdata:
            if username.lower() == "administrator":
                if userdata[username].user_sid != dom_sid(str(domainsid) + "-500"):
                    logger.error(
                        "User 'Administrator' in your existing directory has SID %s, expected it to be %s"
                        % (userdata[username].user_sid, dom_sid(str(domainsid) + "-500"))
                    )
                    raise ProvisioningError(
                        "User 'Administrator' in your existing directory does not have SID ending in -500"
                    )
            if username.lower() == "root":
                if userdata[username].user_sid == dom_sid(str(domainsid) + "-500"):
                    logger.warn("User root has been replaced by Administrator")
                else:
                    logger.warn(
                        "User root has been kept in the directory, it should be removed in favour of the Administrator user"
                    )

            s4_passdb.add_sam_account(userdata[username])
            if username in uids:
                add_ad_posix_idmap_entry(
                    result.samdb, userdata[username].user_sid, uids[username], "ID_TYPE_UID", logger
                )
                if (
                    (username in homes)
                    and (homes[username] is not None)
                    and (username in shells)
                    and (shells[username] is not None)
                    and (username in pgids)
                    and (pgids[username] is not None)
                ):
                    add_posix_attrs(
                        samdb=result.samdb,
                        sid=userdata[username].user_sid,
                        name=username,
                        nisdomain=domainname.lower(),
                        xid_type="ID_TYPE_UID",
                        home=homes[username],
                        shell=shells[username],
                        pgid=pgids[username],
                        logger=logger,
                    )

    except:
        # We need this, so that we do not give even more errors due to not cancelling the transaction
        result.samdb.transaction_cancel()
        raise

    logger.info("Committing 'add users' transaction to disk")
    result.samdb.transaction_commit()

    logger.info("Adding users to groups")
    # Start a new transaction (should speed this up a little, due to index churn)
    result.samdb.transaction_start()

    try:
        for g in grouplist:
            if str(g.sid) in groupmembers:
                add_users_to_group(result.samdb, g, groupmembers[str(g.sid)], logger)

    except:
        # We need this, so that we do not give even more errors due to not cancelling the transaction
        result.samdb.transaction_cancel()
        raise

    logger.info("Committing 'add users to groups' transaction to disk")
    result.samdb.transaction_commit()

    # Set password for administrator
    if admin_user:
        logger.info("Setting password for administrator")
        admin_userdata = s4_passdb.getsampwnam("administrator")
        admin_userdata.nt_passwd = userdata[admin_user].nt_passwd
        if userdata[admin_user].lanman_passwd:
            admin_userdata.lanman_passwd = userdata[admin_user].lanman_passwd
        admin_userdata.pass_last_set_time = userdata[admin_user].pass_last_set_time
        if userdata[admin_user].pw_history:
            admin_userdata.pw_history = userdata[admin_user].pw_history
        s4_passdb.update_sam_account(admin_userdata)
        logger.info("Administrator password has been set to password of user '%s'", admin_user)

    if result.server_role == "active directory domain controller":
        setsysvolacl(
            result.samdb,
            result.paths.netlogon,
            result.paths.sysvol,
            result.paths.root_uid,
            result.paths.root_gid,
            security.dom_sid(result.domainsid),
            result.names.dnsdomain,
            result.names.domaindn,
            result.lp,
            use_ntvfs,
        )
Example #57
0
File: upgrade.py Project: hef/samba
    logger.info("Reading WINS database")
    samba3_winsdb = None
    try:
        samba3_winsdb = samba3.get_wins_db()
    except IOError, e:
        logger.warn('Cannot open wins database, Ignoring: %s', str(e))

    if not (serverrole == "ROLE_DOMAIN_BDC" or serverrole == "ROLE_DOMAIN_PDC"):
        dns_backend = "NONE"

    # If we found an admin user, set a fake pw that we will override.
    # This avoids us printing out an admin password that we won't actually
    # set.
    if admin_user:
        adminpass = generate_random_password(12, 32)
    else:
        adminpass = None

    # Do full provision
    result = provision(logger, session_info,
                       targetdir=targetdir, realm=realm, domain=domainname,
                       domainsid=str(domainsid), next_rid=next_rid,
                       dc_rid=machinerid, adminpass = adminpass,
                       dom_for_fun_level=dsdb.DS_DOMAIN_FUNCTION_2003,
                       hostname=netbiosname.lower(), machinepass=machinepass,
                       serverrole=serverrole, samdb_fill=FILL_FULL,
                       useeadb=useeadb, dns_backend=dns_backend, use_rfc2307=True,
                       use_ntvfs=use_ntvfs, skip_sysvolacl=True)
    result.report_logger(logger)
Example #58
0
from samba.auth import system_session
from samba.tests import TestCase
from samba.ndr import ndr_unpack
from samba.dcerpc import drsblobs
from samba.dcerpc.samr import DOMAIN_PASSWORD_STORE_CLEARTEXT
from samba.dsdb import UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED
from samba.tests import delete_force
import ldb
import os
import samba
import binascii
import md5


USER_NAME = "PasswordHashTestUser"
USER_PASS = samba.generate_random_password(32,32)
UPN       = "*****@*****.**"

# Get named package from the passed supplemental credentials
#
# returns the package and it's position within the supplemental credentials
def get_package(sc, name):
    if sc is None:
        return None

    idx = 0
    for p in sc.sub.packages:
        idx += 1
        if name == p.name:
            return (idx, p)
Example #59
0
    def __init__(ctx, server=None, creds=None, lp=None, site=None,
            netbios_name=None, targetdir=None, domain=None):
        ctx.creds = creds
        ctx.lp = lp
        ctx.site = site
        ctx.netbios_name = netbios_name
        ctx.targetdir = targetdir

        ctx.creds.set_gensec_features(creds.get_gensec_features() | gensec.FEATURE_SEAL)
        ctx.net = Net(creds=ctx.creds, lp=ctx.lp)

        if server is not None:
            ctx.server = server
        else:
            print("Finding a writeable DC for domain '%s'" % domain)
            ctx.server = ctx.find_dc(domain)
            print("Found DC %s" % ctx.server)

        ctx.samdb = SamDB(url="ldap://%s" % ctx.server,
                          session_info=system_session(),
                          credentials=ctx.creds, lp=ctx.lp)

        ctx.myname = netbios_name
        ctx.samname = "%s$" % ctx.myname
        ctx.base_dn = str(ctx.samdb.get_default_basedn())
        ctx.root_dn = str(ctx.samdb.get_root_basedn())
        ctx.schema_dn = str(ctx.samdb.get_schema_basedn())
        ctx.config_dn = str(ctx.samdb.get_config_basedn())
        ctx.domsid = ctx.samdb.get_domain_sid()
        ctx.domain_name = ctx.get_domain_name()

        lp.set("workgroup", ctx.domain_name)
        print("workgroup is %s" % ctx.domain_name)

        ctx.dc_ntds_dn = ctx.get_dsServiceName()
        ctx.dc_dnsHostName = ctx.get_dnsHostName()
        ctx.behavior_version = ctx.get_behavior_version()

        ctx.acct_pass = samba.generate_random_password(32, 40)

        # work out the DNs of all the objects we will be adding
        ctx.server_dn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (ctx.myname, ctx.site, ctx.config_dn)
        ctx.ntds_dn = "CN=NTDS Settings,%s" % ctx.server_dn
        topology_base = "CN=Topology,CN=Domain System Volume,CN=DFSR-GlobalSettings,CN=System,%s" % ctx.base_dn
        if ctx.dn_exists(topology_base):
            ctx.topology_dn = "CN=%s,%s" % (ctx.myname, topology_base)
        else:
            ctx.topology_dn = None

        ctx.dnsdomain = ldb.Dn(ctx.samdb, ctx.base_dn).canonical_str().split('/')[0]

        ctx.realm = ctx.dnsdomain
        lp.set("realm", ctx.realm)

        print("realm is %s" % ctx.realm)

        ctx.dnshostname = "%s.%s" % (ctx.myname.lower(), ctx.dnsdomain)

        ctx.acct_dn = "CN=%s,OU=Domain Controllers,%s" % (ctx.myname, ctx.base_dn)

        ctx.tmp_samdb = None

        ctx.SPNs = [ "HOST/%s" % ctx.myname,
                     "HOST/%s" % ctx.dnshostname,
                     "GC/%s/%s" % (ctx.dnshostname, ctx.dnsdomain) ]

        # these elements are optional
        ctx.never_reveal_sid = None
        ctx.reveal_sid = None
        ctx.connection_dn = None
        ctx.RODC = False
        ctx.krbtgt_dn = None
        ctx.drsuapi = None
        ctx.managedby = None