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:
parent
be4b688175
commit
d7a46ee129
@ -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"])
|
||||||
|
@ -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:
|
||||||
|
@ -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"""
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
"""
|
"""
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user