1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

s4-python: Simplify code, improve formatting.

This commit is contained in:
Jelmer Vernooij 2010-04-08 18:57:09 +02:00
parent be4b688175
commit d7a46ee129
8 changed files with 205 additions and 232 deletions

View File

@ -40,8 +40,7 @@ from ldb import SCOPE_SUBTREE, SCOPE_BASE, \
MessageElement, Message, Dn MessageElement, Message, Dn
from samba import param from samba import param
from samba.misc import messageEltFlagToString from samba.misc import messageEltFlagToString
from samba.provision import find_setup_dir, get_domain_descriptor, get_config_descriptor, secretsdb_self_join,set_gpo_acl,getpolicypath,create_gpo_struct from samba.provision import find_setup_dir, get_domain_descriptor, get_config_descriptor, secretsdb_self_join,set_gpo_acl,getpolicypath,create_gpo_struct, ProvisioningError
from samba.provisionexceptions import ProvisioningError
from samba.schema import get_linked_attributes, Schema, get_schema_descriptor from samba.schema import get_linked_attributes, Schema, get_schema_descriptor
from samba.dcerpc import security from samba.dcerpc import security
from samba.ndr import ndr_unpack from samba.ndr import ndr_unpack
@ -321,16 +320,22 @@ def handle_special_case(att, delta, new, old, ischema):
def update_secrets(newpaths, paths, creds, session): def update_secrets(newpaths, paths, creds, session):
"""Update secrets.ldb """Update secrets.ldb
:param newpaths: a list of paths for different provision objects from the reference provision :param newpaths: a list of paths for different provision objects from the
:param paths: a list of paths for different provision objects from the upgraded provision reference provision
:param paths: a list of paths for different provision objects from the
upgraded provision
:param creds: credential for the authentification :param creds: credential for the authentification
:param session: session for connexion""" :param session: session for connexion"""
message(SIMPLE,"update secrets.ldb") message(SIMPLE,"update secrets.ldb")
newsecrets_ldb = Ldb(newpaths.secrets, session_info=session, credentials=creds,lp=lp) newsecrets_ldb = Ldb(newpaths.secrets, session_info=session,
secrets_ldb = Ldb(paths.secrets, session_info=session, credentials=creds,lp=lp, options=["modules:samba_secrets"]) credentials=creds,lp=lp)
reference = newsecrets_ldb.search(expression="dn=@MODULES",base="", scope=SCOPE_SUBTREE) secrets_ldb = Ldb(paths.secrets, session_info=session,
current = secrets_ldb.search(expression="dn=@MODULES",base="", scope=SCOPE_SUBTREE) credentials=creds,lp=lp, options=["modules:samba_secrets"])
reference = newsecrets_ldb.search(expression="dn=@MODULES",base="",
scope=SCOPE_SUBTREE)
current = secrets_ldb.search(expression="dn=@MODULES",base="",
scope=SCOPE_SUBTREE)
delta = secrets_ldb.msg_diff(current[0],reference[0]) delta = secrets_ldb.msg_diff(current[0],reference[0])
delta.dn = current[0].dn delta.dn = current[0].dn
secrets_ldb.modify(delta) secrets_ldb.modify(delta)
@ -449,7 +454,8 @@ def handle_special_add(sam_ldb,dn,names):
message(CHANGE,"Existing object %s must be replaced by %s, removing old object"%(dntoremove,str(dn))) message(CHANGE,"Existing object %s must be replaced by %s, removing old object"%(dntoremove,str(dn)))
sam_ldb.delete(res[0]["dn"]) sam_ldb.delete(res[0]["dn"])
def check_dn_nottobecreated(hash,index,listdn):
def check_dn_nottobecreated(hash, index, listdn):
"""Check if one of the DN present in the list has a creation order greater than the current. """Check if one of the DN present in the list has a creation order greater than the current.
Hash is indexed by dn to be created, with each key is associated the creation order Hash is indexed by dn to be created, with each key is associated the creation order
@ -780,22 +786,22 @@ def update_basesamdb(newpaths, paths, names):
shutil.copy(newpaths.samdb,paths.samdb) shutil.copy(newpaths.samdb,paths.samdb)
message(SIMPLE,"Update partitions filename if needed") message(SIMPLE,"Update partitions filename if needed")
schemaldb=os.path.join(paths.private_dir,"schema.ldb") schemaldb = os.path.join(paths.private_dir, "schema.ldb")
configldb=os.path.join(paths.private_dir,"configuration.ldb") configldb = os.path.join(paths.private_dir, "configuration.ldb")
usersldb=os.path.join(paths.private_dir,"users.ldb") usersldb = os.path.join(paths.private_dir, "users.ldb")
samldbdir=os.path.join(paths.private_dir,"sam.ldb.d") samldbdir = os.path.join(paths.private_dir, "sam.ldb.d")
if not os.path.isdir(samldbdir): if not os.path.isdir(samldbdir):
os.mkdir(samldbdir) os.mkdir(samldbdir)
os.chmod(samldbdir,0700) os.chmod(samldbdir,0700)
if os.path.isfile(schemaldb): if os.path.isfile(schemaldb):
shutil.copy(schemaldb, os.path.join(samldbdir, "%s.ldb"%str(names.schemadn).upper())) shutil.copy(schemaldb, os.path.join(samldbdir, "%s.ldb" % str(names.schemadn).upper()))
os.remove(schemaldb) os.remove(schemaldb)
if os.path.isfile(usersldb): if os.path.isfile(usersldb):
shutil.copy(usersldb, os.path.join(samldbdir, "%s.ldb"%str(names.rootdn).upper())) shutil.copy(usersldb, os.path.join(samldbdir, "%s.ldb" % str(names.rootdn).upper()))
os.remove(usersldb) os.remove(usersldb)
if os.path.isfile(configldb): if os.path.isfile(configldb):
shutil.copy(configldb, os.path.join(samldbdir, "%s.ldb"%str(names.configdn).upper())) shutil.copy(configldb, os.path.join(samldbdir, "%s.ldb" % str(names.configdn).upper()))
os.remove(configldb) os.remove(configldb)
@ -834,7 +840,8 @@ def update_machine_account_password(paths, creds, session, names):
:param session: Session for connexion :param session: Session for connexion
:param names: List of key provision parameters""" :param names: List of key provision parameters"""
secrets_ldb = Ldb(paths.secrets, session_info=session, credentials=creds,lp=lp) secrets_ldb = Ldb(paths.secrets, session_info=session,
credentials=creds,lp=lp)
secrets_ldb.transaction_start() secrets_ldb.transaction_start()
secrets_msg = secrets_ldb.search(expression=("samAccountName=%s$" % names.netbiosname), attrs=["secureChannelType"]) secrets_msg = secrets_ldb.search(expression=("samAccountName=%s$" % names.netbiosname), attrs=["secureChannelType"])
sam_ldb = Ldb(paths.samdb, session_info=session, credentials=creds,lp=lp) sam_ldb = Ldb(paths.samdb, session_info=session, credentials=creds,lp=lp)
@ -885,6 +892,7 @@ def update_gpo(paths,creds,session,names):
set_gpo_acl(paths.sysvol, names.dnsdomain, names.domainsid, set_gpo_acl(paths.sysvol, names.dnsdomain, names.domainsid,
names.domaindn, samdb, lp) names.domaindn, samdb, lp)
def updateOEMInfo(paths, creds, session,names): def updateOEMInfo(paths, creds, session,names):
sam_ldb = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp, sam_ldb = Ldb(paths.samdb, session_info=session, credentials=creds, lp=lp,
options=["modules:samba_dsdb"]) options=["modules:samba_dsdb"])

