[PATCH 13/18] provision: introduce use-xattr parameter for defining where to store attributes

Matthieu Patou mat at matws.net
Fri Jan 8 07:00:54 MST 2010


  This option allow simple user (non root) to invoke provision without facing an error
  while insuring that ACL on shared files will always be set
---
 source4/scripting/python/samba/provision.py |   59 ++++++++++++++++-----------
 source4/setup/provision                     |   27 +++++++++---
 source4/setup/provision.smb.conf.dc         |    1 +
 source4/setup/provision.smb.conf.member     |    1 +
 source4/setup/provision.smb.conf.standalone |    1 +
 5 files changed, 59 insertions(+), 30 deletions(-)

diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 0da494d..7fddc09 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -47,7 +47,7 @@ from samba import DS_DOMAIN_FUNCTION_2003, DS_DOMAIN_FUNCTION_2008, DS_DC_FUNCTI
 from samba.samdb import SamDB
 from samba.idmap import IDmapDB
 from samba.dcerpc import security
-from samba.misc import setntacl,dsacl2fsacl
+from samba.ntacls import setntacl,dsacl2fsacl
 from samba.ndr import ndr_pack,ndr_unpack
 import urllib
 from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError
@@ -435,7 +435,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
     
 
 def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, 
-                 targetdir, sid_generator):
+                 targetdir, sid_generator,eadb):
     """Create a new smb.conf file based on a couple of basic settings.
     """
     assert smbconf is not None
@@ -467,7 +467,11 @@ def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,
     #Load non-existant file
     if os.path.exists(smbconf):
         default_lp.load(smbconf)
-    
+    if eadb:
+        posixeadb_line = "posix:eadb = " + os.path.abspath(os.path.join(os.path.join(targetdir, "private"),"eadb.tdb"))
+    else:
+        posixeadb_line = ""
+
     if targetdir is not None:
         privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private"))
         lockdir_line = "lock dir = " + os.path.abspath(targetdir)
@@ -495,7 +499,8 @@ def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,
             "SYSVOLPATH": sysvol,
             "SIDGENERATOR_LINE": sid_generator_line,
             "PRIVATEDIR_LINE": privatedir_line,
-            "LOCKDIR_LINE": lockdir_line
+            "LOCKDIR_LINE": lockdir_line,
+			"POSIXEADB_LINE": posixeadb_line
             })
 
 
@@ -1056,30 +1061,37 @@ FILL_DRS = "DRS"
 SYSVOL_ACL = "O:${DOMAINSID}-500G:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;S-1-5-32-549)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)"
 POLICIES_ACL = "O:${DOMAINSID}-500G:BAD:P(A;OICI;0x001f01ff;;;BA)(A;OICI;0x001200a9;;;S-1-5-32-549)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)(A;OICI;0x001301bf;;;${DOMAINSID}-520)"
 
-def set_gpo_acl(path,acl):
-	setntacl(path,acl)
+def set_gpo_acl(path,acl,lp):
+	setntacl(lp,path,acl)
 	for root, dirs, files in os.walk(path, topdown=False):
 		for name in files:
-			setntacl(os.path.join(root, name),acl)
+			setntacl(lp,os.path.join(root, name),acl)
 		for name in dirs:
-			setntacl(os.path.join(root, name),acl)
+			setntacl(lp,os.path.join(root, name),acl)
 
-def setdiracl(samdb,names,netlogon,sysvol,gid,domainsid):
+def setsysvolacl(samdb,names,netlogon,sysvol,gid,domainsid,lp):
+	canchown = 1
 	acl = SYSVOL_ACL.replace("${DOMAINSID}",str(domainsid))
-	os.chown(sysvol,-1,gid)
-	setntacl(sysvol,acl)
+	try:
+		os.chown(sysvol,-1,gid)
+	except:
+		canchown = 0
+
+	setntacl(lp,sysvol,acl)
 	for root, dirs, files in os.walk(sysvol, topdown=False):
 		for name in files:
-			os.chown(os.path.join(root, name),-1,gid)
-			setntacl(os.path.join(root, name),acl)
+			if canchown:
+				os.chown(os.path.join(root, name),-1,gid)
+			setntacl(lp,os.path.join(root, name),acl)
 		for name in dirs:
-			os.chown(os.path.join(root, name),-1,gid)
-			setntacl(os.path.join(root, name),acl)
+			if canchown:
+				os.chown(os.path.join(root, name),-1,gid)
+			setntacl(lp,os.path.join(root, name),acl)
 
 	# Set ACL for GPO
 	policy_path = os.path.join(sysvol, names.dnsdomain, "Policies")
 	acl = POLICIES_ACL.replace("${DOMAINSID}",str(domainsid))
-	set_gpo_acl(policy_path,dsacl2fsacl(acl))
+	set_gpo_acl(policy_path,dsacl2fsacl(acl),lp)
 	res = samdb.search(base="CN=Policies,CN=System,%s"%(names.domaindn),
 						attrs=["cn","nTSecurityDescriptor"],
 						expression="", scope=SCOPE_ONELEVEL)
@@ -1088,7 +1100,7 @@ def setdiracl(samdb,names,netlogon,sysvol,gid,domainsid):
 		acl = ndr_unpack(security.descriptor,str(policy["nTSecurityDescriptor"])).as_sddl()
 		policy_path = os.path.join(sysvol, names.dnsdomain, "Policies",
 									 str(policy["cn"]))
-		set_gpo_acl(policy_path,dsacl2fsacl(acl))
+		set_gpo_acl(policy_path,dsacl2fsacl(acl),lp)
 
 
 
@@ -1109,7 +1121,7 @@ def provision(setup_dir, message, session_info,
               sitename=None,
               ol_mmr_urls=None, ol_olc=None, 
               setup_ds_path=None, slapd_path=None, nosync=False,
-              ldap_dryrun_mode=False,setfileacl=False):
+              ldap_dryrun_mode=False,useeadb=False):
     """Provision samba4
     
     :note: caution, this wipes all existing data!
@@ -1168,7 +1180,7 @@ def provision(setup_dir, message, session_info,
     # only install a new smb.conf if there isn't one there already
     if not os.path.exists(smbconf):
         make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, 
-                     targetdir, sid_generator)
+                     targetdir, sid_generator,useeadb)
 
     lp = param.LoadParm()
     lp.load(smbconf)
@@ -1316,11 +1328,10 @@ def provision(setup_dir, message, session_info,
                             root_uid=root_uid, nobody_uid=nobody_uid,
                             users_gid=users_gid, wheel_gid=wheel_gid)
 
-        setup_gpo(paths,names,samdb,policyguid,policyguid_dc,domainsid)
-
-        if setfileacl:
-            setdiracl(samdb,names,paths.netlogon,paths.sysvol,wheel_gid,domainsid)
-        # Set up group policies (domain policy and domain controller policy)
+        if serverrole == "domain controller":
+            # Set up group policies (domain policy and domain controller policy)
+            setup_gpo(paths,names,samdb,policyguid,policyguid_dc,domainsid)
+            setsysvolacl(samdb,names,paths.netlogon,paths.sysvol,wheel_gid,domainsid,lp)
 
         message("Setting up sam.ldb rootDSE marking as synchronized")
         setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif"))
diff --git a/source4/setup/provision b/source4/setup/provision
index 1165eda..b77348c 100755
--- a/source4/setup/provision
+++ b/source4/setup/provision
@@ -24,11 +24,14 @@
 
 import optparse
 import sys
+import os
+import tempfile
 
 # Find right directory when running from source tree
 sys.path.insert(0, "bin/python")
 
 import samba
+import samba.ntacls
 from samba.credentials import DONT_USE_KERBEROS
 from samba.auth import system_session
 import samba.getopt as options
@@ -110,7 +113,7 @@ parser.add_option("--slapd-path", type="string", metavar="SLAPD-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.") 
 parser.add_option("--nosync", help="Configure LDAP backend not to call fsync() (for performance in test environments)", action="store_true")
-parser.add_option("--nosetfileacl", help="Do not set NT ACL on files (set by default)", 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("--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]
@@ -202,10 +205,22 @@ if opts.blank:
 elif opts.partitions_only:
     samdb_fill = FILL_DRS
 
-setfileacl = True
+if not opts.use_xattrs:
+	opts.use_xattrs="auto"
+
+eadb = False 
+if opts.use_xattrs == "yes":
+	eadb = False
+elif opts.use_xattrs == "auto":
+	file=tempfile.NamedTemporaryFile()
+	try:
+		samba.ntacls.setntacl(lp,file.name,"O:S-1-5-32G:S-1-5-32","native")
+	except:
+		eadb = True
+		print "Notice: you are not root or your system do not support xattr, tdb backend for attributes has been selected"
+		print " if you intend to use this provision in production you'd better rerun the script as root on a system supporting xattr"
+	file.close()
 
-if opts.nosetfileacl:
-	setfileacl = False
 
 session = system_session()
 provision(setup_dir, message, 
@@ -215,7 +230,7 @@ provision(setup_dir, message,
           policyguid=opts.policy_guid, policyguid_dc=opts.policy_guid_dc,
           hostname=opts.host_name,
           hostip=opts.host_ip, hostip6=opts.host_ip6,
-	  ntdsguid=opts.ntds_guid,
+          ntdsguid=opts.ntds_guid,
           invocationid=opts.invocationid, adminpass=opts.adminpass,
           krbtgtpass=opts.krbtgtpass, machinepass=opts.machinepass,
           dnspass=opts.dnspass, root=opts.root, nobody=opts.nobody,
@@ -225,4 +240,4 @@ provision(setup_dir, message,
           backend_type=opts.ldap_backend_type,
           ldapadminpass=opts.ldapadminpass, ol_mmr_urls=opts.ol_mmr_urls,
           slapd_path=opts.slapd_path, setup_ds_path=opts.setup_ds_path,
-          nosync=opts.nosync,ldap_dryrun_mode=opts.ldap_dryrun_mode,setfileacl=setfileacl)
+          nosync=opts.nosync,ldap_dryrun_mode=opts.ldap_dryrun_mode,useeadb=eadb)
diff --git a/source4/setup/provision.smb.conf.dc b/source4/setup/provision.smb.conf.dc
index a8e98ba..0449f75 100644
--- a/source4/setup/provision.smb.conf.dc
+++ b/source4/setup/provision.smb.conf.dc
@@ -6,6 +6,7 @@
 	${SIDGENERATOR_LINE}
 	${PRIVATEDIR_LINE}
 	${LOCKDIR_LINE}
+	${POSIXEADB_LINE}
 
 [netlogon]
 	path = ${NETLOGONPATH}
diff --git a/source4/setup/provision.smb.conf.member b/source4/setup/provision.smb.conf.member
index 8241fc2..4d32ef4 100644
--- a/source4/setup/provision.smb.conf.member
+++ b/source4/setup/provision.smb.conf.member
@@ -6,3 +6,4 @@
 	${SIDGENERATOR_LINE}
 	${PRIVATEDIR_LINE}
 	${LOCKDIR_LINE}
+	${POSIXEADB_LINE}
diff --git a/source4/setup/provision.smb.conf.standalone b/source4/setup/provision.smb.conf.standalone
index 8241fc2..4d32ef4 100644
--- a/source4/setup/provision.smb.conf.standalone
+++ b/source4/setup/provision.smb.conf.standalone
@@ -6,3 +6,4 @@
 	${SIDGENERATOR_LINE}
 	${PRIVATEDIR_LINE}
 	${LOCKDIR_LINE}
+	${POSIXEADB_LINE}
-- 
1.6.3.3


--------------080603070205020905060303
Content-Type: text/x-patch;
 name="0014-s4-allow-python-code-to-dump-NTACL-object-as-well.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename*0="0014-s4-allow-python-code-to-dump-NTACL-object-as-well.patch"



More information about the samba-technical mailing list