2007-12-10 11:29:00 +03:00
#
2008-01-25 03:02:13 +03:00
# 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
2007-12-20 01:27:24 +03:00
#
# Based on the original in EJS:
2008-01-25 03:02:13 +03:00
# 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/>.
2007-12-10 11:29:00 +03:00
#
from base64 import b64encode
import os
import pwd
import grp
import time
2007-12-17 06:56:54 +03:00
import uuid , misc
2007-12-10 11:29:00 +03:00
from socket import gethostname , gethostbyname
import param
import registry
2007-12-17 22:03:06 +03:00
import samba
2008-01-25 03:02:13 +03:00
from samba import Ldb , substitute_var , valid_netbios_name , check_all_substituted
2007-12-17 10:20:20 +03:00
from samba . samdb import SamDB
2007-12-17 13:12:36 +03:00
import security
2008-01-25 03:02:13 +03:00
import urllib
2008-01-11 18:13:46 +03:00
from ldb import SCOPE_SUBTREE , SCOPE_ONELEVEL , SCOPE_BASE , LdbError , \
2007-12-20 01:27:38 +03:00
LDB_ERR_NO_SUCH_OBJECT , timestring , CHANGETYPE_MODIFY , CHANGETYPE_NONE
2007-12-10 11:29:00 +03:00
2007-12-30 03:14:18 +03:00
""" Functions for setting up a Samba configuration. """
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:24 +03:00
DEFAULTSITE = " Default-First-Site-Name "
2007-12-10 11:29:00 +03:00
class InvalidNetbiosName ( Exception ) :
def __init__ ( self , name ) :
super ( InvalidNetbiosName , self ) . __init__ ( " The name ' %r ' is not a valid NetBIOS name " % name )
class ProvisionPaths :
def __init__ ( self ) :
self . smbconf = None
self . shareconf = None
self . hklm = None
self . hkcu = None
self . hkcr = None
self . hku = None
self . hkpd = None
self . hkpt = None
self . samdb = None
self . secrets = None
self . keytab = None
2007-12-18 19:21:20 +03:00
self . dns_keytab = None
2007-12-10 11:29:00 +03:00
self . dns = None
self . winsdb = None
self . ldap_basedn_ldif = None
self . ldap_config_basedn_ldif = None
self . ldap_schema_basedn_ldif = None
2008-01-25 03:02:13 +03:00
def check_install ( lp , session_info , credentials ) :
2007-12-30 03:14:18 +03:00
""" Check whether the current install seems ok.
: param lp : Loadparm context
: param session_info : Session information
: param credentials : Credentials
"""
2007-12-18 01:16:12 +03:00
if lp . get ( " realm " ) == " " :
2008-01-25 03:02:13 +03:00
raise Error ( " Realm empty " )
2007-12-18 01:16:12 +03:00
ldb = Ldb ( lp . get ( " sam database " ) , session_info = session_info ,
credentials = credentials , lp = lp )
2008-01-11 18:13:46 +03:00
if len ( ldb . search ( " (cn=Administrator) " ) ) != 1 :
2008-01-25 03:02:13 +03:00
raise " No administrator account found "
2007-12-10 11:29:00 +03:00
def findnss ( nssfn , * names ) :
""" Find a user or group from a list of possibilities. """
for name in names :
try :
return nssfn ( name )
except KeyError :
pass
raise Exception ( " Unable to find user/group for %s " % arguments [ 1 ] )
2007-12-18 01:16:12 +03:00
def open_ldb ( session_info , credentials , lp , dbname ) :
2007-12-30 03:14:15 +03:00
""" Open a LDB, thrashing it if it is corrupt.
: param session_info : auth session information
: param credentials : credentials
: param lp : Loadparm context
: param dbname : Path of the database to open .
: return : a Ldb object
"""
2007-12-10 11:29:00 +03:00
assert session_info is not None
try :
2007-12-18 01:16:12 +03:00
return Ldb ( dbname , session_info = session_info , credentials = credentials ,
lp = lp )
2007-12-10 11:29:00 +03:00
except LdbError , e :
print e
os . unlink ( dbname )
2007-12-18 01:16:12 +03:00
return Ldb ( dbname , session_info = session_info , credentials = credentials ,
lp = lp )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
def setup_add_ldif ( ldb , ldif_path , subst_vars = None ) :
2007-12-30 03:14:15 +03:00
""" Setup a ldb in the private dir.
: param ldb : LDB file to import data into
: param ldif_path : Path of the LDIF file to load
: param subst_vars : Optional variables to subsitute in LDIF .
"""
2007-12-20 01:27:38 +03:00
assert isinstance ( ldif_path , str )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
data = open ( ldif_path , ' r ' ) . read ( )
2007-12-18 19:21:13 +03:00
if subst_vars is not None :
data = substitute_var ( data , subst_vars )
2007-12-10 11:29:00 +03:00
2008-01-25 03:02:13 +03:00
check_all_substituted ( data )
2007-12-18 19:21:20 +03:00
2007-12-26 01:36:44 +03:00
ldb . add_ldif ( data )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
def setup_modify_ldif ( ldb , ldif_path , substvars = None ) :
2007-12-18 20:54:19 +03:00
""" Modify a ldb in the private dir.
: param ldb : LDB object .
2007-12-20 01:27:38 +03:00
: param ldif_path : LDIF file path .
2007-12-18 20:54:19 +03:00
: param substvars : Optional dictionary with substitution variables .
"""
2007-12-20 01:27:38 +03:00
data = open ( ldif_path , ' r ' ) . read ( )
2007-12-18 19:21:13 +03:00
if substvars is not None :
data = substitute_var ( data , substvars )
2007-12-10 11:29:00 +03:00
2008-01-25 03:02:13 +03:00
check_all_substituted ( data )
2007-12-18 19:21:20 +03:00
2007-12-24 04:19:41 +03:00
ldb . modify_ldif ( data )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
def setup_ldb ( ldb , ldif_path , subst_vars ) :
2007-12-10 11:29:00 +03:00
assert ldb is not None
ldb . transaction_start ( )
try :
2007-12-20 01:27:38 +03:00
setup_add_ldif ( ldb , ldif_path , subst_vars )
2007-12-10 11:29:00 +03:00
except :
ldb . transaction_cancel ( )
raise
ldb . transaction_commit ( )
2007-12-20 01:27:38 +03:00
def setup_file ( template , fname , substvars ) :
2007-12-30 03:14:15 +03:00
""" Setup a file in the private dir.
: param template : Path of the template file .
: param fname : Path of the file to create .
: param substvars : Substitution variables .
"""
2007-12-10 11:29:00 +03:00
f = fname
2007-12-18 19:21:13 +03:00
if os . path . exists ( f ) :
os . unlink ( f )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
data = open ( template , ' r ' ) . read ( )
2007-12-18 19:21:20 +03:00
if substvars :
data = substitute_var ( data , substvars )
2008-01-25 03:02:13 +03:00
check_all_substituted ( data )
2007-12-10 11:29:00 +03:00
open ( f , ' w ' ) . write ( data )
2008-01-25 03:02:13 +03:00
def provision_paths_from_lp ( lp , dnsdomain , private_dir = None ) :
2007-12-10 11:29:00 +03:00
""" Set the default paths for provisioning.
: param lp : Loadparm context .
2007-12-20 01:27:24 +03:00
: param dnsdomain : DNS Domain name
2007-12-10 11:29:00 +03:00
"""
paths = ProvisionPaths ( )
2008-01-25 03:02:13 +03:00
if private_dir is None :
private_dir = lp . get ( " private dir " )
2007-12-10 11:29:00 +03:00
paths . shareconf = os . path . join ( private_dir , " share.ldb " )
2007-12-18 04:21:28 +03:00
paths . samdb = os . path . join ( private_dir , lp . get ( " sam database " ) or " samdb.ldb " )
paths . secrets = os . path . join ( private_dir , lp . get ( " secrets database " ) or " secrets.ldb " )
2007-12-10 11:29:00 +03:00
paths . templates = os . path . join ( private_dir , " templates.ldb " )
paths . keytab = os . path . join ( private_dir , " secrets.keytab " )
2007-12-18 19:21:20 +03:00
paths . dns_keytab = os . path . join ( private_dir , " dns.keytab " )
2007-12-20 01:27:24 +03:00
paths . dns = os . path . join ( private_dir , dnsdomain + " .zone " )
2007-12-10 11:29:00 +03:00
paths . winsdb = os . path . join ( private_dir , " wins.ldb " )
paths . s4_ldapi_path = os . path . join ( private_dir , " ldapi " )
2007-12-18 01:16:16 +03:00
paths . phpldapadminconfig = os . path . join ( private_dir ,
" phpldapadmin-config.php " )
2007-12-10 11:29:00 +03:00
paths . hklm = os . path . join ( private_dir , " hklm.ldb " )
2007-12-18 19:21:20 +03:00
paths . sysvol = lp . get ( " sysvol " , " path " )
if paths . sysvol is None :
paths . sysvol = os . path . join ( lp . get ( " lock dir " ) , " sysvol " )
paths . netlogon = lp . get ( " netlogon " , " path " )
if paths . netlogon is None :
paths . netlogon = os . path . join ( os . path . join ( paths . sysvol , " scripts " ) )
2007-12-10 11:29:00 +03:00
return paths
2007-12-20 01:27:24 +03:00
def setup_name_mappings ( ldb , sid , domaindn , root , nobody , nogroup , users ,
wheel , backup ) :
2007-12-30 03:14:15 +03:00
""" setup reasonable name mappings for sam names to unix names.
: param ldb : SamDB object .
: param sid : The domain sid .
: param domaindn : The domain DN .
: param root : Name of the UNIX root user .
: param nobody : Name of the UNIX nobody user .
: param nogroup : Name of the unix nobody group .
: param users : Name of the unix users group .
: param wheel : Name of the wheel group ( users that can become root ) .
: param backup : Name of the backup group . """
2007-12-10 11:29:00 +03:00
# add some foreign sids if they are not present already
2007-12-20 01:27:24 +03:00
ldb . add_foreign ( domaindn , " S-1-5-7 " , " Anonymous " )
ldb . add_foreign ( domaindn , " S-1-1-0 " , " World " )
ldb . add_foreign ( domaindn , " S-1-5-2 " , " Network " )
ldb . add_foreign ( domaindn , " S-1-5-18 " , " System " )
ldb . add_foreign ( domaindn , " S-1-5-11 " , " Authenticated Users " )
2007-12-10 11:29:00 +03:00
# some well known sids
2007-12-20 01:27:24 +03:00
ldb . setup_name_mapping ( domaindn , " S-1-5-7 " , nobody )
ldb . setup_name_mapping ( domaindn , " S-1-1-0 " , nogroup )
ldb . setup_name_mapping ( domaindn , " S-1-5-2 " , nogroup )
ldb . setup_name_mapping ( domaindn , " S-1-5-18 " , root )
ldb . setup_name_mapping ( domaindn , " S-1-5-11 " , users )
ldb . setup_name_mapping ( domaindn , " S-1-5-32-544 " , wheel )
ldb . setup_name_mapping ( domaindn , " S-1-5-32-545 " , users )
ldb . setup_name_mapping ( domaindn , " S-1-5-32-546 " , nogroup )
ldb . setup_name_mapping ( domaindn , " S-1-5-32-551 " , backup )
2007-12-10 11:29:00 +03:00
# and some well known domain rids
2007-12-20 01:27:24 +03:00
ldb . setup_name_mapping ( domaindn , sid + " -500 " , root )
ldb . setup_name_mapping ( domaindn , sid + " -518 " , wheel )
ldb . setup_name_mapping ( domaindn , sid + " -519 " , wheel )
ldb . setup_name_mapping ( domaindn , sid + " -512 " , wheel )
ldb . setup_name_mapping ( domaindn , sid + " -513 " , users )
ldb . setup_name_mapping ( domaindn , sid + " -520 " , wheel )
2007-12-10 11:29:00 +03:00
2008-01-25 03:02:13 +03:00
def setup_samdb_partitions ( samdb_path , setup_path , message , lp , session_info ,
credentials , configdn , schemadn , domaindn ,
hostname , netbiosname , dnsdomain , realm ,
rootdn , serverrole , ldap_backend = None ,
ldap_backend_type = None , erase = False ) :
""" Setup the partitions for the SAM database.
Alternatively , provision ( ) may call this , and then populate the database .
: param erase : Remove the existing data present in the database .
: param
: note : This will wipe the Sam Database !
: note : This function always removes the local SAM LDB file . The erase
parameter controls whether to erase the existing data , which
may not be stored locally but in LDAP .
"""
2007-12-10 11:29:00 +03:00
assert session_info is not None
2007-12-20 01:27:38 +03:00
2008-01-25 03:02:13 +03:00
if os . path . exists ( samdb_path ) :
os . unlink ( samdb_path )
2007-12-10 11:29:00 +03:00
# Also wipes the database
2008-01-25 03:02:13 +03:00
samdb = SamDB ( samdb_path , session_info = session_info ,
2007-12-20 17:53:56 +03:00
credentials = credentials , lp = lp )
2007-12-10 11:29:00 +03:00
2008-01-25 03:02:13 +03:00
#Add modules to the list to activate them by default
#beware often order is important
#
# Some Known ordering constraints:
# - rootdse must be first, as it makes redirects from "" -> cn=rootdse
# - objectclass must be before password_hash, because password_hash checks
# that the objectclass is of type person (filled in by objectclass
# module when expanding the objectclass list)
# - partition must be last
# - each partition has its own module list then
modules_list = [ " rootdse " ,
" paged_results " ,
" ranged_results " ,
" anr " ,
" server_sort " ,
" extended_dn " ,
" asq " ,
" samldb " ,
" rdn_name " ,
" objectclass " ,
" kludge_acl " ,
" operational " ]
tdb_modules_list = [
" subtree_rename " ,
" subtree_delete " ,
" linked_attributes " ]
modules_list2 = [ " show_deleted " ,
" partition " ]
domaindn_ldb = " users.ldb "
if ldap_backend is not None :
domaindn_ldb = ldap_backend
configdn_ldb = " configuration.ldb "
if ldap_backend is not None :
configdn_ldb = ldap_backend
schema_ldb = " schema.ldb "
if ldap_backend is not None :
schema_ldb = ldap_backend
if ldap_backend_type == " fedora-ds " :
backend_modules = [ " nsuniqueid " , " paged_searches " ]
elif ldap_backend_type == " openldap " :
backend_modules = [ " normalise " , " entryuuid " , " paged_searches " ]
elif serverrole == " domain controller " :
backend_modules = [ " repl_meta_data " ]
else :
backend_modules = [ " objectguid " ]
setup_add_ldif ( samdb , setup_path ( " provision_partitions.ldif " ) , {
" SCHEMADN " : schemadn ,
" SCHEMADN_LDB " : " schema.ldb " ,
" SCHEMADN_MOD2 " : " ,objectguid " ,
" CONFIGDN " : configdn ,
" CONFIGDN_LDB " : " configuration.ldb " ,
" DOMAINDN " : domaindn ,
" DOMAINDN_LDB " : " users.ldb " ,
" SCHEMADN_MOD " : " schema_fsmo,instancetype " ,
" CONFIGDN_MOD " : " naming_fsmo,instancetype " ,
" DOMAINDN_MOD " : " pdc_fsmo,password_hash,instancetype " ,
" MODULES_LIST " : " , " . join ( modules_list ) ,
" TDB_MODULES_LIST " : " , " + " , " . join ( tdb_modules_list ) ,
" MODULES_LIST2 " : " , " . join ( modules_list2 ) ,
" BACKEND_MOD " : " , " . join ( backend_modules ) ,
} )
2007-12-18 19:21:13 +03:00
2008-01-25 03:02:13 +03:00
samdb = SamDB ( samdb_path , session_info = session_info ,
2007-12-20 17:53:56 +03:00
credentials = credentials , lp = lp )
2007-12-18 19:21:13 +03:00
2008-01-25 03:02:13 +03:00
samdb . transaction_start ( )
2007-12-10 11:29:00 +03:00
try :
2007-12-20 01:27:38 +03:00
message ( " Setting up sam.ldb attributes " )
samdb . load_ldif_file_add ( setup_path ( " provision_init.ldif " ) )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
message ( " Setting up sam.ldb rootDSE " )
2008-01-25 03:02:13 +03:00
setup_samdb_rootdse ( samdb , setup_path , schemadn , domaindn , hostname ,
dnsdomain , realm , rootdn , configdn , netbiosname )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
if erase :
message ( " Erasing data from partitions " )
samdb . erase_partitions ( )
2007-12-10 11:29:00 +03:00
except :
samdb . transaction_cancel ( )
raise
samdb . transaction_commit ( )
2008-01-25 03:02:13 +03:00
return samdb
2007-12-10 11:29:00 +03:00
2008-01-25 03:02:13 +03:00
def secretsdb_become_dc ( secretsdb , setup_path , domain , realm , dnsdomain ,
netbiosname , domainsid , keytab_path , samdb_url ,
dns_keytab_path , dnspass , machinepass ) :
""" Add DC-specific bits to a secrets database.
: param secretsdb : Ldb Handle to the secrets database
: param setup_path : Setup path function
: param machinepass : Machine password
"""
setup_ldb ( secretsdb , setup_path ( " secrets_dc.ldif " ) , {
" MACHINEPASS_B64 " : b64encode ( machinepass ) ,
" DOMAIN " : domain ,
" REALM " : realm ,
" DNSDOMAIN " : dnsdomain ,
" DOMAINSID " : str ( domainsid ) ,
" SECRETS_KEYTAB " : keytab_path ,
" NETBIOSNAME " : netbiosname ,
" SAM_LDB " : samdb_url ,
" DNS_KEYTAB " : dns_keytab_path ,
" DNSPASS_B64 " : b64encode ( dnspass ) ,
} )
2007-12-18 19:21:13 +03:00
2007-12-20 01:27:38 +03:00
def setup_secretsdb ( path , setup_path , session_info , credentials , lp ) :
2008-01-24 03:06:19 +03:00
""" Setup the secrets database.
: param path : Path to the secrets database .
: param setup_path : Get the path to a setup file .
: param session_info : Session info .
: param credentials : Credentials
: param lp : Loadparm context
2008-01-25 03:02:13 +03:00
: return : LDB handle for the created secrets database
2008-01-24 03:06:19 +03:00
"""
2007-12-20 17:53:56 +03:00
if os . path . exists ( path ) :
os . unlink ( path )
2008-01-25 03:02:13 +03:00
secrets_ldb = Ldb ( path , session_info = session_info , credentials = credentials ,
lp = lp )
2007-12-18 19:21:13 +03:00
secrets_ldb . erase ( )
2007-12-20 01:27:38 +03:00
secrets_ldb . load_ldif_file_add ( setup_path ( " secrets_init.ldif " ) )
secrets_ldb . load_ldif_file_add ( setup_path ( " secrets.ldif " ) )
2007-12-18 19:21:13 +03:00
return secrets_ldb
2007-12-20 01:27:38 +03:00
def setup_templatesdb ( path , setup_path , session_info , credentials , lp ) :
2008-01-24 03:06:19 +03:00
""" Setup the templates database.
: param path : Path to the database .
: param setup_path : Function for obtaining the path to setup files .
: param session_info : Session info
: param credentials : Credentials
: param lp : Loadparm context
"""
2007-12-20 01:27:38 +03:00
templates_ldb = SamDB ( path , session_info = session_info ,
2008-01-25 03:02:13 +03:00
credentials = credentials , lp = lp )
2007-12-18 19:21:13 +03:00
templates_ldb . erase ( )
2007-12-20 01:27:38 +03:00
templates_ldb . load_ldif_file_add ( setup_path ( " provision_templates.ldif " ) )
2007-12-18 19:21:13 +03:00
2007-12-20 01:27:38 +03:00
def setup_registry ( path , setup_path , session_info , credentials , lp ) :
2008-01-24 03:06:19 +03:00
""" Setup the registry.
: param path : Path to the registry database
: param setup_path : Function that returns the path to a setup .
: param session_info : Session information
: param credentials : Credentials
: param lp : Loadparm context
"""
2007-12-18 19:21:13 +03:00
reg = registry . Registry ( )
2007-12-22 14:03:02 +03:00
hive = registry . open_ldb ( path , session_info = session_info ,
2007-12-18 19:21:13 +03:00
credentials = credentials , lp_ctx = lp )
reg . mount_hive ( hive , " HKEY_LOCAL_MACHINE " )
2007-12-20 01:27:38 +03:00
provision_reg = setup_path ( " provision.reg " )
2007-12-18 19:21:13 +03:00
assert os . path . exists ( provision_reg )
2007-12-22 14:03:02 +03:00
reg . diff_apply ( provision_reg )
2007-12-18 19:21:13 +03:00
2007-12-20 01:27:38 +03:00
def setup_samdb_rootdse ( samdb , setup_path , schemadn , domaindn , hostname ,
2007-12-20 01:27:24 +03:00
dnsdomain , realm , rootdn , configdn , netbiosname ) :
2008-01-24 03:06:19 +03:00
""" Setup the SamDB rootdse.
: param samdb : Sam Database handle
: param setup_path : Obtain setup path
. . .
"""
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_rootdse_add.ldif " ) , {
2007-12-20 01:27:24 +03:00
" SCHEMADN " : schemadn ,
" NETBIOSNAME " : netbiosname ,
" DNSDOMAIN " : dnsdomain ,
" DEFAULTSITE " : DEFAULTSITE ,
" REALM " : realm ,
" DNSNAME " : " %s . %s " % ( hostname , dnsdomain ) ,
" DOMAINDN " : domaindn ,
" ROOTDN " : rootdn ,
" CONFIGDN " : configdn ,
2007-12-18 19:21:13 +03:00
" VERSION " : samba . version ( ) ,
} )
2008-01-25 03:02:13 +03:00
2007-12-10 11:29:00 +03:00
2007-12-22 11:26:38 +03:00
def setup_self_join ( samdb , configdn , schemadn , domaindn ,
netbiosname , hostname , dnsdomain , machinepass , dnspass ,
realm , domainname , domainsid , invocationid , setup_path ,
policyguid , hostguid = None ) :
2008-01-25 03:02:13 +03:00
""" Join a host to its own domain. """
2007-12-22 11:26:38 +03:00
if hostguid is not None :
hostguid_add = " objectGUID: %s " % hostguid
else :
hostguid_add = " "
setup_add_ldif ( samdb , setup_path ( " provision_self_join.ldif " ) , {
" CONFIGDN " : configdn ,
" SCHEMADN " : schemadn ,
" DOMAINDN " : domaindn ,
" INVOCATIONID " : invocationid ,
" NETBIOSNAME " : netbiosname ,
" DEFAULTSITE " : DEFAULTSITE ,
" DNSNAME " : " %s . %s " % ( hostname , dnsdomain ) ,
" MACHINEPASS_B64 " : b64encode ( machinepass ) ,
" DNSPASS_B64 " : b64encode ( dnspass ) ,
" REALM " : realm ,
" DOMAIN " : domainname ,
" HOSTGUID_ADD " : hostguid_add ,
" DNSDOMAIN " : dnsdomain } )
setup_add_ldif ( samdb , setup_path ( " provision_group_policy.ldif " ) , {
" POLICYGUID " : policyguid ,
" DNSDOMAIN " : dnsdomain ,
" DOMAINSID " : str ( domainsid ) ,
" DOMAINDN " : domaindn } )
2007-12-22 09:47:36 +03:00
def setup_samdb ( path , setup_path , session_info , credentials , lp ,
schemadn , configdn , domaindn , dnsdomain , realm ,
netbiosname , message , hostname , rootdn , erase ,
2008-01-25 03:02:13 +03:00
domainsid , aci , domainguid , policyguid ,
domainname , fill , adminpass , krbtgtpass ,
machinepass , hostguid , invocationid , dnspass ,
serverrole , ldap_backend = None , ldap_backend_type = None ) :
""" Setup a complete SAM Database.
"""
2007-12-18 19:21:13 +03:00
2008-01-25 03:02:13 +03:00
# Also wipes the database
setup_samdb_partitions ( path , setup_path , schemadn = schemadn , configdn = configdn ,
domaindn = domaindn , message = message , lp = lp ,
credentials = credentials , session_info = session_info ,
hostname = hostname , netbiosname = netbiosname ,
dnsdomain = dnsdomain , realm = realm , rootdn = rootdn ,
ldap_backend = ldap_backend , serverrole = serverrole ,
ldap_backend_type = ldap_backend_type , erase = erase )
2007-12-10 11:29:00 +03:00
2007-12-22 09:47:36 +03:00
samdb = SamDB ( path , session_info = session_info ,
2007-12-18 04:21:14 +03:00
credentials = credentials , lp = lp )
2007-12-18 19:21:13 +03:00
2008-01-25 03:02:13 +03:00
if fill == FILL_DRS :
# We want to finish here, but setup the index before we do so
message ( " Setting up sam.ldb index " )
samdb . load_ldif_file_add ( setup_path ( " provision_index.ldif " ) )
return samdb
2007-12-10 11:29:00 +03:00
message ( " Pre-loading the Samba 4 and AD schema " )
2007-12-22 09:47:36 +03:00
samdb = SamDB ( path , session_info = session_info ,
2007-12-18 01:16:12 +03:00
credentials = credentials , lp = lp )
2007-12-20 01:27:24 +03:00
samdb . set_domain_sid ( domainsid )
2008-01-25 03:02:13 +03:00
if lp . get ( " server role " ) == " domain controller " :
samdb . set_invocation_id ( invocationid )
2007-12-20 01:27:38 +03:00
load_schema ( setup_path , samdb , schemadn , netbiosname , configdn )
2007-12-10 11:29:00 +03:00
samdb . transaction_start ( )
try :
2007-12-20 01:27:24 +03:00
message ( " Adding DomainDN: %s (permitted to fail) " % domaindn )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_basedn.ldif " ) , {
2007-12-20 01:27:24 +03:00
" DOMAINDN " : domaindn ,
" ACI " : aci ,
2007-12-18 19:21:13 +03:00
} )
2007-12-20 01:27:24 +03:00
message ( " Modifying DomainDN: " + domaindn + " " )
if domainguid is not None :
domainguid_mod = " replace: objectGUID \n objectGUID: %s \n - " % domainguid
2007-12-18 19:21:13 +03:00
else :
domainguid_mod = " "
2007-12-20 01:27:38 +03:00
setup_modify_ldif ( samdb , setup_path ( " provision_basedn_modify.ldif " ) , {
2007-12-18 19:21:13 +03:00
" LDAPTIME " : timestring ( int ( time . time ( ) ) ) ,
2007-12-20 01:27:24 +03:00
" DOMAINSID " : str ( domainsid ) ,
" SCHEMADN " : schemadn ,
" NETBIOSNAME " : netbiosname ,
" DEFAULTSITE " : DEFAULTSITE ,
" CONFIGDN " : configdn ,
" POLICYGUID " : policyguid ,
" DOMAINDN " : domaindn ,
2007-12-18 19:21:13 +03:00
" DOMAINGUID_MOD " : domainguid_mod ,
2007-12-18 19:21:24 +03:00
} )
2007-12-10 11:29:00 +03:00
message ( " Adding configuration container (permitted to fail) " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_configuration_basedn.ldif " ) , {
2007-12-20 01:27:24 +03:00
" CONFIGDN " : configdn ,
" ACI " : aci ,
2007-12-18 19:21:13 +03:00
" EXTENSIBLEOBJECT " : " # no objectClass: extensibleObject for local ldb " ,
} )
2007-12-10 11:29:00 +03:00
message ( " Modifying configuration container " )
2007-12-20 01:27:38 +03:00
setup_modify_ldif ( samdb , setup_path ( " provision_configuration_basedn_modify.ldif " ) , {
2007-12-20 01:27:24 +03:00
" CONFIGDN " : configdn ,
" SCHEMADN " : schemadn ,
2007-12-18 19:21:24 +03:00
} )
2007-12-10 11:29:00 +03:00
message ( " Adding schema container (permitted to fail) " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_schema_basedn.ldif " ) , {
2007-12-20 01:27:24 +03:00
" SCHEMADN " : schemadn ,
" ACI " : aci ,
2007-12-18 19:21:13 +03:00
" EXTENSIBLEOBJECT " : " # no objectClass: extensibleObject for local ldb "
} )
2007-12-10 11:29:00 +03:00
message ( " Modifying schema container " )
2008-01-25 03:02:13 +03:00
setup_modify_ldif ( samdb ,
setup_path ( " provision_schema_basedn_modify.ldif " ) , {
2007-12-20 01:27:24 +03:00
" SCHEMADN " : schemadn ,
" NETBIOSNAME " : netbiosname ,
" DEFAULTSITE " : DEFAULTSITE ,
" CONFIGDN " : configdn ,
2007-12-18 19:21:24 +03:00
} )
2007-12-18 19:21:13 +03:00
2007-12-10 11:29:00 +03:00
message ( " Setting up sam.ldb Samba4 schema " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " schema_samba4.ldif " ) ,
2007-12-20 01:27:24 +03:00
{ " SCHEMADN " : schemadn } )
2007-12-10 11:29:00 +03:00
message ( " Setting up sam.ldb AD schema " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " schema.ldif " ) ,
2007-12-20 01:27:24 +03:00
{ " SCHEMADN " : schemadn } )
2007-12-10 11:29:00 +03:00
message ( " Setting up sam.ldb configuration data " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_configuration.ldif " ) , {
2007-12-20 01:27:24 +03:00
" CONFIGDN " : configdn ,
" NETBIOSNAME " : netbiosname ,
" DEFAULTSITE " : DEFAULTSITE ,
" DNSDOMAIN " : dnsdomain ,
2007-12-22 09:47:36 +03:00
" DOMAIN " : domainname ,
2007-12-20 01:27:24 +03:00
" SCHEMADN " : schemadn ,
" DOMAINDN " : domaindn ,
2007-12-18 19:21:13 +03:00
} )
2007-12-10 11:29:00 +03:00
message ( " Setting up display specifiers " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " display_specifiers.ldif " ) ,
{ " CONFIGDN " : configdn } )
2007-12-10 11:29:00 +03:00
message ( " Adding users container (permitted to fail) " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_users_add.ldif " ) , {
2007-12-20 01:27:24 +03:00
" DOMAINDN " : domaindn } )
2007-12-10 11:29:00 +03:00
message ( " Modifying users container " )
2007-12-20 01:27:38 +03:00
setup_modify_ldif ( samdb , setup_path ( " provision_users_modify.ldif " ) , {
2007-12-20 01:27:24 +03:00
" DOMAINDN " : domaindn } )
2007-12-10 11:29:00 +03:00
message ( " Adding computers container (permitted to fail) " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_computers_add.ldif " ) , {
2007-12-20 01:27:24 +03:00
" DOMAINDN " : domaindn } )
2007-12-10 11:29:00 +03:00
message ( " Modifying computers container " )
2007-12-20 01:27:38 +03:00
setup_modify_ldif ( samdb , setup_path ( " provision_computers_modify.ldif " ) , {
2007-12-20 01:27:24 +03:00
" DOMAINDN " : domaindn } )
2007-12-10 11:29:00 +03:00
message ( " Setting up sam.ldb data " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision.ldif " ) , {
2007-12-20 01:27:24 +03:00
" DOMAINDN " : domaindn ,
" NETBIOSNAME " : netbiosname ,
" DEFAULTSITE " : DEFAULTSITE ,
" CONFIGDN " : configdn ,
2007-12-18 19:21:13 +03:00
} )
2007-12-10 11:29:00 +03:00
2008-01-25 03:02:13 +03:00
if fill == FILL_FULL :
2007-12-18 19:21:20 +03:00
message ( " Setting up sam.ldb users and groups " )
2007-12-20 01:27:38 +03:00
setup_add_ldif ( samdb , setup_path ( " provision_users.ldif " ) , {
2007-12-20 01:27:24 +03:00
" DOMAINDN " : domaindn ,
" DOMAINSID " : str ( domainsid ) ,
" CONFIGDN " : configdn ,
" ADMINPASS_B64 " : b64encode ( adminpass ) ,
" KRBTGTPASS_B64 " : b64encode ( krbtgtpass ) ,
2007-12-18 19:21:20 +03:00
} )
if lp . get ( " server role " ) == " domain controller " :
message ( " Setting up self join " )
2008-01-24 03:06:19 +03:00
setup_self_join ( samdb , configdn = configdn , schemadn = schemadn ,
domaindn = domaindn , invocationid = invocationid ,
dnspass = dnspass , netbiosname = netbiosname ,
dnsdomain = dnsdomain , realm = realm ,
machinepass = machinepass , domainname = domainname ,
domainsid = domainsid , policyguid = policyguid ,
hostname = hostname , hostguid = hostguid ,
setup_path = setup_path )
2007-12-20 01:27:24 +03:00
2008-01-25 03:02:13 +03:00
#We want to setup the index last, as adds are faster unindexed
2007-12-10 11:29:00 +03:00
message ( " Setting up sam.ldb index " )
2007-12-20 01:27:38 +03:00
samdb . load_ldif_file_add ( setup_path ( " provision_index.ldif " ) )
2007-12-10 11:29:00 +03:00
except :
samdb . transaction_cancel ( )
raise
samdb . transaction_commit ( )
2007-12-22 09:47:36 +03:00
return samdb
2008-01-25 03:02:13 +03:00
FILL_FULL = " FULL "
FILL_NT4SYNC = " NT4SYNC "
FILL_DRS = " DRS "
def provision ( lp , setup_dir , message , paths , session_info ,
credentials , ldapbackend , samdb_fill = FILL_FULL , realm = None , rootdn = None ,
domain = None , hostname = None , hostip = None , domainsid = None ,
hostguid = None , adminpass = None , krbtgtpass = None , domainguid = None ,
policyguid = None , invocationid = None , machinepass = None ,
dnspass = None , root = None , nobody = None , nogroup = None , users = None ,
wheel = None , backup = None , aci = None , serverrole = None , erase = False ,
ldap_backend = None , ldap_backend_type = None ) :
2007-12-22 09:47:36 +03:00
""" Provision samba4
: note : caution , this wipes all existing data !
"""
def setup_path ( file ) :
return os . path . join ( setup_dir , file )
if domainsid is None :
domainsid = security . random_sid ( )
if policyguid is None :
policyguid = uuid . random ( )
if adminpass is None :
adminpass = misc . random_password ( 12 )
if krbtgtpass is None :
krbtgtpass = misc . random_password ( 12 )
if machinepass is None :
machinepass = misc . random_password ( 12 )
if dnspass is None :
dnspass = misc . random_password ( 12 )
if root is None :
root = findnss ( pwd . getpwnam , " root " ) [ 4 ]
if nobody is None :
nobody = findnss ( pwd . getpwnam , " nobody " ) [ 4 ]
if nogroup is None :
nogroup = findnss ( grp . getgrnam , " nogroup " , " nobody " ) [ 2 ]
if users is None :
2007-12-30 03:14:15 +03:00
users = findnss ( grp . getgrnam , " users " , " guest " , " other " , " unknown " ,
" usr " ) [ 2 ]
2007-12-22 09:47:36 +03:00
if wheel is None :
wheel = findnss ( grp . getgrnam , " wheel " , " root " , " staff " , " adm " ) [ 2 ]
if backup is None :
backup = findnss ( grp . getgrnam , " backup " , " wheel " , " root " , " staff " ) [ 2 ]
if aci is None :
aci = " # no aci for local ldb "
if serverrole is None :
serverrole = lp . get ( " server role " )
2008-01-25 03:02:13 +03:00
if invocationid is None and serverrole == " domain controller " :
invocationid = uuid . random ( )
2007-12-22 09:47:36 +03:00
if realm is None :
realm = lp . get ( " realm " )
2008-01-25 03:02:13 +03:00
if lp . get ( " realm " ) . upper ( ) != realm . upper ( ) :
raise Exception ( " realm ' %s ' in smb.conf must match chosen realm ' %s ' " %
2007-12-22 09:47:36 +03:00
( lp . get ( " realm " ) , realm ) )
2008-01-25 03:02:13 +03:00
ldapi_url = " ldapi:// %s " % urllib . quote ( paths . s4_ldapi_path )
if ldap_backend == " ldapi " :
# provision-backend will set this path suggested slapd command line / fedorads.inf
2008-01-25 05:54:33 +03:00
ldap_backend = " ldapi:// " % urllib . quote ( os . path . join ( lp . get ( " private dir " ) , " ldap " , " ldapi " ) , " " )
2008-01-25 03:02:13 +03:00
2007-12-22 09:47:36 +03:00
assert realm is not None
realm = realm . upper ( )
if hostname is None :
hostname = gethostname ( ) . split ( " . " ) [ 0 ] . lower ( )
if hostip is None :
hostip = gethostbyname ( hostname )
netbiosname = hostname . upper ( )
if not valid_netbios_name ( netbiosname ) :
raise InvalidNetbiosName ( netbiosname )
dnsdomain = realm . lower ( )
2008-01-25 03:02:13 +03:00
if serverrole == " domain controller " :
domaindn = " DC= " + dnsdomain . replace ( " . " , " ,DC= " )
if domain is None :
domain = lp . get ( " workgroup " )
if lp . get ( " workgroup " ) . upper ( ) != domain . upper ( ) :
raise Error ( " workgroup ' %s ' in smb.conf must match chosen domain ' %s ' " ,
lp . get ( " workgroup " ) , domain )
assert domain is not None
domain = domain . upper ( )
if not valid_netbios_name ( domain ) :
raise InvalidNetbiosName ( domain )
else :
domaindn = " CN= " + netbiosname
domain = netbiosname
if rootdn is None :
rootdn = domaindn
2007-12-22 09:47:36 +03:00
configdn = " CN=Configuration, " + rootdn
schemadn = " CN=Schema, " + configdn
message ( " set DOMAIN SID: %s " % str ( domainsid ) )
message ( " Provisioning for %s in realm %s " % ( domain , realm ) )
message ( " Using administrator password: %s " % adminpass )
assert paths . smbconf is not None
# only install a new smb.conf if there isn't one there already
if not os . path . exists ( paths . smbconf ) :
message ( " Setting up smb.conf " )
if serverrole == " domain controller " :
smbconfsuffix = " dc "
elif serverrole == " member " :
smbconfsuffix = " member "
else :
assert " Invalid server role setting: %s " % serverrole
2008-01-25 03:02:13 +03:00
setup_file ( setup_path ( " provision.smb.conf. %s " % smbconfsuffix ) ,
paths . smbconf , {
2007-12-22 09:47:36 +03:00
" HOSTNAME " : hostname ,
" DOMAIN_CONF " : domain ,
" REALM_CONF " : realm ,
" SERVERROLE " : serverrole ,
" NETLOGONPATH " : paths . netlogon ,
" SYSVOLPATH " : paths . sysvol ,
} )
lp . reload ( )
# only install a new shares config db if there is none
if not os . path . exists ( paths . shareconf ) :
message ( " Setting up share.ldb " )
share_ldb = Ldb ( paths . shareconf , session_info = session_info ,
credentials = credentials , lp = lp )
share_ldb . load_ldif_file_add ( setup_path ( " share.ldif " ) )
2008-01-25 03:02:13 +03:00
2007-12-22 09:47:36 +03:00
message ( " Setting up secrets.ldb " )
secrets_ldb = setup_secretsdb ( paths . secrets , setup_path ,
session_info = session_info ,
credentials = credentials , lp = lp )
message ( " Setting up the registry " )
2007-12-22 14:02:57 +03:00
setup_registry ( paths . hklm , setup_path , session_info ,
credentials = credentials , lp = lp )
2007-12-22 09:47:36 +03:00
message ( " Setting up templates db " )
setup_templatesdb ( paths . templates , setup_path , session_info = session_info ,
credentials = credentials , lp = lp )
2008-01-25 03:02:13 +03:00
samdb = setup_samdb ( paths . samdb , setup_path , session_info = session_info ,
credentials = credentials , lp = lp , schemadn = schemadn ,
configdn = configdn , domaindn = domaindn ,
dnsdomain = dnsdomain , netbiosname = netbiosname ,
realm = realm , message = message , hostname = hostname ,
rootdn = rootdn , erase = erase , domainsid = domainsid ,
aci = aci , domainguid = domainguid , policyguid = policyguid ,
domainname = domain , fill = samdb_fill ,
adminpass = adminpass , krbtgtpass = krbtgtpass ,
hostguid = hostguid , invocationid = invocationid ,
machinepass = machinepass , dnspass = dnspass ,
serverrole = serverrole , ldap_backend = ldap_backend ,
ldap_backend_type = ldap_backend_type )
2007-12-22 09:47:36 +03:00
if lp . get ( " server role " ) == " domain controller " :
2008-01-25 03:02:13 +03:00
policy_path = os . path . join ( paths . sysvol , dnsdomain , " Policies " ,
" { " + policyguid + " } " )
os . makedirs ( policy_path , 0755 )
os . makedirs ( os . path . join ( policy_path , " Machine " ) , 0755 )
os . makedirs ( os . path . join ( policy_path , " User " ) , 0755 )
if not os . path . isdir ( paths . netlogon ) :
2007-12-22 09:47:36 +03:00
os . makedirs ( paths . netlogon , 0755 )
2008-01-25 03:02:13 +03:00
secrets_ldb = Ldb ( paths . secrets , session_info = session_info ,
credentials = credentials , lp = lp )
secretsdb_become_dc ( secrets_ldb , setup_path , domain = domain , realm = realm ,
netbiosname = netbiosname , domainsid = domainsid ,
keytab_path = paths . keytab , samdb_url = paths . samdb ,
dns_keytab_path = paths . dns_keytab , dnspass = dnspass ,
machinepass = machinepass , dnsdomain = dnsdomain )
if samdb_fill == FILL_FULL :
setup_name_mappings ( samdb , str ( domainsid ) , domaindn , root = root ,
nobody = nobody , nogroup = nogroup , wheel = wheel ,
users = users , backup = backup )
message ( " Setting up sam.ldb rootDSE marking as synchronized " )
setup_modify_ldif ( samdb , setup_path ( " provision_rootdse_modify.ldif " ) )
2007-12-10 11:29:00 +03:00
message ( " Setting up phpLDAPadmin configuration " )
2008-01-25 03:02:13 +03:00
create_phpldapadmin_config ( paths . phpldapadminconfig , setup_path ,
ldapi_url )
2007-12-18 19:21:13 +03:00
2007-12-10 11:29:00 +03:00
message ( " Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php " % paths . phpldapadminconfig )
2007-12-22 14:11:21 +03:00
if lp . get ( " server role " ) == " domain controller " :
samdb = SamDB ( paths . samdb , session_info = session_info ,
credentials = credentials , lp = lp )
2007-12-20 17:53:56 +03:00
2008-01-25 05:54:33 +03:00
domainguid = samdb . searchone ( basedn = domaindn , attribute = " objectGUID " )
2007-12-22 14:11:21 +03:00
assert isinstance ( domainguid , str )
2008-01-25 05:54:33 +03:00
hostguid = samdb . searchone ( basedn = domaindn , attribute = " objectGUID " ,
2007-12-22 14:11:21 +03:00
expression = " (&(objectClass=computer)(cn= %s )) " % hostname ,
scope = SCOPE_SUBTREE )
assert isinstance ( hostguid , str )
2007-12-20 17:53:56 +03:00
2007-12-22 11:26:38 +03:00
message ( " Setting up DNS zone: %s " % dnsdomain )
create_zone_file ( paths . dns , setup_path , samdb ,
hostname = hostname , hostip = hostip , dnsdomain = dnsdomain ,
domaindn = domaindn , dnspass = dnspass , realm = realm ,
domainguid = domainguid , hostguid = hostguid )
message ( " Please install the zone located in %s into your DNS server " % paths . dns )
2007-12-10 11:29:00 +03:00
2007-12-27 12:09:49 +03:00
return domaindn
2008-01-25 03:02:13 +03:00
2008-01-25 05:54:33 +03:00
def create_phpldapadmin_config ( path , setup_path , ldapi_uri ) :
2007-12-30 03:14:15 +03:00
""" Create a PHP LDAP admin configuration file.
: param path : Path to write the configuration to .
: param setup_path : Function to generate setup paths .
"""
2008-01-25 03:02:13 +03:00
setup_file ( setup_path ( " phpldapadmin-config.php " ) , path ,
2008-01-25 05:54:33 +03:00
{ " S4_LDAPI_URI " : ldapi_uri } )
2007-12-18 19:21:13 +03:00
2007-12-20 01:27:38 +03:00
def create_zone_file ( path , setup_path , samdb , dnsdomain , domaindn ,
2007-12-20 17:53:56 +03:00
hostip , hostname , dnspass , realm , domainguid , hostguid ) :
2007-12-30 03:14:15 +03:00
""" Write out a DNS zone file, from the info in the current database.
: param path : Path of the new file .
: param setup_path " : Setup path function.
: param samdb : SamDB object
: param dnsdomain : DNS Domain name
: param domaindn : DN of the Domain
: param hostip : Local IP
: param hostname : Local hostname
: param dnspass : Password for DNS
: param realm : Realm name
: param domainguid : GUID of the domain .
: param hostguid : GUID of the host .
"""
2008-01-25 05:54:33 +03:00
assert isinstance ( domainguid , str )
2007-12-20 01:27:24 +03:00
2007-12-20 01:27:38 +03:00
setup_file ( setup_path ( " provision.zone " ) , path , {
2007-12-20 01:27:24 +03:00
" DNSPASS_B64 " : b64encode ( dnspass ) ,
" HOSTNAME " : hostname ,
" DNSDOMAIN " : dnsdomain ,
" REALM " : realm ,
" HOSTIP " : hostip ,
2007-12-18 19:21:13 +03:00
" DOMAINGUID " : domainguid ,
" DATESTRING " : time . strftime ( " % Y % m %d % H " ) ,
2007-12-20 01:27:24 +03:00
" DEFAULTSITE " : DEFAULTSITE ,
2007-12-18 19:21:13 +03:00
" HOSTGUID " : hostguid ,
} )
2007-12-10 11:29:00 +03:00
2007-12-20 01:27:38 +03:00
def load_schema ( setup_path , samdb , schemadn , netbiosname , configdn ) :
2007-12-30 03:14:15 +03:00
""" Load schema.
: param samdb : Load a schema into a SamDB .
: param setup_path : Setup path function .
: param schemadn : DN of the schema
: param netbiosname : NetBIOS name of the host .
: param configdn : DN of the configuration
"""
2007-12-20 01:27:38 +03:00
schema_data = open ( setup_path ( " schema.ldif " ) , ' r ' ) . read ( )
schema_data + = open ( setup_path ( " schema_samba4.ldif " ) , ' r ' ) . read ( )
2007-12-20 01:27:24 +03:00
schema_data = substitute_var ( schema_data , { " SCHEMADN " : schemadn } )
2007-12-20 01:27:38 +03:00
head_data = open ( setup_path ( " provision_schema_basedn_modify.ldif " ) , ' r ' ) . read ( )
2007-12-18 19:21:13 +03:00
head_data = substitute_var ( head_data , {
2007-12-20 01:27:24 +03:00
" SCHEMADN " : schemadn ,
" NETBIOSNAME " : netbiosname ,
" CONFIGDN " : configdn ,
2008-01-25 03:02:13 +03:00
" DEFAULTSITE " : DEFAULTSITE
} )
2007-12-17 14:07:51 +03:00
samdb . attach_schema_from_ldif ( head_data , schema_data )
2007-12-10 11:29:00 +03:00