View File

@ -114,7 +114,7 @@ class cmd_domainlevel(Command):
raise CommandError("Could not retrieve the actual domain, forest level and/or lowest DC function level!") raise CommandError("Could not retrieve the actual domain, forest level and/or lowest DC function level!")
if subcommand == "show": if subcommand == "show":
self.message("Domain and forest function level for domain '" + domain_dn + "'") self.message("Domain and forest function level for domain '%s'" % domain_dn)
if level_forest < DS_DOMAIN_FUNCTION_2003: if level_forest < DS_DOMAIN_FUNCTION_2003:
self.message("\nATTENTION: You run SAMBA 4 on a forest function level lower than Windows 2003 (Native). This isn't supported! Please raise!") self.message("\nATTENTION: You run SAMBA 4 on a forest function level lower than Windows 2003 (Native). This isn't supported! Please raise!")
if level_domain < DS_DOMAIN_FUNCTION_2003: if level_domain < DS_DOMAIN_FUNCTION_2003:

View File

@ -57,7 +57,8 @@ class cmd_ds_acl_set(Command):
} }
takes_options = [ takes_options = [
Option("--host", help="LDB URL for database or target server", type=str), Option("--host", help="LDB URL for database or target server",
type=str),
Option("--car", type="choice", choices=["change-rid", Option("--car", type="choice", choices=["change-rid",
"change-pdc", "change-pdc",
"change-infrastructure", "change-infrastructure",
@ -74,12 +75,15 @@ class cmd_ds_acl_set(Command):
help=car_help), help=car_help),
Option("--action", type="choice", choices=["allow", "deny"], Option("--action", type="choice", choices=["allow", "deny"],
help="""Deny or allow access"""), help="""Deny or allow access"""),
Option("--objectdn", help="DN of the object whose SD to modify", type="string"), Option("--objectdn", help="DN of the object whose SD to modify",
Option("--trusteedn", help="DN of the entity that gets access", type="string"), type="string"),
Option("--trusteedn", help="DN of the entity that gets access",
type="string"),
] ]
def find_trustee_sid(self, samdb, trusteedn): def find_trustee_sid(self, samdb, trusteedn):
res = samdb.search(base=trusteedn, expression="(objectClass=*)", scope=SCOPE_BASE) res = samdb.search(base=trusteedn, expression="(objectClass=*)",
scope=SCOPE_BASE)
assert(len(res) == 1) assert(len(res) == 1)
return ndr_unpack( security.dom_sid,res[0]["objectSid"][0]) return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
@ -93,18 +97,20 @@ class cmd_ds_acl_set(Command):
samdb.modify(m) samdb.modify(m)
def read_descriptor(self, samdb, object_dn): def read_descriptor(self, samdb, object_dn):
res = samdb.search(base=object_dn, scope=SCOPE_BASE, attrs=["nTSecurityDescriptor"]) res = samdb.search(base=object_dn, scope=SCOPE_BASE,
attrs=["nTSecurityDescriptor"])
# we should theoretically always have an SD # we should theoretically always have an SD
assert(len(res) == 1) assert(len(res) == 1)
desc = res[0]["nTSecurityDescriptor"][0] desc = res[0]["nTSecurityDescriptor"][0]
return ndr_unpack(security.descriptor, desc) return ndr_unpack(security.descriptor, desc)
def get_domain_sid(self, samdb): def get_domain_sid(self, samdb):
res = samdb.search(base=SamDB.domain_dn(samdb), expression="(objectClass=*)", scope=SCOPE_BASE) res = samdb.search(base=SamDB.domain_dn(samdb),
expression="(objectClass=*)", scope=SCOPE_BASE)
return ndr_unpack( security.dom_sid,res[0]["objectSid"][0]) return ndr_unpack( security.dom_sid,res[0]["objectSid"][0])
#add new ace explicitly
def add_ace(self, samdb, object_dn, new_ace): def add_ace(self, samdb, object_dn, new_ace):
"""Add new ace explicitly."""
desc = self.read_descriptor(samdb, object_dn) desc = self.read_descriptor(samdb, object_dn)
desc_sddl = desc.as_sddl(self.get_domain_sid(samdb)) desc_sddl = desc.as_sddl(self.get_domain_sid(samdb))
#TODO add bindings for descriptor manipulation and get rid of this #TODO add bindings for descriptor manipulation and get rid of this
@ -164,6 +170,7 @@ class cmd_ds_acl_set(Command):
self.add_ace(samdb, objectdn, new_ace) self.add_ace(samdb, objectdn, new_ace)
self.print_new_acl(samdb, objectdn) self.print_new_acl(samdb, objectdn)
class cmd_ds_acl(SuperCommand): class cmd_ds_acl(SuperCommand):
"""DS ACLs manipulation""" """DS ACLs manipulation"""

View File

@ -2,7 +2,7 @@
# Unix SMB/CIFS implementation. # Unix SMB/CIFS implementation.
# backend code for provisioning a Samba4 server # backend code for provisioning a Samba4 server
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2010
# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008-2009 # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008-2009
# Copyright (C) Oliver Liebel <oliver@itc.li> 2008-2009 # Copyright (C) Oliver Liebel <oliver@itc.li> 2008-2009
# #
@ -53,7 +53,6 @@ from samba.schema import Schema
from samba.samdb import SamDB from samba.samdb import SamDB
from ms_display_specifiers import read_ms_ldif from ms_display_specifiers import read_ms_ldif
from samba.provisionbackend import LDBBackend, ExistingBackend, FDSBackend, OpenLDAPBackend from samba.provisionbackend import LDBBackend, ExistingBackend, FDSBackend, OpenLDAPBackend
from provisionexceptions import ProvisioningError, InvalidNetbiosName
__docformat__ = "restructuredText" __docformat__ = "restructuredText"
@ -150,9 +149,8 @@ def get_domain_descriptor(domain_sid):
DEFAULTSITE = "Default-First-Site-Name" DEFAULTSITE = "Default-First-Site-Name"
# Exception classes
class ProvisionPaths(object): class ProvisionPaths(object):
def __init__(self): def __init__(self):
self.shareconf = None self.shareconf = None
self.hklm = None self.hklm = None
@ -172,6 +170,7 @@ class ProvisionPaths(object):
class ProvisionNames(object): class ProvisionNames(object):
def __init__(self): def __init__(self):
self.rootdn = None self.rootdn = None
self.domaindn = None self.domaindn = None
@ -188,12 +187,14 @@ class ProvisionNames(object):
class ProvisionResult(object): class ProvisionResult(object):
def __init__(self): def __init__(self):
self.paths = None self.paths = None
self.domaindn = None self.domaindn = None
self.lp = None self.lp = None
self.samdb = None self.samdb = None
def check_install(lp, session_info, credentials): def check_install(lp, session_info, credentials):
"""Check whether the current install seems ok. """Check whether the current install seems ok.
@ -203,9 +204,9 @@ def check_install(lp, session_info, credentials):
""" """
if lp.get("realm") == "": if lp.get("realm") == "":
raise Exception("Realm empty") raise Exception("Realm empty")
ldb = Ldb(lp.get("sam database"), session_info=session_info, samdb = Ldb(lp.get("sam database"), session_info=session_info,
credentials=credentials, lp=lp) credentials=credentials, lp=lp)
if len(ldb.search("(cn=Administrator)")) != 1: if len(samdb.search("(cn=Administrator)")) != 1:
raise ProvisioningError("No administrator account found") raise ProvisioningError("No administrator account found")
@ -825,6 +826,7 @@ def create_gpo_struct(policy_path):
os.makedirs(os.path.join(policy_path, "MACHINE"), 0755) os.makedirs(os.path.join(policy_path, "MACHINE"), 0755)
os.makedirs(os.path.join(policy_path, "USER"), 0755) os.makedirs(os.path.join(policy_path, "USER"), 0755)
def setup_gpo(sysvolpath, dnsdomain, policyguid, policyguid_dc): def setup_gpo(sysvolpath, dnsdomain, policyguid, policyguid_dc):
policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid) policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid)
create_gpo_struct(policy_path) create_gpo_struct(policy_path)
@ -832,6 +834,7 @@ def setup_gpo(sysvolpath, dnsdomain, policyguid, policyguid_dc):
policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid_dc) policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid_dc)
create_gpo_struct(policy_path) create_gpo_struct(policy_path)
def setup_samdb(path, setup_path, session_info, provision_backend, lp, def setup_samdb(path, setup_path, session_info, provision_backend, lp,
names, message, names, message,
domainsid, domainguid, policyguid, policyguid_dc, domainsid, domainguid, policyguid, policyguid_dc,
@ -851,7 +854,8 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
if dom_for_fun_level is None: if dom_for_fun_level is None:
dom_for_fun_level = DS_DOMAIN_FUNCTION_2003 dom_for_fun_level = DS_DOMAIN_FUNCTION_2003
if dom_for_fun_level < DS_DOMAIN_FUNCTION_2003: if dom_for_fun_level < DS_DOMAIN_FUNCTION_2003:
message("You want to run SAMBA 4 on a domain and forest function level lower than Windows 2003 (Native). This is not recommended") message("You want to run SAMBA 4 on a domain and forest function level"
" lower than Windows 2003 (Native). This is not recommended")
if dom_for_fun_level > domainControllerFunctionality: if dom_for_fun_level > domainControllerFunctionality:
raise ProvisioningError("You want to run SAMBA 4 on a domain and forest function level which itself is higher than its actual DC function level (2008). This won't work!") raise ProvisioningError("You want to run SAMBA 4 on a domain and forest function level which itself is higher than its actual DC function level (2008). This won't work!")
@ -864,7 +868,7 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
provision_backend=provision_backend, session_info=session_info, provision_backend=provision_backend, session_info=session_info,
names=names, serverrole=serverrole, schema=schema) names=names, serverrole=serverrole, schema=schema)
if (schema == None): if schema is None:
schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn) schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn)
# Load the database, but importantly, use Ldb not SamDB as we don't want to # Load the database, but importantly, use Ldb not SamDB as we don't want to
@ -1033,7 +1037,6 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,
names.ntdsguid = samdb.searchone(basedn=ntds_dn, names.ntdsguid = samdb.searchone(basedn=ntds_dn,
attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE) attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE)
assert isinstance(names.ntdsguid, str) assert isinstance(names.ntdsguid, str)
except: except:
samdb.transaction_cancel() samdb.transaction_cancel()
raise raise
@ -1066,9 +1069,11 @@ def set_gpo_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp):
attrs=["cn","nTSecurityDescriptor"], attrs=["cn","nTSecurityDescriptor"],
expression="", scope=ldb.SCOPE_ONELEVEL) expression="", scope=ldb.SCOPE_ONELEVEL)
for policy in res: for policy in res:
acl = ndr_unpack(security.descriptor,str(policy["nTSecurityDescriptor"])).as_sddl() acl = ndr_unpack(security.descriptor,
str(policy["nTSecurityDescriptor"])).as_sddl()
policy_path = getpolicypath(sysvol,dnsdomain,str(policy["cn"])) policy_path = getpolicypath(sysvol,dnsdomain,str(policy["cn"]))
set_dir_acl(policy_path,dsacl2fsacl(acl,str(domainsid)),lp,str(domainsid)) set_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp,
str(domainsid))
def setsysvolacl(samdb, netlogon, sysvol, gid, domainsid, dnsdomain, domaindn, def setsysvolacl(samdb, netlogon, sysvol, gid, domainsid, dnsdomain, domaindn,
lp): lp):
@ -1177,8 +1182,8 @@ def provision(setup_dir, message, session_info,
data = open(smbconf, 'r').read() data = open(smbconf, 'r').read()
data = data.lstrip() data = data.lstrip()
if data is None or data == "": if data is None or data == "":
make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, make_smbconf(smbconf, setup_path, hostname, domain, realm,
targetdir, sid_generator, useeadb) serverrole, targetdir, sid_generator, useeadb)
else: else:
make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,
targetdir, sid_generator, useeadb) targetdir, sid_generator, useeadb)
@ -1229,7 +1234,8 @@ def provision(setup_dir, message, session_info,
ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="")
schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn) schema = Schema(setup_path, domainsid, schemadn=names.schemadn,
serverdn=names.serverdn)
if backend_type == "ldb": if backend_type == "ldb":
provision_backend = LDBBackend(backend_type, provision_backend = LDBBackend(backend_type,
@ -1275,7 +1281,7 @@ def provision(setup_dir, message, session_info,
ol_mmr_urls=ol_mmr_urls, ol_mmr_urls=ol_mmr_urls,
nosync=nosync) nosync=nosync)
else: else:
raise ProvisioningError("Unknown LDAP backend type selected") raise ValueError("Unknown LDAP backend type selected")
provision_backend.init() provision_backend.init()
provision_backend.start() provision_backend.start()
@ -1290,8 +1296,8 @@ def provision(setup_dir, message, session_info,
message("Setting up secrets.ldb") message("Setting up secrets.ldb")
secrets_ldb = setup_secretsdb(paths.secrets, setup_path, secrets_ldb = setup_secretsdb(paths.secrets, setup_path,
session_info=session_info, session_info=session_info,
backend_credentials=provision_backend.secrets_credentials, lp=lp) backend_credentials=provision_backend.secrets_credentials, lp=lp)
message("Setting up the registry") message("Setting up the registry")
setup_registry(paths.hklm, setup_path, session_info, setup_registry(paths.hklm, setup_path, session_info,
@ -1322,15 +1328,15 @@ def provision(setup_dir, message, session_info,
if paths.netlogon is None: if paths.netlogon is None:
message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.") message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.")
message("Please either remove %s or see the template at %s" % message("Please either remove %s or see the template at %s" %
( paths.smbconf, setup_path("provision.smb.conf.dc"))) (paths.smbconf, setup_path("provision.smb.conf.dc")))
assert(paths.netlogon is not None) assert paths.netlogon is not None
if paths.sysvol is None: if paths.sysvol is None:
message("Existing smb.conf does not have a [sysvol] share, but you are configuring a DC.") message("Existing smb.conf does not have a [sysvol] share, but you"
" are configuring a DC.")
message("Please either remove %s or see the template at %s" % message("Please either remove %s or see the template at %s" %
(paths.smbconf, setup_path("provision.smb.conf.dc"))) (paths.smbconf, setup_path("provision.smb.conf.dc")))
assert(paths.sysvol is not None) assert paths.sysvol is not None
if not os.path.isdir(paths.netlogon): if not os.path.isdir(paths.netlogon):
os.makedirs(paths.netlogon, 0755) os.makedirs(paths.netlogon, 0755)
@ -1342,8 +1348,9 @@ def provision(setup_dir, message, session_info,
if serverrole == "domain controller": if serverrole == "domain controller":
# Set up group policies (domain policy and domain controller policy) # Set up group policies (domain policy and domain controller policy)
setup_gpo(paths.sysvol,names.dnsdomain,policyguid,policyguid_dc) setup_gpo(paths.sysvol, names.dnsdomain, policyguid, policyguid_dc)
setsysvolacl(samdb,paths.netlogon,paths.sysvol,wheel_gid,domainsid,names.dnsdomain,names.domaindn,lp) setsysvolacl(samdb, paths.netlogon, paths.sysvol, wheel_gid,
domainsid, names.dnsdomain, names.domaindn, lp)
message("Setting up sam.ldb rootDSE marking as synchronized") message("Setting up sam.ldb rootDSE marking as synchronized")
setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
@ -1368,11 +1375,10 @@ def provision(setup_dir, message, session_info,
# Only make a zone file on the first DC, it should be replicated # Only make a zone file on the first DC, it should be replicated
# with DNS replication # with DNS replication
create_zone_file(lp, message, paths, targetdir, setup_path, dnsdomain=names.dnsdomain, create_zone_file(lp, message, paths, targetdir, setup_path,
hostip=hostip, dnsdomain=names.dnsdomain, hostip=hostip, hostip6=hostip6,
hostip6=hostip6, hostname=names.hostname, hostname=names.hostname, realm=names.realm,
realm=names.realm, domainguid=domainguid, ntdsguid=names.ntdsguid)
domainguid=domainguid, ntdsguid=names.ntdsguid)
create_named_conf(paths, setup_path, realm=names.realm, create_named_conf(paths, setup_path, realm=names.realm,
dnsdomain=names.dnsdomain, private_dir=paths.private_dir) dnsdomain=names.dnsdomain, private_dir=paths.private_dir)
@ -1381,12 +1387,14 @@ def provision(setup_dir, message, session_info,
dnsdomain=names.dnsdomain, private_dir=paths.private_dir, dnsdomain=names.dnsdomain, private_dir=paths.private_dir,
keytab_name=paths.dns_keytab) keytab_name=paths.dns_keytab)
message("See %s for an example configuration include file for BIND" % paths.namedconf) message("See %s for an example configuration include file for BIND" % paths.namedconf)
message("and %s for further documentation required for secure DNS updates" % paths.namedtxt) message("and %s for further documentation required for secure DNS "
"updates" % paths.namedtxt)
create_krb5_conf(paths.krb5conf, setup_path, create_krb5_conf(paths.krb5conf, setup_path,
dnsdomain=names.dnsdomain, hostname=names.hostname, dnsdomain=names.dnsdomain, hostname=names.hostname,
realm=names.realm) realm=names.realm)
message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf) message("A Kerberos configuration suitable for Samba 4 has been "
"generated at %s" % paths.krb5conf)
if serverrole == "domain controller": if serverrole == "domain controller":
create_dns_update_list(lp, message, paths, setup_path) create_dns_update_list(lp, message, paths, setup_path)
@ -1407,7 +1415,8 @@ def provision(setup_dir, message, session_info,
os.chmod(dns_keytab_path, 0640) os.chmod(dns_keytab_path, 0640)
os.chown(dns_keytab_path, -1, paths.bind_gid) os.chown(dns_keytab_path, -1, paths.bind_gid)
except OSError: except OSError:
message("Failed to chown %s to bind gid %u" % (dns_keytab_path, paths.bind_gid)) message("Failed to chown %s to bind gid %u" % (dns_keytab_path,
paths.bind_gid))
message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
@ -1443,7 +1452,6 @@ def provision(setup_dir, message, session_info,
return result return result
def provision_become_dc(setup_dir=None, def provision_become_dc(setup_dir=None,
smbconf=None, targetdir=None, realm=None, smbconf=None, targetdir=None, realm=None,
rootdn=None, domaindn=None, schemadn=None, rootdn=None, domaindn=None, schemadn=None,
@ -1622,7 +1630,6 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm):
:param hostname: Local hostname :param hostname: Local hostname
:param realm: Realm name :param realm: Realm name
""" """
setup_file(setup_path("krb5.conf"), path, { setup_file(setup_path("krb5.conf"), path, {
"DNSDOMAIN": dnsdomain, "DNSDOMAIN": dnsdomain,
"HOSTNAME": hostname, "HOSTNAME": hostname,
@ -1630,3 +1637,17 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm):
}) })
class ProvisioningError(Exception):
"""A generic provision error."""
def __init__(self, value):
self.value = value
def __str__(self):
return "ProvisioningError: " + self.value
class InvalidNetbiosName(Exception):
"""A specified name was not a valid NetBIOS name."""
def __init__(self, name):
super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name)

View File

@ -26,6 +26,7 @@
"""Functions for setting up a Samba configuration (LDB and LDAP backends).""" """Functions for setting up a Samba configuration (LDB and LDAP backends)."""
from base64 import b64encode from base64 import b64encode
import errno
import ldb import ldb
import os import os
import sys import sys
@ -40,11 +41,21 @@ from ldb import SCOPE_BASE, SCOPE_ONELEVEL, LdbError, timestring
from samba import Ldb, read_and_sub_file, setup_file from samba import Ldb, read_and_sub_file, setup_file
from samba.credentials import Credentials, DONT_USE_KERBEROS from samba.credentials import Credentials, DONT_USE_KERBEROS
from samba.schema import Schema from samba.schema import Schema
from samba.provisionexceptions import ProvisioningError
class SlapdAlreadyRunning(Exception):
def __init__(self, uri):
self.ldapi_uri = uri
super(SlapdAlreadyRunning, self).__init__("Another slapd Instance "
"seems already running on this host, listening to %s." %
self.ldapi_uri)
class ProvisionBackend(object): class ProvisionBackend(object):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None): def __init__(self, backend_type, paths=None, setup_path=None, lp=None,
credentials=None, names=None, message=None):
"""Provision a backend for samba4""" """Provision a backend for samba4"""
self.paths = paths self.paths = paths
self.setup_path = setup_path self.setup_path = setup_path
@ -72,15 +83,6 @@ class ProvisionBackend(object):
class LDBBackend(ProvisionBackend): class LDBBackend(ProvisionBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None):
super(LDBBackend, self).__init__(
backend_type=backend_type,
paths=paths, setup_path=setup_path,
lp=lp, credentials=credentials,
names=names,
message=message)
def init(self): def init(self):
self.credentials = None self.credentials = None
@ -91,49 +93,40 @@ class LDBBackend(ProvisionBackend):
class ExistingBackend(ProvisionBackend): class ExistingBackend(ProvisionBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None,
ldapi_uri=None):
super(ExistingBackend, self).__init__( def __init__(self, backend_type, paths=None, setup_path=None, lp=None,
backend_type=backend_type, credentials=None, names=None, message=None, ldapi_uri=None):
paths=paths, setup_path=setup_path,
lp=lp, credentials=credentials, super(ExistingBackend, self).__init__(backend_type=backend_type,
names=names, paths=paths, setup_path=setup_path, lp=lp,
message=message) credentials=credentials, names=names, message=message)
self.ldapi_uri = ldapi_uri self.ldapi_uri = ldapi_uri
def init(self): def init(self):
#Check to see that this 'existing' LDAP backend in fact exists # Check to see that this 'existing' LDAP backend in fact exists
ldapi_db = Ldb(self.ldapi_uri, credentials=self.credentials) ldapi_db = Ldb(self.ldapi_uri, credentials=self.credentials)
ldapi_db.search(base="", scope=SCOPE_BASE, ldapi_db.search(base="", scope=SCOPE_BASE,
expression="(objectClass=OpenLDAProotDSE)") expression="(objectClass=OpenLDAProotDSE)")
# If we have got here, then we must have a valid connection to the LDAP server, with valid credentials supplied # If we have got here, then we must have a valid connection to the LDAP
# This caused them to be set into the long-term database later in the script. # server, with valid credentials supplied This caused them to be set
# into the long-term database later in the script.
self.secrets_credentials = self.credentials self.secrets_credentials = self.credentials
self.ldap_backend_type = "openldap" #For now, assume existing backends at least emulate OpenLDAP self.ldap_backend_type = "openldap" # For now, assume existing backends at least emulate OpenLDAP
class LDAPBackend(ProvisionBackend): class LDAPBackend(ProvisionBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None,
domainsid=None,
schema=None,
hostname=None,
ldapadminpass=None,
slapd_path=None,
ldap_backend_extra_port=None,
ldap_dryrun_mode=False):
super(LDAPBackend, self).__init__( def __init__(self, backend_type, paths=None, setup_path=None, lp=None,
backend_type=backend_type, credentials=None, names=None, message=None, domainsid=None,
paths=paths, setup_path=setup_path, schema=None, hostname=None, ldapadminpass=None, slapd_path=None,
lp=lp, credentials=credentials, ldap_backend_extra_port=None, ldap_dryrun_mode=False):
names=names,
message=message) super(LDAPBackend, self).__init__(backend_type=backend_type,
paths=paths, setup_path=setup_path, lp=lp,
credentials=credentials, names=names, message=message)
self.domainsid = domainsid self.domainsid = domainsid
self.schema = schema self.schema = schema
@ -156,23 +149,26 @@ class LDAPBackend(ProvisionBackend):
os.mkdir(self.ldapdir) os.mkdir(self.ldapdir)
def init(self): def init(self):
# we will shortly start slapd with ldapi for final provisioning. first check with ldapsearch -> rootDSE via self.ldapi_uri from samba.provision import ProvisioningError
# if another instance of slapd is already running # we will shortly start slapd with ldapi for final provisioning. first
# check with ldapsearch -> rootDSE via self.ldapi_uri if another
# instance of slapd is already running
try: try:
ldapi_db = Ldb(self.ldapi_uri) ldapi_db = Ldb(self.ldapi_uri)
ldapi_db.search(base="", scope=SCOPE_BASE, ldapi_db.search(base="", scope=SCOPE_BASE,
expression="(objectClass=OpenLDAProotDSE)") expression="(objectClass=OpenLDAProotDSE)")
try: try:
f = open(self.slapd_pid, "r") f = open(self.slapd_pid, "r")
except IOError, err:
if err != errno.ENOENT:
raise
else:
p = f.read() p = f.read()
f.close() f.close()
self.message("Check for slapd Process with PID: " + str(p) + " and terminate it manually.") self.message("Check for slapd Process with PID: " + str(p) + " and terminate it manually.")
except: raise SlapdAlreadyRunning(self.ldapi_uri)
pass
raise ProvisioningError("Warning: Another slapd Instance seems already running on this host, listening to " + self.ldapi_uri + ". Please shut it down before you continue. ")
except LdbError: except LdbError:
# XXX: We should never be catching all Ldb errors
pass pass
# Try to print helpful messages when the user has not specified the path to slapd # Try to print helpful messages when the user has not specified the path to slapd
@ -216,13 +212,15 @@ class LDAPBackend(ProvisionBackend):
pass pass
def start(self): def start(self):
from samba.provision import ProvisioningError
self.slapd_command_escaped = "\'" + "\' \'".join(self.slapd_command) + "\'" self.slapd_command_escaped = "\'" + "\' \'".join(self.slapd_command) + "\'"
open(self.ldapdir + "/ldap_backend_startup.sh", 'w').write("#!/bin/sh\n" + self.slapd_command_escaped + "\n") open(os.path.join(self.ldapdir, "ldap_backend_startup.sh"), 'w').write("#!/bin/sh\n" + self.slapd_command_escaped + "\n")
# Now start the slapd, so we can provision onto it. We keep the # Now start the slapd, so we can provision onto it. We keep the
# subprocess context around, to kill this off at the successful # subprocess context around, to kill this off at the successful
# end of the script # end of the script
self.slapd = subprocess.Popen(self.slapd_provision_command, close_fds=True, shell=False) self.slapd = subprocess.Popen(self.slapd_provision_command,
close_fds=True, shell=False)
while self.slapd.poll() is None: while self.slapd.poll() is None:
# Wait until the socket appears # Wait until the socket appears
@ -253,29 +251,18 @@ class LDAPBackend(ProvisionBackend):
class OpenLDAPBackend(LDAPBackend): class OpenLDAPBackend(LDAPBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None,
domainsid=None,
schema=None,
hostname=None,
ldapadminpass=None,
slapd_path=None,
ldap_backend_extra_port=None,
ldap_dryrun_mode=False,
ol_mmr_urls=None,
nosync=False):
super(OpenLDAPBackend, self).__init__( def __init__(self, backend_type, paths=None, setup_path=None, lp=None,
backend_type=backend_type, credentials=None, names=None, message=None, domainsid=None,
paths=paths, setup_path=setup_path, schema=None, hostname=None, ldapadminpass=None, slapd_path=None,
lp=lp, credentials=credentials, ldap_backend_extra_port=None, ldap_dryrun_mode=False,
names=names, ol_mmr_urls=None, nosync=False):
message=message,
domainsid=domainsid, super(OpenLDAPBackend, self).__init__( backend_type=backend_type,
schema=schema, paths=paths, setup_path=setup_path, lp=lp,
hostname=hostname, credentials=credentials, names=names, message=message,
ldapadminpass=ldapadminpass, domainsid=domainsid, schema=schema, hostname=hostname,
slapd_path=slapd_path, ldapadminpass=ldapadminpass, slapd_path=slapd_path,
ldap_backend_extra_port=ldap_backend_extra_port, ldap_backend_extra_port=ldap_backend_extra_port,
ldap_dryrun_mode=ldap_dryrun_mode) ldap_dryrun_mode=ldap_dryrun_mode)
@ -290,11 +277,8 @@ class OpenLDAPBackend(LDAPBackend):
self.olcdir = os.path.join(self.ldapdir, "slapd.d") self.olcdir = os.path.join(self.ldapdir, "slapd.d")
self.olcseedldif = os.path.join(self.ldapdir, "olc_seed.ldif") self.olcseedldif = os.path.join(self.ldapdir, "olc_seed.ldif")
self.schema = Schema( self.schema = Schema(self.setup_path, self.domainsid,
self.setup_path, schemadn=self.names.schemadn, serverdn=self.names.serverdn,
self.domainsid,
schemadn=self.names.schemadn,
serverdn=self.names.serverdn,
files=[setup_path("schema_samba4.ldif")]) files=[setup_path("schema_samba4.ldif")])
def setup_db_config(self, dbdir): def setup_db_config(self, dbdir):
@ -307,10 +291,11 @@ class OpenLDAPBackend(LDAPBackend):
if not os.path.isdir(os.path.join(dbdir, "tmp")): if not os.path.isdir(os.path.join(dbdir, "tmp")):
os.makedirs(os.path.join(dbdir, "tmp"), 0700) os.makedirs(os.path.join(dbdir, "tmp"), 0700)
setup_file(self.setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"), setup_file(self.setup_path("DB_CONFIG"),
{"LDAPDBDIR": dbdir}) os.path.join(dbdir, "DB_CONFIG"), {"LDAPDBDIR": dbdir})
def provision(self): def provision(self):
from samba.provision import ProvisioningError
# Wipe the directories so we can start # Wipe the directories so we can start
shutil.rmtree(os.path.join(self.ldapdir, "db"), True) shutil.rmtree(os.path.join(self.ldapdir, "db"), True)
@ -350,7 +335,6 @@ class OpenLDAPBackend(LDAPBackend):
mmr_syncrepl_schema_config = "" mmr_syncrepl_schema_config = ""
mmr_syncrepl_config_config = "" mmr_syncrepl_config_config = ""
mmr_syncrepl_user_config = "" mmr_syncrepl_user_config = ""
if self.ol_mmr_urls is not None: if self.ol_mmr_urls is not None:
# For now, make these equal # For now, make these equal
@ -485,7 +469,8 @@ class OpenLDAPBackend(LDAPBackend):
if self.ol_mmr_urls is None: if self.ol_mmr_urls is None:
server_port_string = "ldap://0.0.0.0:%d" % self.ldap_backend_extra_port server_port_string = "ldap://0.0.0.0:%d" % self.ldap_backend_extra_port
else: else:
server_port_string = "ldap://" + self.names.hostname + "." + self.names.dnsdomain +":%d" % self.ldap_backend_extra_port server_port_string = "ldap://%s.%s:%d" (self.names.hostname,
self.names.dnsdomain, self.ldap_backend_extra_port)
else: else:
server_port_string = "" server_port_string = ""
@ -537,29 +522,18 @@ class OpenLDAPBackend(LDAPBackend):
class FDSBackend(LDAPBackend): class FDSBackend(LDAPBackend):
def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,
names=None, message=None,
domainsid=None,
schema=None,
hostname=None,
ldapadminpass=None,
slapd_path=None,
ldap_backend_extra_port=None,
ldap_dryrun_mode=False,
root=None,
setup_ds_path=None):
super(FDSBackend, self).__init__( def __init__(self, backend_type, paths=None, setup_path=None, lp=None,
backend_type=backend_type, credentials=None, names=None, message=None, domainsid=None,
paths=paths, setup_path=setup_path, schema=None, hostname=None, ldapadminpass=None, slapd_path=None,
lp=lp, credentials=credentials, ldap_backend_extra_port=None, ldap_dryrun_mode=False, root=None,
names=names, setup_ds_path=None):
message=message,
domainsid=domainsid, super(FDSBackend, self).__init__(backend_type=backend_type,
schema=schema, paths=paths, setup_path=setup_path, lp=lp,
hostname=hostname, credentials=credentials, names=names, message=message,
ldapadminpass=ldapadminpass, domainsid=domainsid, schema=schema, hostname=hostname,
slapd_path=slapd_path, ldapadminpass=ldapadminpass, slapd_path=slapd_path,
ldap_backend_extra_port=ldap_backend_extra_port, ldap_backend_extra_port=ldap_backend_extra_port,
ldap_dryrun_mode=ldap_dryrun_mode) ldap_dryrun_mode=ldap_dryrun_mode)
@ -600,6 +574,7 @@ class FDSBackend(LDAPBackend):
prefixmap=["1000:1.3.6.1.4.1.7165.2.1", "1001:1.3.6.1.4.1.7165.2.2"]) prefixmap=["1000:1.3.6.1.4.1.7165.2.1", "1001:1.3.6.1.4.1.7165.2.2"])
def provision(self): def provision(self):
from samba.provision import ProvisioningError
if self.ldap_backend_extra_port is not None: if self.ldap_backend_extra_port is not None:
serverport = "ServerPort=%d" % self.ldap_backend_extra_port serverport = "ServerPort=%d" % self.ldap_backend_extra_port
else: else:
@ -616,7 +591,8 @@ class FDSBackend(LDAPBackend):
"LDAPMANAGERPASS": self.ldapadminpass, "LDAPMANAGERPASS": self.ldapadminpass,
"SERVERPORT": serverport}) "SERVERPORT": serverport})
setup_file(self.setup_path("fedorads-partitions.ldif"), self.partitions_ldif, setup_file(self.setup_path("fedorads-partitions.ldif"),
self.partitions_ldif,
{"CONFIGDN": self.names.configdn, {"CONFIGDN": self.names.configdn,
"SCHEMADN": self.names.schemadn, "SCHEMADN": self.names.schemadn,
"SAMBADN": self.sambadn, "SAMBADN": self.sambadn,

View File

@ -1,38 +0,0 @@
#
# Unix SMB/CIFS implementation.
# backend code for provisioning a Samba4 server
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008
# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008-2009
# Copyright (C) Oliver Liebel <oliver@itc.li> 2008-2009
#
# Based on the original in EJS:
# Copyright (C) Andrew Tridgell <tridge@samba.org> 2005
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
class ProvisioningError(Exception):
"""A generic provision error."""
def __init__(self, value):
self.value = value
def __str__(self):
return "ProvisioningError: " + self.value
class InvalidNetbiosName(ProvisioningError):
"""A specified name was not a valid NetBIOS name."""
def __init__(self, name):
super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name)

View File

@ -31,8 +31,8 @@ from samba import Ldb
from samba.dsdb import DS_DOMAIN_FUNCTION_2000 from samba.dsdb import DS_DOMAIN_FUNCTION_2000
from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE
import ldb import ldb
from samba.provision import ProvisionNames, provision_paths_from_lp, FILL_FULL, provision from samba.provision import (ProvisionNames, provision_paths_from_lp,
from samba.provisionexceptions import ProvisioningError FILL_FULL, provision, ProvisioningError)
from samba.dcerpc import misc, security from samba.dcerpc import misc, security
from samba.ndr import ndr_unpack from samba.ndr import ndr_unpack
@ -61,7 +61,8 @@ def get_paths(param, targetdir=None, smbconf=None):
return paths return paths
def find_provision_key_parameters(param, credentials, session_info, paths, smbconf): def find_provision_key_parameters(param, credentials, session_info, paths,
smbconf):
"""Get key provision parameters (realm, domain, ...) from a given provision """Get key provision parameters (realm, domain, ...) from a given provision
:param param: Param object :param param: Param object
@ -82,10 +83,10 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco
names.dnsdomain = names.realm names.dnsdomain = names.realm
names.realm = string.upper(names.realm) names.realm = string.upper(names.realm)
# netbiosname # netbiosname
secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials,lp=lp, options=["modules:samba_secrets"]) secrets_ldb = Ldb(paths.secrets, session_info=session_info,
credentials=credentials,lp=lp, options=["modules:samba_secrets"])
# Get the netbiosname first (could be obtained from smb.conf in theory) # Get the netbiosname first (could be obtained from smb.conf in theory)
attrs = ["sAMAccountName"] res = secrets_ldb.search(expression="(flatname=%s)"%names.domain,base="CN=Primary Domains", scope=SCOPE_SUBTREE, attrs=["sAMAccountName"])
res = secrets_ldb.search(expression="(flatname=%s)"%names.domain,base="CN=Primary Domains", scope=SCOPE_SUBTREE, attrs=attrs)
names.netbiosname = str(res[0]["sAMAccountName"]).replace("$","") names.netbiosname = str(res[0]["sAMAccountName"]).replace("$","")
names.smbconf = smbconf names.smbconf = smbconf
@ -96,8 +97,7 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco
# That's a bit simplistic but it's ok as long as we have only 3 # That's a bit simplistic but it's ok as long as we have only 3
# partitions # partitions
attrs2 = ["defaultNamingContext", "schemaNamingContext","configurationNamingContext","rootDomainNamingContext"] current = samdb.search(expression="(objectClass=*)",base="", scope=SCOPE_BASE, attrs=["defaultNamingContext", "schemaNamingContext","configurationNamingContext","rootDomainNamingContext"])
current = samdb.search(expression="(objectClass=*)",base="", scope=SCOPE_BASE, attrs=attrs2)
names.configdn = current[0]["configurationNamingContext"] names.configdn = current[0]["configurationNamingContext"]
configdn = str(names.configdn) configdn = str(names.configdn)
@ -108,27 +108,28 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco
names.domaindn=current[0]["defaultNamingContext"] names.domaindn=current[0]["defaultNamingContext"]
names.rootdn=current[0]["rootDomainNamingContext"] names.rootdn=current[0]["rootDomainNamingContext"]
# default site name # default site name
attrs3 = ["cn"] res3= samdb.search(expression="(objectClass=*)",base="CN=Sites,"+configdn, scope=SCOPE_ONELEVEL, attrs=["cn"])
res3= samdb.search(expression="(objectClass=*)",base="CN=Sites,"+configdn, scope=SCOPE_ONELEVEL, attrs=attrs3)
names.sitename = str(res3[0]["cn"]) names.sitename = str(res3[0]["cn"])
# dns hostname and server dn # dns hostname and server dn
attrs4 = ["dNSHostName"]
res4= samdb.search(expression="(CN=%s)"%names.netbiosname,base="OU=Domain Controllers,"+basedn, \ res4= samdb.search(expression="(CN=%s)"%names.netbiosname,base="OU=Domain Controllers,"+basedn, \
scope=SCOPE_ONELEVEL, attrs=attrs4) scope=SCOPE_ONELEVEL, attrs=["dNSHostName"])
names.hostname = str(res4[0]["dNSHostName"]).replace("."+names.dnsdomain,"") names.hostname = str(res4[0]["dNSHostName"]).replace("."+names.dnsdomain,"")
server_res = samdb.search(expression="serverReference=%s"%res4[0].dn, attrs=[], base=configdn) server_res = samdb.search(expression="serverReference=%s"%res4[0].dn, attrs=[], base=configdn)
names.serverdn = server_res[0].dn names.serverdn = server_res[0].dn
# invocation id/objectguid # invocation id/objectguid
res5 = samdb.search(expression="(objectClass=*)",base="CN=NTDS Settings,%s" % str(names.serverdn), scope=SCOPE_BASE, attrs=["invocationID","objectGUID"]) res5 = samdb.search(expression="(objectClass=*)",
names.invocation = str(ndr_unpack( misc.GUID,res5[0]["invocationId"][0])) base="CN=NTDS Settings,%s" % str(names.serverdn), scope=SCOPE_BASE,
names.ntdsguid = str(ndr_unpack( misc.GUID,res5[0]["objectGUID"][0])) attrs=["invocationID", "objectGUID"])
names.invocation = str(ndr_unpack(misc.GUID, res5[0]["invocationId"][0]))
names.ntdsguid = str(ndr_unpack(misc.GUID, res5[0]["objectGUID"][0]))
# domain guid/sid # domain guid/sid
attrs6 = ["objectGUID", "objectSid","msDS-Behavior-Version" ] res6 = samdb.search(expression="(objectClass=*)",base=basedn,
res6 = samdb.search(expression="(objectClass=*)",base=basedn, scope=SCOPE_BASE, attrs=attrs6) scope=SCOPE_BASE, attrs=["objectGUID",
"objectSid","msDS-Behavior-Version" ])
names.domainguid = str(ndr_unpack( misc.GUID,res6[0]["objectGUID"][0])) names.domainguid = str(ndr_unpack( misc.GUID,res6[0]["objectGUID"][0]))
names.domainsid = ndr_unpack( security.dom_sid,res6[0]["objectSid"][0]) names.domainsid = ndr_unpack( security.dom_sid,res6[0]["objectSid"][0])
if res6[0].get("msDS-Behavior-Version") == None or int(res6[0]["msDS-Behavior-Version"][0]) < DS_DOMAIN_FUNCTION_2000: if res6[0].get("msDS-Behavior-Version") == None or int(res6[0]["msDS-Behavior-Version"][0]) < DS_DOMAIN_FUNCTION_2000:
@ -137,14 +138,12 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco
names.domainlevel = int(res6[0]["msDS-Behavior-Version"][0]) names.domainlevel = int(res6[0]["msDS-Behavior-Version"][0])
# policy guid # policy guid
attrs7 = ["cn","displayName"]
res7 = samdb.search(expression="(displayName=Default Domain Policy)",base="CN=Policies,CN=System,"+basedn, \ res7 = samdb.search(expression="(displayName=Default Domain Policy)",base="CN=Policies,CN=System,"+basedn, \
scope=SCOPE_ONELEVEL, attrs=attrs7) scope=SCOPE_ONELEVEL, attrs=["cn","displayName"])
names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","") names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","")
# dc policy guid # dc policy guid
attrs8 = ["cn","displayName"]
res8 = samdb.search(expression="(displayName=Default Domain Controllers Policy)",base="CN=Policies,CN=System,"+basedn, \ res8 = samdb.search(expression="(displayName=Default Domain Controllers Policy)",base="CN=Policies,CN=System,"+basedn, \
scope=SCOPE_ONELEVEL, attrs=attrs8) scope=SCOPE_ONELEVEL, attrs=["cn","displayName"])
if len(res8) == 1: if len(res8) == 1:
names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","") names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")
else: else:
@ -194,9 +193,12 @@ def newprovision(names,setup_dir,creds,session,smbconf,provdir,messagefunc):
def dn_sort(x,y): def dn_sort(x,y):
"""Sorts two DNs in the lexicographical order it and put higher level DN before. """Sorts two DNs in the lexicographical order it and put higher level DN
before.
So given the dns cn=bar,cn=foo and cn=foo the later will be return as
smaller
So given the dns cn=bar,cn=foo and cn=foo the later will be return as smaller
:param x: First object to compare :param x: First object to compare
:param y: Second object to compare :param y: Second object to compare
""" """

