summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/lib/ldb/tools/ad2oLschema.c23
-rwxr-xr-xsource4/script/installmisc.sh2
-rw-r--r--source4/scripting/ejs/smbcalls_sys.c28
-rw-r--r--source4/scripting/libjs/provision.js54
-rw-r--r--source4/setup/fedorads-partitions.ldif28
-rw-r--r--source4/setup/fedorads.inf26
-rwxr-xr-xsource4/setup/provision-backend114
-rw-r--r--source4/setup/slapd.conf73
8 files changed, 344 insertions, 4 deletions
diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/lib/ldb/tools/ad2oLschema.c
index d04260103d..4cc07a52d8 100644
--- a/source4/lib/ldb/tools/ad2oLschema.c
+++ b/source4/lib/ldb/tools/ad2oLschema.c
@@ -195,9 +195,11 @@ static int fetch_objectclass_schema(struct ldb_context *ldb, struct ldb_dn *sche
static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ctx)
{
const char *rootdse_attrs[] = {"schemaNamingContext", NULL};
+ const char *no_attrs[] = { NULL };
struct ldb_dn *schemadn;
struct ldb_dn *basedn = ldb_dn_new(mem_ctx, ldb, NULL);
struct ldb_result *rootdse_res;
+ struct ldb_result *schema_res;
int ldb_ret;
if (!basedn) {
return NULL;
@@ -206,8 +208,25 @@ static struct ldb_dn *find_schema_dn(struct ldb_context *ldb, TALLOC_CTX *mem_ct
/* Search for rootdse */
ldb_ret = ldb_search(ldb, basedn, LDB_SCOPE_BASE, NULL, rootdse_attrs, &rootdse_res);
if (ldb_ret != LDB_SUCCESS) {
- printf("Search failed: %s\n", ldb_errstring(ldb));
- return NULL;
+ ldb_ret = ldb_search(ldb, basedn, LDB_SCOPE_SUBTREE,
+ "(&(objectClass=dMD)(cn=Schema))",
+ no_attrs, &schema_res);
+ if (ldb_ret) {
+ printf("cn=Schema Search failed: %s\n", ldb_errstring(ldb));
+ return NULL;
+ }
+
+ talloc_steal(mem_ctx, schema_res);
+
+ if (schema_res->count != 1) {
+ printf("Failed to find rootDSE");
+ return NULL;
+ }
+
+ schemadn = talloc_steal(mem_ctx, schema_res->msgs[0]->dn);
+ talloc_free(schema_res);
+ return schemadn;
+
}
talloc_steal(mem_ctx, rootdse_res);
diff --git a/source4/script/installmisc.sh b/source4/script/installmisc.sh
index 082a01eee9..a714783aec 100755
--- a/source4/script/installmisc.sh
+++ b/source4/script/installmisc.sh
@@ -14,6 +14,8 @@ cp scripting/libjs/*.js $JSDIR || exit 1
echo "Installing setup templates"
mkdir -p $SETUPDIR || exit 1
+cp setup/schema-map-* $SETUPDIR || exit 1
+cp setup/*.inf $SETUPDIR || exit 1
cp setup/*.ldif $SETUPDIR || exit 1
cp setup/*.zone $SETUPDIR || exit 1
cp setup/*.conf $SETUPDIR || exit 1
diff --git a/source4/scripting/ejs/smbcalls_sys.c b/source4/scripting/ejs/smbcalls_sys.c
index ce3f3f5a98..1b1affc80d 100644
--- a/source4/scripting/ejs/smbcalls_sys.c
+++ b/source4/scripting/ejs/smbcalls_sys.c
@@ -305,6 +305,33 @@ static int ejs_sys_file_save(MprVarHandle eid, int argc, char **argv)
return 0;
}
+/*
+ mkdir()
+ usage:
+ ok = sys.mkdir(dirname, mode);
+*/
+static int ejs_sys_mkdir(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+ BOOL ret;
+ char *name;
+ if (argc != 2) {
+ ejsSetErrorMsg(eid, "sys_mkdir invalid arguments, need mkdir(dirname, mode)");
+ return -1;
+ }
+ if (!mprVarIsString(argv[0]->type)) {
+ ejsSetErrorMsg(eid, "sys_mkdir dirname not a string");
+ return -1;
+ }
+ if (!mprVarIsNumber(argv[1]->type)) {
+ ejsSetErrorMsg(eid, "sys_mkdir mode not a number");
+ return -1;
+ }
+ mprVarToString(&name, 0, NULL, argv[0]);
+ ret = mkdir(name, mprVarToNumber(argv[1]));
+ mpr_Return(eid, mprCreateBoolVar(ret == 0));
+ return 0;
+}
+
/*
return fields of a stat() call
@@ -438,6 +465,7 @@ static int ejs_sys_init(MprVarHandle eid, int argc, struct MprVar **argv)
mprSetCFunction(obj, "ntgmtime", ejs_sys_ntgmtime);
mprSetCFunction(obj, "ldaptime", ejs_sys_ldaptime);
mprSetCFunction(obj, "httptime", ejs_sys_httptime);
+ mprSetCFunction(obj, "mkdir", ejs_sys_mkdir);
mprSetStringCFunction(obj, "unlink", ejs_sys_unlink);
mprSetStringCFunction(obj, "file_load", ejs_sys_file_load);
mprSetStringCFunction(obj, "file_save", ejs_sys_file_save);
diff --git a/source4/scripting/libjs/provision.js b/source4/scripting/libjs/provision.js
index d9bdb3b16b..d25c0f38eb 100644
--- a/source4/scripting/libjs/provision.js
+++ b/source4/scripting/libjs/provision.js
@@ -388,6 +388,7 @@ function provision_default_paths(subobj)
paths.ldap_basedn_ldif = lp.get("private dir") + "/" + subobj.DNSDOMAIN + ".ldif";
paths.ldap_config_basedn_ldif = lp.get("private dir") + "/" + subobj.DNSDOMAIN + "-config.ldif";
paths.ldap_schema_basedn_ldif = lp.get("private dir") + "/" + subobj.DNSDOMAIN + "-schema.ldif";
+ paths.ldapdir = lp.get("private dir") + "/ldap";
return paths;
}
@@ -446,10 +447,11 @@ function provision_fix_subobj(subobj, message, paths)
var rdns = split(",", subobj.DOMAINDN);
subobj.RDN_DC = substr(rdns[0], strlen("DC="));
- subobj.SAM_LDB = paths.samdb;
- subobj.SECRETS_LDB = paths.secrets;
+ subobj.SAM_LDB = "tdb://" + paths.samdb;
subobj.SECRETS_KEYTAB = paths.keytab;
+ subobj.LDAPDIR = paths.ldapdir;
+
return true;
}
@@ -703,6 +705,53 @@ function provision(subobj, message, blank, paths, session_info, credentials, lda
return true;
}
+/*
+ provision just the schema into a temporary ldb, so we can run ad2oLschema on it
+*/
+function provision_schema(subobj, message, tmp_schema_path, paths)
+{
+ var lp = loadparm_init();
+ var sys = sys_init();
+ var info = new Object();
+
+ var ok = provision_fix_subobj(subobj, message, paths);
+ assert(ok);
+
+ info.subobj = subobj;
+ info.message = message;
+
+ message("Setting up sam.ldb partitions\n");
+
+ /* This will erase anything in the tmp db */
+ var samdb = open_ldb(info, tmp_schema_path, true);
+
+ message("Adding schema container (permitted to fail)\n");
+ var add_ok = setup_add_ldif("provision_schema_basedn.ldif", info, samdb, true);
+ message("Modifying schema container\n");
+ var modify_ok = setup_ldb_modify("provision_schema_basedn_modify.ldif", info, samdb);
+ if (!modify_ok) {
+ if (!add_ok) {
+ message("Failed to both add and modify schema dn: + samdb.errstring() + "\n");
+ message("Perhaps you need to run the provision script with the --ldap-base-dn option, and add this record to the backend manually\n");
+ assert(modify_ok);
+ }
+ message("Failed to modify the schema container: " + samdb.errstring() + "\n");
+ assert(modify_ok);
+ }
+
+ message("Setting up sam.ldb Samba4 schema\n");
+ setup_add_ldif("schema_samba4.ldif", info, samdb, false);
+ message("Setting up sam.ldb AD schema\n");
+ setup_add_ldif("schema.ldif", info, samdb, false);
+
+ var commit_ok = samdb.transaction_commit();
+ if (!commit_ok) {
+ info.message("samdb commit failed: " + samdb.errstring() + "\n");
+ assert(commit_ok);
+ }
+ samdb.close();
+}
+
/* Write out a DNS zone file, from the info in the current database */
function provision_dns(subobj, message, paths, session_info, credentials)
{
@@ -787,6 +836,7 @@ function provision_guess()
subobj.KRBTGTPASS = randpass(12);
subobj.MACHINEPASS = randpass(12);
subobj.ADMINPASS = randpass(12);
+ subobj.LDAPMANAGERPASS = randpass(12);
subobj.DEFAULTSITE = "Default-First-Site-Name";
subobj.NEWGUID = randguid;
subobj.NTTIME = nttime;
diff --git a/source4/setup/fedorads-partitions.ldif b/source4/setup/fedorads-partitions.ldif
new file mode 100644
index 0000000000..7533b1583a
--- /dev/null
+++ b/source4/setup/fedorads-partitions.ldif
@@ -0,0 +1,28 @@
+dn: cn=\"${CONFIGDN}\",cn=mapping tree,cn=config
+objectclass: top
+objectclass: extensibleObject
+objectclass: nsMappingTree
+nsslapd-state: backend
+nsslapd-backend: configData
+cn: ${CONFIGDN}
+
+dn: cn=configData,cn=ldbm database,cn=plugins,cn=config
+objectclass: extensibleObject
+objectclass: nsBackendInstance
+nsslapd-suffix: ${CONFIGDN}
+cn: configData
+
+dn: cn=\"${SCHEMADN}\",cn=mapping tree,cn=config
+objectclass: top
+objectclass: extensibleObject
+objectclass: nsMappingTree
+nsslapd-state: backend
+nsslapd-backend: schemaData
+cn: ${SCHEMADN}
+
+dn: cn=schemaData,cn=ldbm database,cn=plugins,cn=config
+objectclass: extensibleObject
+objectclass: nsBackendInstance
+nsslapd-suffix: ${SCHEMADN}
+cn: schemaData
+
diff --git a/source4/setup/fedorads.inf b/source4/setup/fedorads.inf
new file mode 100644
index 0000000000..a5d282d392
--- /dev/null
+++ b/source4/setup/fedorads.inf
@@ -0,0 +1,26 @@
+[General]
+SuiteSpotUserID = ${ROOT}
+FullMachineName= ${HOSTNAME}.${DNSDOMAIN}
+ServerRoot= ${LDAPDIR}
+
+[slapd]
+ldapifilepath=${LDAPDIR}/ldapi
+Suffix= ${DOMAINDN}
+RootDN= cn=Manager,${DOMAINDN}
+RootDNPwd= ${LDAPMANAGERPASS}
+ServerIdentifier= samba4
+
+inst_dir= ${LDAPDIR}/slapd-samba4
+config_dir= ${LDAPDIR}/slapd-samba4
+schema_dir= ${LDAPDIR}/slapd-samba4/schema
+lock_dir= ${LDAPDIR}/slapd-samba4/lock
+log_dir= ${LDAPDIR}/slapd-samba4/logs
+run_dir= ${LDAPDIR}/slapd-samba4/logs
+db_dir= ${LDAPDIR}/slapd-samba4/db
+bak_dir= ${LDAPDIR}/slapd-samba4/bak
+tmp_dir= ${LDAPDIR}/slapd-samba4/tmp
+ldif_dir= ${LDAPDIR}/slapd-samba4/ldif
+cert_dir= ${LDAPDIR}/slapd-samba4
+
+start_server= 0
+install_full_schema= 0 \ No newline at end of file
diff --git a/source4/setup/provision-backend b/source4/setup/provision-backend
new file mode 100755
index 0000000000..6a5ec3e892
--- /dev/null
+++ b/source4/setup/provision-backend
@@ -0,0 +1,114 @@
+#!/bin/sh
+exec smbscript "$0" ${1+"$@"}
+/*
+ provision a Samba4 server
+ Copyright Andrew Tridgell 2005
+ Released under the GNU GPL v2 or later
+*/
+
+options = GetOptions(ARGV,
+ "POPT_AUTOHELP",
+ "POPT_COMMON_SAMBA",
+ "POPT_COMMON_VERSION",
+ "POPT_COMMON_CREDENTIALS",
+ 'realm=s',
+ 'host-name=s',
+ 'ldap-manager-pass=s',
+ 'root=s',
+ 'quiet',
+ 'ldap-backend-type=s');
+
+if (options == undefined) {
+ println("Failed to parse options");
+ return -1;
+}
+
+sys = sys_init();
+
+libinclude("base.js");
+libinclude("provision.js");
+
+/*
+ print a message if quiet is not set
+*/
+function message()
+{
+ if (options["quiet"] == undefined) {
+ print(vsprintf(arguments));
+ }
+}
+
+/*
+ show some help
+*/
+function ShowHelp()
+{
+ print("
+Samba4 provisioning
+
+provision [options]
+ --realm REALM set realm
+ --host-name HOSTNAME set hostname
+ --ldap-manager-pass PASSWORD choose LDAP Manager password (otherwise random)
+ --root USERNAME choose 'root' unix username
+ --quiet Be quiet
+ --ldap-backend-type LDAPSERVER Select either \"openldap\" or \"fedora-ds\" as a target to configure
+ --ldap-module= MODULE LDB mapping module to use for the LDAP backend
+You must provide at least a realm and ldap-backend-type
+
+");
+ exit(1);
+}
+
+if (options['host-name'] == undefined) {
+ options['host-name'] = hostname();
+}
+
+/*
+ main program
+*/
+if (options["realm"] == undefined ||
+ options["ldap-backend-type"] == undefined ||
+ options["host-name"] == undefined) {
+ ShowHelp();
+}
+
+/* cope with an initially blank smb.conf */
+var lp = loadparm_init();
+lp.set("realm", options.realm);
+lp.reload();
+
+var subobj = provision_guess();
+for (r in options) {
+ var key = strupper(join("", split("-", r)));
+ subobj[key] = options[r];
+}
+
+var ldapbackend = (options["ldap-backend-type"] != undefined);
+
+var paths = provision_default_paths(subobj);
+provision_fix_subobj(subobj, message, paths);
+message("Provisioning LDAP backend for %s in realm %s into %s\n", subobj.HOSTNAME, subobj.REALM, subobj.LDAPDIR);
+message("Using LDAP Manager password: %s\n", subobj.LDAPMANAGERPASS);
+
+var tmp_schema_ldb = subobj.LDAPDIR + "/schema-tmp.ldb";
+sys.mkdir(subobj.LDAPDIR, 0700);
+
+provision_schema(subobj, message, tmp_schema_ldb, paths);
+
+var mapping;
+var ext;
+if (options["ldap-backend-type"] == "fedora-ds") {
+ mapping = "schema-map-fedora-ds-1.0";
+ ext = "ldif";
+ setup_file("fedorads.inf", message, subobj.LDAPDIR + "/fedorads.inf", subobj);
+ setup_file("fedorads-partitions.ldif", message, subobj.LDAPDIR + "/fedorads-partitions.ldif", subobj);
+} else if (options["ldap-backend-type"] == "openldap") {
+ mapping = "schema-map-openldap-2.3";
+ ext = "schema";
+ setup_file("slapd.conf", message, subobj.LDAPDIR + "/slapd.conf", subobj);
+}
+message("ad2oLschema --option=convert:target=" + options["ldap-backend-type"] + " -I " + lp.get("setup directory") + "/" + mapping + " -H tdb://" + tmp_schema_ldb + " -O " + subobj.LDAPDIR + "/backend-schema." + ext + "\n");
+
+message("All OK\n");
+return 0;
diff --git a/source4/setup/slapd.conf b/source4/setup/slapd.conf
new file mode 100644
index 0000000000..a6fe73a4de
--- /dev/null
+++ b/source4/setup/slapd.conf
@@ -0,0 +1,73 @@
+loglevel 0
+
+include ${LDAPDIR}/backend-schema.schema
+
+pidfile ${LDAPDIR}/slapd.pid
+argsfile ${LDAPDIR}/slapd.args
+sasl-realm ${DNSDOMAIN}
+access to * by * write
+
+allow update_anon
+
+authz-regexp
+ uid=([^,]*),cn=${DNSDOMAIN},cn=digest-md5,cn=auth
+ ldap:///${DOMAINDN}??sub?(samAccountName=\$1)
+
+authz-regexp
+ uid=([^,]*),cn=([^,]*),cn=digest-md5,cn=auth
+ ldap:///${DOMAINDN}??sub?(samAccountName=\$1)
+
+include $modconf
+
+defaultsearchbase \"${DOMAINDN}\"
+
+backend bdb
+database bdb
+suffix \"cn=Schema,cn=Configuration,${DOMAINDN}\"
+directory ${LDAPDIR}/db/schema
+index objectClass eq
+index samAccountName eq
+index name eq
+index objectCategory eq
+index lDAPDisplayName eq
+index subClassOf eq
+
+database bdb
+suffix \"cn=Configuration,${DOMAINDN}\"
+directory ${LDAPDIR}/db/config
+index objectClass eq
+index samAccountName eq
+index name eq
+index objectSid eq
+index objectCategory eq
+index nCName eq pres
+index subClassOf eq
+index dnsRoot eq
+index nETBIOSName eq pres
+
+database bdb
+suffix \"${DOMAINDN}\"
+rootdn \"cn=Manager,${DOMAINDN}\"
+rootpw ${LDAPMANAGERPASS}
+directory ${LDAPDIR}/db/user
+index objectClass eq
+index samAccountName eq
+index name eq
+index objectSid eq
+index objectCategory eq
+index member eq
+index uidNumber eq
+index gidNumber eq
+index unixName eq
+index privilege eq
+index nCName eq pres
+index lDAPDisplayName eq
+index subClassOf eq
+index dnsRoot eq
+index nETBIOSName eq pres
+
+#syncprov is stable in OpenLDAP 2.3, and available in 2.2.
+#We only need this for the contextCSN attribute anyway....
+overlay syncprov
+syncprov-checkpoint 100 10
+syncprov-sessionlog 100