diff options
| author | Nadezhda Ivanova <nadezhda.ivanova@postpath.com> | 2009-09-21 14:26:15 -0700 | 
|---|---|---|
| committer | Nadezhda Ivanova <nadezhda.ivanova@postpath.com> | 2009-09-21 14:26:15 -0700 | 
| commit | 13b979b03d86f3ae43dc5fd539fa5d3f22f579a0 (patch) | |
| tree | 40e15be25f6b975e7c5b91f00fdf6030726e25e7 /source4/scripting/python | |
| parent | 025590e7a4758e86e7942642971b92fc6bab7a8e (diff) | |
| parent | 1afc7c453c1d5f7e761e46cdc69900305a149820 (diff) | |
| download | samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.tar.gz samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.tar.bz2 samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.zip  | |
Merge branch 'master' of git://git.samba.org/samba
Diffstat (limited to 'source4/scripting/python')
| -rw-r--r-- | source4/scripting/python/samba/provision.py | 117 | ||||
| -rw-r--r-- | source4/scripting/python/samba/samdb.py | 4 | 
2 files changed, 92 insertions, 29 deletions
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 25cec4b143..2d3e04eac1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -44,7 +44,7 @@ from credentials import Credentials, DONT_USE_KERBEROS  from auth import system_session, admin_session  from samba import version, Ldb, substitute_var, valid_netbios_name  from samba import check_all_substituted -from samba import DS_DOMAIN_FUNCTION_2000, DS_DC_FUNCTION_2008_R2 +from samba import DS_DOMAIN_FUNCTION_2000, DS_DOMAIN_FUNCTION_2008, DS_DC_FUNCTION_2008, DS_DC_FUNCTION_2008_R2  from samba.samdb import SamDB  from samba.idmap import IDmapDB  from samba.dcerpc import security @@ -54,14 +54,10 @@ from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, timestring  from ms_schema import read_ms_schema  from ms_display_specifiers import read_ms_ldif  from signal import SIGTERM +from dcerpc.misc import SEC_CHAN_BDC, SEC_CHAN_WKSTA  __docformat__ = "restructuredText" - -class ProvisioningError(ValueError): -  pass - -  def find_setup_dir():      """Find the setup directory used by provision."""      dirname = os.path.dirname(__file__) @@ -113,6 +109,11 @@ def get_config_descriptor(domain_sid):  DEFAULTSITE = "Default-First-Site-Name" +# Exception classes + +class ProvisioningError(Exception): +    """A generic provision error.""" +  class InvalidNetbiosName(Exception):      """A specified name was not a valid NetBIOS name."""      def __init__(self, name): @@ -355,7 +356,6 @@ def provision_paths_from_lp(lp, dnsdomain):      """      paths = ProvisionPaths()      paths.private_dir = lp.get("private dir") -    paths.keytab = "secrets.keytab"      paths.dns_keytab = "dns.keytab"      paths.shareconf = os.path.join(paths.private_dir, "share.ldb") @@ -695,26 +695,83 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,      samdb.transaction_commit() +def secretsdb_self_join(secretsdb, domain,  +                        netbiosname, domainsid, machinepass,  +                        realm=None, dnsdomain=None, +                        keytab_path=None,  +                        key_version_number=1, +                        secure_channel_type=SEC_CHAN_WKSTA): +    """Add domain join-specific bits to a secrets database. +     +    :param secretsdb: Ldb Handle to the secrets database +    :param machinepass: Machine password +    """ +    attrs=["whenChanged", +           "secret", +           "priorSecret", +           "priorChanged", +           "krb5Keytab", +           "privateKeytab"] +     + +    msg = ldb.Message(ldb.Dn(secretsdb, "flatname=%s,cn=Primary Domains" % domain)); +    msg["secureChannelType"] = str(secure_channel_type) +    msg["flatname"] = [domain] +    msg["objectClass"] = ["top", "primaryDomain"] +    if realm is not None: +      if dnsdomain is None: +        dnsdomain = realm.lower() +      msg["objectClass"] = ["top", "primaryDomain", "kerberosSecret"] +      msg["realm"] = realm +      msg["saltPrincipal"] = "host/%s.%s@%s" % (netbiosname.lower(), dnsdomain.lower(), realm.upper()) +      msg["msDS-KeyVersionNumber"] = [str(key_version_number)] +      msg["privateKeytab"] = ["secrets.keytab"]; + + +    msg["secret"] = [machinepass] +    msg["samAccountName"] = ["%s$" % netbiosname] +    msg["secureChannelType"] = [str(secure_channel_type)] +    msg["objectSid"] = [ndr_pack(domainsid)] +     +    res = secretsdb.search(base="cn=Primary Domains",  +                           attrs=attrs,  +                           expression=("(&(|(flatname=%s)(realm=%s)(objectSid=%s))(objectclass=primaryDomain))" % (domain, realm, str(domainsid))),  +                           scope=SCOPE_ONELEVEL) +     +    for del_msg in res: +      if del_msg.dn is not msg.dn: +        secretsdb.delete(del_msg.dn) + +    res = secretsdb.search(base=msg.dn, attrs=attrs, scope=SCOPE_BASE) +    if len(res) == 1: +      msg["priorSecret"] = res[0]["secret"] +      msg["priorWhenChanged"] = res[0]["whenChanged"] -def secretsdb_become_dc(secretsdb, setup_path, domain, realm, dnsdomain,  -                        netbiosname, domainsid, keytab_path, samdb_url,  -                        dns_keytab_path, dnspass, machinepass): -    """Add DC-specific bits to a secrets database. +      if res["privateKeytab"] is not None: +        msg["privateKeytab"] = res[0]["privateKeytab"] + +      if res["krb5Keytab"] is not None: +        msg["krb5Keytab"] = res[0]["krb5Keytab"] + +      for el in msg: +        el.set_flags(ldb.FLAG_MOD_REPLACE) +        secretsdb.modify(msg) +    else: +      secretsdb.add(msg) + + +def secretsdb_setup_dns(secretsdb, setup_path, realm, dnsdomain,  +                        dns_keytab_path, dnspass): +    """Add DNS specific bits to a secrets database.      :param secretsdb: Ldb Handle to the secrets database      :param setup_path: Setup path function      :param machinepass: Machine password      """ -    setup_ldb(secretsdb, setup_path("secrets_dc.ldif"), {  -            "MACHINEPASS_B64": b64encode(machinepass), -            "DOMAIN": domain, +    setup_ldb(secretsdb, setup_path("secrets_dns.ldif"), {               "REALM": realm,              "DNSDOMAIN": dnsdomain, -            "DOMAINSID": str(domainsid), -            "SECRETS_KEYTAB": keytab_path, -            "NETBIOSNAME": netbiosname, -            "SAM_LDB": samdb_url,              "DNS_KEYTAB": dns_keytab_path,              "DNSPASS_B64": b64encode(dnspass),              }) @@ -738,6 +795,7 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp):      secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif"))      secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials,                        lp=lp) +    secrets_ldb.transaction_start()      secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif"))      if credentials is not None and credentials.authentication_requested(): @@ -873,9 +931,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,      :note: This will wipe the main SAM database file!      """ -    domainFunctionality = DS_DOMAIN_FUNCTION_2000 -    forestFunctionality = DS_DOMAIN_FUNCTION_2000 -    domainControllerFunctionality = DS_DC_FUNCTION_2008_R2 +    # Do NOT change these default values without discussion with the team and reslease manager.   +    domainFunctionality = DS_DOMAIN_FUNCTION_2008 +    forestFunctionality = DS_DOMAIN_FUNCTION_2008 +    domainControllerFunctionality = DS_DC_FUNCTION_2008      # Also wipes the database      setup_samdb_partitions(path, setup_path, message=message, lp=lp, @@ -1275,16 +1334,18 @@ def provision(setup_dir, message, session_info,          # Only make a zone file on the first DC, it should be replicated with DNS replication          if serverrole == "domain controller": -            secrets_ldb = Ldb(paths.secrets, session_info=session_info,  -                              credentials=credentials, lp=lp) -            secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, +            secretsdb_self_join(secrets_ldb, domain=domain,                                  realm=names.realm, +                                dnsdomain=names.dnsdomain,                                  netbiosname=names.netbiosname,                                  domainsid=domainsid,  -                                keytab_path=paths.keytab, samdb_url=paths.samdb, +                                machinepass=machinepass, +                                secure_channel_type=SEC_CHAN_BDC) + +            secretsdb_setup_dns(secrets_ldb, setup_path,  +                                realm=names.realm, dnsdomain=names.dnsdomain,                                  dns_keytab_path=paths.dns_keytab, -                                dnspass=dnspass, machinepass=machinepass, -                                dnsdomain=names.dnsdomain) +                                dnspass=dnspass)              domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID")              assert isinstance(domainguid, str) @@ -1309,6 +1370,8 @@ def provision(setup_dir, message, session_info,                               realm=names.realm)              message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf) +    #Now commit the secrets.ldb to disk +    secrets_ldb.transaction_commit()      if provision_backend is not None:         if ldap_backend_type == "fedora-ds": diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 239dd6a6ea..39cf1d6c40 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -202,8 +202,8 @@ userPassword:: %s          self.transaction_start()          try:              res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE, -                              expression=filter, -                              attrs=["userAccountControl", "accountExpires"]) +                          expression=filter, +                          attrs=["userAccountControl", "accountExpires"])              assert(len(res) == 1)              user_dn = res[0].dn  | 
