[PATCH] s4 - SID allocation using FDS DNA plugin

Endi S. Dewata edewata at redhat.com
Wed Oct 28 14:28:31 MDT 2009


---
 selftest/target/Samba4.pm                   |   14 +++++++++-
 source4/dsdb/samdb/ldb_modules/samldb.c     |   29 +++++++++++++-------
 source4/param/loadparm.c                    |    8 +++++
 source4/param/param.h                       |    6 ++++
 source4/scripting/python/samba/provision.py |   39 ++++++++++++++++++++++-----
 source4/setup/fedorads-dna.ldif             |   18 ++++++++++++
 source4/setup/fedorads-samba.ldif           |   10 +++++++
 source4/setup/fedorads.inf                  |    1 +
 source4/setup/provision.smb.conf.dc         |    1 +
 source4/setup/provision.smb.conf.member     |    1 +
 source4/setup/provision.smb.conf.standalone |    1 +
 11 files changed, 110 insertions(+), 18 deletions(-)
 create mode 100644 source4/setup/fedorads-dna.ldif

diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 3c0c4f5..c6ac17e 100644
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -471,6 +471,7 @@ sub provision_raw_prepare($$$$$$$)
 	$ctx->{realm} = "SAMBA.EXAMPLE.COM";
 	$ctx->{dnsname} = "samba.example.com";
 	$ctx->{basedn} = "dc=samba,dc=example,dc=com";
+	$ctx->{sid_generator} = "internal";
 
 	my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
 	chomp $unix_name;
@@ -578,7 +579,14 @@ sub provision_raw_step1($$)
 #We don't want to pass our self-tests if the PAC code is wrong
 	gensec:require_pac = true
 	log level = $ctx->{server_loglevel}
-	lanman auth = Yes
+	lanman auth = Yes";
+
+	if (defined($ctx->{sid_generator}) && $ctx->{sid_generator} ne "internal") {
+		print CONFFILE "
+	sid generator = $ctx->{sid_generator}";
+        }
+
+	print CONFFILE "
 
 	# Begin extra options
 	$ctx->{smb_conf_extra_options}
@@ -778,6 +786,10 @@ sub provision($$$$$$$)
 		$ldap_uri =~ s|/|%2F|g;
 		$ldap_uri = "ldapi://$ldap_uri";
 		$ctx->{ldap_uri} = $ldap_uri;
+
+                if ($self->{ldap} eq "fedora-ds") {
+			$ctx->{sid_generator} = "backend";
+		}
 	}
 
 	my $ret = $self->provision_raw_step1($ctx);
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 2a0bb2d..0f314b2 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -37,6 +37,7 @@
 #include "librpc/gen_ndr/ndr_security.h"
 #include "../lib/util/util_ldb.h"
 #include "ldb_wrap.h"
+#include "param/param.h"
 
 struct samldb_ctx;
 
@@ -923,6 +924,8 @@ static int samldb_add_entry(struct samldb_ctx *ac)
 static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 {
 	struct ldb_context *ldb;
+	struct loadparm_context *lp_ctx;
+	enum sid_generator sid_generator;
 	int ret;
 
 	ldb = ldb_module_get_ctx(ac->module);
@@ -997,19 +1000,25 @@ static int samldb_fill_object(struct samldb_ctx *ac, const char *type)
 		if (ret != LDB_SUCCESS) return ret;
 	}
 
-	/* check if we have a valid SID */
-	ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
-	if ( ! ac->sid) {
-		ret = samldb_add_step(ac, samldb_new_sid);
-		if (ret != LDB_SUCCESS) return ret;
-	} else {
-		ret = samldb_add_step(ac, samldb_get_sid_domain);
+	lp_ctx = talloc_get_type(ldb_get_opaque(ldb, "loadparm"),
+		 struct loadparm_context);
+
+	sid_generator = lp_sid_generator(lp_ctx);
+	if (sid_generator == SID_GENERATOR_INTERNAL) {
+		/* check if we have a valid SID */
+		ac->sid = samdb_result_dom_sid(ac, ac->msg, "objectSid");
+		if ( ! ac->sid) {
+			ret = samldb_add_step(ac, samldb_new_sid);
+			if (ret != LDB_SUCCESS) return ret;
+		} else {
+			ret = samldb_add_step(ac, samldb_get_sid_domain);
+			if (ret != LDB_SUCCESS) return ret;
+		}
+
+		ret = samldb_add_step(ac, samldb_notice_sid);
 		if (ret != LDB_SUCCESS) return ret;
 	}
 
-	ret = samldb_add_step(ac, samldb_notice_sid);
-	if (ret != LDB_SUCCESS) return ret;
-
 	/* finally proceed with adding the entry */
 	ret = samldb_add_step(ac, samldb_add_entry);
 	if (ret != LDB_SUCCESS) return ret;
diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c
index 882de13..b400b25 100644
--- a/source4/param/loadparm.c
+++ b/source4/param/loadparm.c
@@ -79,6 +79,7 @@ static bool defaults_saved = false;
 struct loadparm_global
 {
 	enum server_role server_role;
+	enum sid_generator sid_generator;
 
 	const char **smb_ports;
 	char *ncalrpc_dir;
@@ -328,12 +329,18 @@ static const struct enum_list enum_server_role[] = {
 	{-1, NULL}
 };
 
+static const struct enum_list enum_sid_generator[] = {
+	{SID_GENERATOR_INTERNAL, "internal"},
+	{SID_GENERATOR_BACKEND, "backend"},
+	{-1, NULL}
+};
 
 #define GLOBAL_VAR(name) offsetof(struct loadparm_global, name)
 #define LOCAL_VAR(name) offsetof(struct loadparm_service, name)
 
 static struct parm_struct parm_table[] = {
 	{"server role", P_ENUM, P_GLOBAL, GLOBAL_VAR(server_role), NULL, enum_server_role},
+	{"sid generator", P_ENUM, P_GLOBAL, GLOBAL_VAR(sid_generator), NULL, enum_sid_generator},
 
 	{"dos charset", P_STRING, P_GLOBAL, GLOBAL_VAR(dos_charset), NULL, NULL},
 	{"unix charset", P_STRING, P_GLOBAL, GLOBAL_VAR(unix_charset), NULL, NULL},
@@ -612,6 +619,7 @@ static const char *lp_string(const char *s)
  int fn_name(struct loadparm_service *service, struct loadparm_service *sDefault) {return((service != NULL)? service->val : sDefault->val);}
 
 _PUBLIC_ FN_GLOBAL_INTEGER(lp_server_role, server_role)
+_PUBLIC_ FN_GLOBAL_INTEGER(lp_sid_generator, sid_generator)
 _PUBLIC_ FN_GLOBAL_LIST(lp_smb_ports, smb_ports)
 _PUBLIC_ FN_GLOBAL_INTEGER(lp_nbt_port, nbt_port)
 _PUBLIC_ FN_GLOBAL_INTEGER(lp_dgram_port, dgram_port)
diff --git a/source4/param/param.h b/source4/param/param.h
index 0c8e73e..3ce5e93 100644
--- a/source4/param/param.h
+++ b/source4/param/param.h
@@ -51,6 +51,11 @@ enum server_role {
 	ROLE_DOMAIN_CONTROLLER=2,
 };
 
+enum sid_generator {
+	SID_GENERATOR_INTERNAL=0,
+	SID_GENERATOR_BACKEND=1,
+};
+
 enum announce_as {/* Types of machine we can announce as. */
 	ANNOUNCE_AS_NT_SERVER=1,
 	ANNOUNCE_AS_WIN95=2,
@@ -69,6 +74,7 @@ void reload_charcnv(struct loadparm_context *lp_ctx);
 struct loadparm_service *lp_default_service(struct loadparm_context *lp_ctx);
 struct parm_struct *lp_parm_table(void);
 int lp_server_role(struct loadparm_context *);
+int lp_sid_generator(struct loadparm_context *);
 const char **lp_smb_ports(struct loadparm_context *);
 int lp_nbt_port(struct loadparm_context *);
 int lp_dgram_port(struct loadparm_context *);
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 18a311a..08f5e0b 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -144,6 +144,7 @@ class ProvisionPaths(object):
         self.fedoradsinf = None
         self.fedoradspartitions = None
         self.fedoradssasl = None
+        self.fedoradsdna = None
         self.fedoradspam = None
         self.fedoradsrefint = None
         self.fedoradslinkedattributes = None
@@ -394,8 +395,10 @@ def provision_paths_from_lp(lp, dnsdomain):
                                             "fedorads-partitions.ldif")
     paths.fedoradssasl = os.path.join(paths.ldapdir, 
                                       "fedorads-sasl.ldif")
+    paths.fedoradsdna = os.path.join(paths.ldapdir, 
+                                     "fedorads-dna.ldif")
     paths.fedoradspam = os.path.join(paths.ldapdir,
-                                      "fedorads-pam.ldif")
+                                     "fedorads-pam.ldif")
     paths.fedoradsrefint = os.path.join(paths.ldapdir,
                                         "fedorads-refint.ldif")
     paths.fedoradslinkedattributes = os.path.join(paths.ldapdir,
@@ -515,7 +518,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
     
 
 def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, 
-                 targetdir):
+                 targetdir, sid_generator):
     """Create a new smb.conf file based on a couple of basic settings.
     """
     assert smbconf is not None
@@ -533,6 +536,9 @@ def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,
     elif serverrole == "standalone":
         smbconfsuffix = "standalone"
 
+    if sid_generator is None:
+        sid_generator = "internal"
+
     assert domain is not None
     assert realm is not None
 
@@ -550,6 +556,11 @@ def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,
         privatedir_line = ""
         lockdir_line = ""
 
+    if sid_generator == "internal":
+        sid_generator_line = ""
+    else:
+        sid_generator_line = "sid generator = " + sid_generator
+
     sysvol = os.path.join(default_lp.get("lock dir"), "sysvol")
     netlogon = os.path.join(sysvol, realm.lower(), "scripts")
 
@@ -561,6 +572,7 @@ def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,
             "SERVERROLE": serverrole,
             "NETLOGONPATH": netlogon,
             "SYSVOLPATH": sysvol,
+            "SIDGENERATOR_LINE": sid_generator_line,
             "PRIVATEDIR_LINE": privatedir_line,
             "LOCKDIR_LINE": lockdir_line
             })
@@ -1221,6 +1233,9 @@ def provision(setup_dir, message, session_info,
         #Make a new, random password between Samba and it's LDAP server
         ldapadminpass=glue.generate_random_str(12)        
 
+    sid_generator = "internal"
+    if ldap_backend_type == "fedora-ds":
+        sid_generator = "backend"
 
     root_uid = findnss_uid([root or "root"])
     nobody_uid = findnss_uid([nobody or "nobody"])
@@ -1240,7 +1255,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)
+                     targetdir, sid_generator)
 
     lp = param.LoadParm()
     lp.load(smbconf)
@@ -1295,7 +1310,8 @@ def provision(setup_dir, message, session_info,
                                              ol_mmr_urls=ol_mmr_urls, 
                                              slapd_path=slapd_path,
                                              setup_ds_path=setup_ds_path,
-                                             ldap_dryrun_mode=ldap_dryrun_mode)
+                                             ldap_dryrun_mode=ldap_dryrun_mode,
+                                             domainsid=domainsid)
 
         # Now use the backend credentials to access the databases
         credentials = provision_backend.credentials
@@ -1552,7 +1568,8 @@ class ProvisionBackend(object):
                  ldap_backend_type=None, ldap_backend_extra_port=None,
                  ol_mmr_urls=None, 
                  setup_ds_path=None, slapd_path=None, 
-                 nosync=False, ldap_dryrun_mode=False):
+                 nosync=False, ldap_dryrun_mode=False,
+                 domainsid=None):
         """Provision an LDAP backend for samba4
         
         This works for OpenLDAP and Fedora DS
@@ -1643,7 +1660,8 @@ class ProvisionBackend(object):
                                   setup_ds_path=setup_ds_path,
                                   slapd_path=slapd_path,
                                   nosync=nosync,
-                                  ldap_dryrun_mode=ldap_dryrun_mode)
+                                  ldap_dryrun_mode=ldap_dryrun_mode,
+                                  domainsid=domainsid)
             
         elif ldap_backend_type == "openldap":
             provision_openldap_backend(self, paths=paths, setup_path=setup_path,
@@ -1920,7 +1938,8 @@ def provision_fds_backend(result, paths=None, setup_path=None, names=None,
                           setup_ds_path=None,
                           slapd_path=None,
                           nosync=False, 
-                          ldap_dryrun_mode=False):
+                          ldap_dryrun_mode=False,
+                          domainsid=None):
 
     if ldap_backend_extra_port is not None:
         serverport = "ServerPort=%d" % ldap_backend_extra_port
@@ -1947,6 +1966,12 @@ def provision_fds_backend(result, paths=None, setup_path=None, names=None,
                {"SAMBADN": names.sambadn,
                 })
 
+    setup_file(setup_path("fedorads-dna.ldif"), paths.fedoradsdna, 
+               {"DOMAINDN": names.domaindn,
+                "SAMBADN": names.sambadn,
+                "DOMAINSID": str(domainsid),
+                })
+
     setup_file(setup_path("fedorads-pam.ldif"), paths.fedoradspam)
 
     lnkattr = get_linked_attributes(names.schemadn,schema.ldb)
diff --git a/source4/setup/fedorads-dna.ldif b/source4/setup/fedorads-dna.ldif
new file mode 100644
index 0000000..f9785f3
--- /dev/null
+++ b/source4/setup/fedorads-dna.ldif
@@ -0,0 +1,18 @@
+dn: cn=Samba SIDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
+objectClass: top
+objectClass: extensibleObject
+cn: Samba SIDs
+dnaType: sambaSID
+dnaMaxValue: 10000
+dnaMagicRegen: 0
+dnaFilter: (|(objectClass=user)(objectClass=group))
+dnaScope: ${DOMAINDN}
+dnaNextValue: 1000
+dnaSharedCfgDn: cn=Samba SIDs,ou=Ranges,${SAMBADN}
+dnaPrefix: ${DOMAINSID}-
+
+dn: cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
+changetype: modify
+replace: nsslapd-pluginEnabled
+nsslapd-pluginEnabled: on
+-
diff --git a/source4/setup/fedorads-samba.ldif b/source4/setup/fedorads-samba.ldif
index cc0faf2..2bcf35b 100644
--- a/source4/setup/fedorads-samba.ldif
+++ b/source4/setup/fedorads-samba.ldif
@@ -9,3 +9,13 @@ objectClass: person
 cn: samba-admin
 sn: samba-admin
 userPassword: {CLEAR}${LDAPADMINPASS}
+
+dn: ou=Ranges,${SAMBADN}
+objectClass: top
+objectClass: organizationalUnit
+ou: Ranges
+
+dn: cn=Samba SIDs,ou=Ranges,${SAMBADN}
+objectClass: top
+objectClass: nsContainer
+cn: Samba SIDs
diff --git a/source4/setup/fedorads.inf b/source4/setup/fedorads.inf
index 9653f50..e93913c 100644
--- a/source4/setup/fedorads.inf
+++ b/source4/setup/fedorads.inf
@@ -33,6 +33,7 @@ SchemaFile=/etc/dirsrv/schema/06inetorgperson.ldif
 SchemaFile=/usr/share/dirsrv/data/60samba3.ldif
 ConfigFile = ${LDAPDIR}/fedorads-partitions.ldif
 ConfigFile = ${LDAPDIR}/fedorads-sasl.ldif
+ConfigFile = ${LDAPDIR}/fedorads-dna.ldif
 ConfigFile = ${LDAPDIR}/fedorads-pam.ldif
 ConfigFile = ${LDAPDIR}/fedorads-refint.ldif
 ConfigFile = ${LDAPDIR}/fedorads-linked-attributes.ldif
diff --git a/source4/setup/provision.smb.conf.dc b/source4/setup/provision.smb.conf.dc
index ad06be4..5fa65e8 100644
--- a/source4/setup/provision.smb.conf.dc
+++ b/source4/setup/provision.smb.conf.dc
@@ -3,6 +3,7 @@
 	workgroup	= ${DOMAIN}
 	realm		= ${REALM}
 	server role     = ${SERVERROLE}
+	${SIDGENERATOR_LINE}
 	${PRIVATEDIR_LINE}
 	${LOCKDIR_LINE}
 
diff --git a/source4/setup/provision.smb.conf.member b/source4/setup/provision.smb.conf.member
index 0d742fb..03f72c3 100644
--- a/source4/setup/provision.smb.conf.member
+++ b/source4/setup/provision.smb.conf.member
@@ -3,5 +3,6 @@
 	workgroup	= ${DOMAIN}
 	realm		= ${REALM}
 	server role     = ${SERVERROLE}
+	${SIDGENERATOR_LINE}
 	${PRIVATEDIR_LINE}
 	${LOCKDIR_LINE}
diff --git a/source4/setup/provision.smb.conf.standalone b/source4/setup/provision.smb.conf.standalone
index 0d742fb..03f72c3 100644
--- a/source4/setup/provision.smb.conf.standalone
+++ b/source4/setup/provision.smb.conf.standalone
@@ -3,5 +3,6 @@
 	workgroup	= ${DOMAIN}
 	realm		= ${REALM}
 	server role     = ${SERVERROLE}
+	${SIDGENERATOR_LINE}
 	${PRIVATEDIR_LINE}
 	${LOCKDIR_LINE}
-- 
1.6.0.6


------=_Part_50362_992392124.1256763631872--


More information about the samba-technical mailing list