View File

@ -34,13 +34,12 @@ import samba.ntacls
from samba.credentials import DONT_USE_KERBEROS from samba.credentials import DONT_USE_KERBEROS
from samba.auth import system_session from samba.auth import system_session
import samba.getopt as options import samba.getopt as options
from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir from samba.provision import provision, FILL_FULL, FILL_NT4SYNC, FILL_DRS, find_setup_dir, ProvisioningError
from samba.dsdb import ( from samba.dsdb import (
DS_DOMAIN_FUNCTION_2003, DS_DOMAIN_FUNCTION_2003,
DS_DOMAIN_FUNCTION_2008, DS_DOMAIN_FUNCTION_2008,
DS_DOMAIN_FUNCTION_2008_R2, DS_DOMAIN_FUNCTION_2008_R2,
) )
from samba.provisionexceptions import ProvisioningError
# how do we make this case insensitive?? # how do we make this case insensitive??
@ -118,7 +117,7 @@ parser.add_option("--slapd-path", type="string", metavar="SLAPD-PATH",
parser.add_option("--setup-ds-path", type="string", metavar="SETUP_DS-PATH", parser.add_option("--setup-ds-path", type="string", metavar="SETUP_DS-PATH",
help="Path to setup-ds.pl script for Fedora DS LDAP backend [e.g.:'/usr/sbin/setup-ds.pl']. Required for Setup with Fedora DS backend.") help="Path to setup-ds.pl script for Fedora DS LDAP backend [e.g.:'/usr/sbin/setup-ds.pl']. Required for Setup with Fedora DS backend.")
parser.add_option("--nosync", help="Configure LDAP backend not to call fsync() (for performance in test environments)", action="store_true") parser.add_option("--nosync", help="Configure LDAP backend not to call fsync() (for performance in test environments)", action="store_true")
parser.add_option("--use-xattrs", type="choice", choices=["yes","no","auto"], help="Define if we should use the native fs capabilities or a tdb file for storing attributes likes ntacl, auto tries to make an inteligent guess based on the user rights and system capabilities") parser.add_option("--use-xattrs", type="choice", choices=["yes","no","auto"], help="Define if we should use the native fs capabilities or a tdb file for storing attributes likes ntacl, auto tries to make an inteligent guess based on the user rights and system capabilities", default="auto")
parser.add_option("--ldap-dryrun-mode", help="Configure LDAP backend, but do not run any binaries and exit early. Used only for the test environment. DO NOT USE", action="store_true") parser.add_option("--ldap-dryrun-mode", help="Configure LDAP backend, but do not run any binaries and exit early. Used only for the test environment. DO NOT USE", action="store_true")
opts = parser.parse_args()[0] opts = parser.parse_args()[0]
@ -210,16 +209,14 @@ if opts.blank:
elif opts.partitions_only: elif opts.partitions_only:
samdb_fill = FILL_DRS samdb_fill = FILL_DRS
if not opts.use_xattrs:
opts.use_xattrs="auto"
eadb = True eadb = True
if opts.use_xattrs == "yes": if opts.use_xattrs == "yes":
eadb = False eadb = False
elif opts.use_xattrs == "auto": elif opts.use_xattrs == "auto":
file=tempfile.NamedTemporaryFile() file = tempfile.NamedTemporaryFile()
try: try:
samba.ntacls.setntacl(lp,file.name,"O:S-1-5-32G:S-1-5-32","S-1-5-32","native") samba.ntacls.setntacl(lp, file.name,
"O:S-1-5-32G:S-1-5-32", "S-1-5-32", "native")
eadb = False eadb = False
except: except:
if lp.get("posix:eadb") == None: if lp.get("posix:eadb") == None: