From e035433bab87cb5f2f12def900e194da877e6925 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Wed, 28 Oct 2009 15:28:31 -0500 Subject: [PATCH] s4 - SID allocation using FDS DNA plugin --- 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 db2793e36bf..f1788491978 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 2a0bb2dfe66..0f314b241a1 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 669e0d7d225..f2e4ace122c 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 0c8e73ecaa4..3ce5e93acf5 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 74d8562c9b3..6c00127bc66 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, @@ -517,7 +520,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 @@ -536,6 +539,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 domain = domain.upper() @@ -556,6 +562,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") @@ -567,6 +578,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 }) @@ -1248,6 +1260,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"]) @@ -1267,7 +1282,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) @@ -1322,7 +1337,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 @@ -1579,7 +1595,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 @@ -1670,7 +1687,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, @@ -1947,7 +1965,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 @@ -1974,6 +1993,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 00000000000..f9785f33648 --- /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 cc0faf29edb..2bcf35b9e5d 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 9653f50325b..e93913c70fa 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 f489f59ff9d..a8e98ba4bc9 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 96e5d0c2e5a..8241fc28f1c 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 96e5d0c2e5a..8241fc28f1c 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} -- 2.34.1