summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs-xml/manpages-3/net.8.xml14
-rw-r--r--docs-xml/smbdotconf/ldap/ldapreffollow.xml21
-rw-r--r--nsswitch/libwbclient/wbclient.h6
-rw-r--r--source3/include/proto.h3
-rw-r--r--source3/lib/smbldap.c12
-rw-r--r--source3/libnet/libnet_join.c1
-rw-r--r--source3/libsmb/trusts_util.c3
-rw-r--r--source3/param/loadparm.c11
-rw-r--r--source3/rpc_client/cli_netlogon.c3
-rw-r--r--source3/utils/net_rpc.c23
-rw-r--r--source4/dsdb/common/util.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/config.mk20
-rw-r--r--source4/dsdb/samdb/ldb_modules/naming_fsmo.c26
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c9
-rw-r--r--source4/dsdb/samdb/ldb_modules/password_hash.c2
-rw-r--r--source4/dsdb/samdb/ldb_modules/pdc_fsmo.c20
-rw-r--r--source4/dsdb/samdb/ldb_modules/samldb.c11
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c113
-rw-r--r--source4/dsdb/samdb/ldb_modules/util.c128
-rw-r--r--source4/dsdb/samdb/ldb_modules/util.h22
-rw-r--r--source4/dsdb/schema/schema_inferiors.c27
-rw-r--r--source4/dsdb/schema/schema_init.c115
-rw-r--r--source4/dsdb/schema/schema_set.c5
-rw-r--r--source4/lib/ldb/common/ldb.c8
-rw-r--r--source4/lib/ldb/common/ldb_modules.c8
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c9
-rw-r--r--source4/scripting/python/samba/provision.py30
-rw-r--r--source4/setup/provision_basedn.ldif2
-rw-r--r--source4/setup/schema_samba4.ldif43
29 files changed, 450 insertions, 247 deletions
diff --git a/docs-xml/manpages-3/net.8.xml b/docs-xml/manpages-3/net.8.xml
index 82fd7a57af..8ab33d58b0 100644
--- a/docs-xml/manpages-3/net.8.xml
+++ b/docs-xml/manpages-3/net.8.xml
@@ -748,6 +748,9 @@ such as domain name, domain sid and number of users and groups.
<para>Add a interdomain trust account for <replaceable>DOMAIN</replaceable>.
This is in fact a Samba account named <replaceable>DOMAIN$</replaceable>
with the account flag <constant>'I'</constant> (interdomain trust account).
+This is required for incoming trusts to work. It makes Samba be a
+trusted domain of the foreign (trusting) domain.
+Users of the Samba domain will be made available in the foreign domain.
If the command is used against localhost it has the same effect as
<command>smbpasswd -a -i DOMAIN</command>. Please note that both commands
expect a appropriate UNIX account.
@@ -769,8 +772,13 @@ it has the same effect as <command>smbpasswd -x DOMAIN$</command>.
<title>RPC TRUSTDOM ESTABLISH <replaceable>DOMAIN</replaceable></title>
<para>
-Establish a trust relationship to a trusting domain.
+Establish a trust relationship to a trusted domain.
Interdomain account must already be created on the remote PDC.
+This is required for outgoing trusts to work. It makes Samba be a
+trusting domain of a foreign (trusted) domain.
+Users of the foreign domain will be made available in our domain.
+You'll need winbind and a working idmap config to make them
+appear in your system.
</para>
</refsect3>
@@ -784,7 +792,7 @@ Interdomain account must already be created on the remote PDC.
<refsect3>
<title>RPC TRUSTDOM LIST</title>
-<para>List all current interdomain trust relationships.</para>
+<para>List all interdomain trust relationships.</para>
</refsect3>
@@ -835,7 +843,7 @@ Force shutting down all applications.
Timeout before system will be shut down. An interactive
user of the system can use this time to cancel the shutdown.
</para></listitem>
-</varlistentry>'>
+</varlistentry>
<varlistentry>
<term>-C message</term>
diff --git a/docs-xml/smbdotconf/ldap/ldapreffollow.xml b/docs-xml/smbdotconf/ldap/ldapreffollow.xml
new file mode 100644
index 0000000000..f059f15f15
--- /dev/null
+++ b/docs-xml/smbdotconf/ldap/ldapreffollow.xml
@@ -0,0 +1,21 @@
+<samba:parameter name="ldap ref follow" context="G" type="enum"
+ advanced="1" developer="1"
+ xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
+
+<description>
+
+ <para>This option controls whether to follow LDAP referrals or not when
+ searching for entries in the LDAP database. Possible values are
+ <emphasis>on</emphasis> to enable following referrals,
+ <emphasis>off</emphasis> to disable this, and
+ <emphasis>auto</emphasis>, to use the libldap default settings.
+ libldap's choice of following referrals or not is set in
+ /etc/openldap/ldap.conf with the REFERRALS parameter as documented in
+ ldap.conf(5).</para>
+
+</description>
+
+<value type="default">auto</value>
+<value type="example">off</value>
+
+</samba:parameter>
diff --git a/nsswitch/libwbclient/wbclient.h b/nsswitch/libwbclient/wbclient.h
index ced82d8d22..e262679264 100644
--- a/nsswitch/libwbclient/wbclient.h
+++ b/nsswitch/libwbclient/wbclient.h
@@ -438,6 +438,12 @@ enum wbcPasswordChangeRejectReason {
WBC_PWD_CHANGE_PASSWORD_TOO_LONG=8
};
+/* Note: this defines exist for compatibility reasons with existing code */
+#define WBC_PWD_CHANGE_REJECT_OTHER WBC_PWD_CHANGE_NO_ERROR
+#define WBC_PWD_CHANGE_REJECT_TOO_SHORT WBC_PWD_CHANGE_PASSWORD_TOO_SHORT
+#define WBC_PWD_CHANGE_REJECT_IN_HISTORY WBC_PWD_CHANGE_PWD_IN_HISTORY
+#define WBC_PWD_CHANGE_REJECT_COMPLEXITY WBC_PWD_CHANGE_NOT_COMPLEX
+
/**
* @brief Logoff User Parameters
**/
diff --git a/source3/include/proto.h b/source3/include/proto.h
index dd46bdda83..7e31da064f 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -3307,6 +3307,7 @@ void update_trustdom_cache( void );
NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *domain,
+ const char *account_name,
unsigned char orig_trust_passwd_hash[16],
uint32 sec_channel_type);
NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
@@ -3976,6 +3977,7 @@ char *lp_ldap_suffix(void);
char *lp_ldap_admin_dn(void);
int lp_ldap_ssl(void);
bool lp_ldap_ssl_ads(void);
+int lp_ldap_ref_follow(void);
int lp_ldap_passwd_sync(void);
bool lp_ldap_delete_dn(void);
int lp_ldap_replication_sleep(void);
@@ -5237,6 +5239,7 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
struct netr_SamInfo3 **info3);
NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ const char *account_name,
const unsigned char orig_trust_passwd_hash[16],
const char *new_trust_pwd_cleartext,
const unsigned char new_trust_passwd_hash[16],
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index c96801a72b..47b2208880 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -721,9 +721,18 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
rc = ldap_initialize(ldap_struct, uri);
if (rc) {
DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));
+ return rc;
}
- return rc;
+ if (lp_ldap_ref_follow() != Auto) {
+ rc = ldap_set_option(*ldap_struct, LDAP_OPT_REFERRALS,
+ lp_ldap_ref_follow() ? LDAP_OPT_ON : LDAP_OPT_OFF);
+ if (rc != LDAP_SUCCESS)
+ DEBUG(0, ("Failed to set LDAP_OPT_REFERRALS: %s\n",
+ ldap_err2string(rc)));
+ }
+
+ return LDAP_SUCCESS;
#else
/* Parse the string manually */
@@ -774,7 +783,6 @@ int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri)
}
#endif /* HAVE_LDAP_INITIALIZE */
-
/* now set connection timeout */
#ifdef LDAP_X_OPT_CONNECT_TIMEOUT /* Netscape */
{
diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c
index 8c3030711b..aa5f54adaf 100644
--- a/source3/libnet/libnet_join.c
+++ b/source3/libnet/libnet_join.c
@@ -789,6 +789,7 @@ static NTSTATUS libnet_join_joindomain_rpc_unsecure(TALLOC_CTX *mem_ctx,
E_md4hash(trust_passwd, orig_trust_passwd_hash);
status = rpccli_netlogon_set_trust_password(pipe_hnd, mem_ctx,
+ r->in.machine_name,
orig_trust_passwd_hash,
r->in.machine_password,
new_trust_passwd_hash,
diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c
index adf1525812..e201814163 100644
--- a/source3/libsmb/trusts_util.c
+++ b/source3/libsmb/trusts_util.c
@@ -29,6 +29,7 @@
NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
const char *domain,
+ const char *account_name,
unsigned char orig_trust_passwd_hash[16],
uint32 sec_channel_type)
{
@@ -47,6 +48,7 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m
E_md4hash(new_trust_passwd, new_trust_passwd_hash);
nt_status = rpccli_netlogon_set_trust_password(cli, mem_ctx,
+ account_name,
orig_trust_passwd_hash,
new_trust_passwd,
new_trust_passwd_hash,
@@ -88,6 +90,7 @@ NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli,
}
return trust_pw_change_and_store_it(cli, mem_ctx, domain,
+ global_myname(),
old_trust_passwd_hash,
sec_channel_type);
}
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index b1f2a4aeb5..7bac72ebd3 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -260,6 +260,7 @@ struct global {
char *szLdapGroupSuffix;
int ldap_ssl;
bool ldap_ssl_ads;
+ int ldap_ref_follow;
char *szLdapSuffix;
char *szLdapAdminDn;
int ldap_debug_level;
@@ -3667,6 +3668,14 @@ static struct parm_struct parm_table[] = {
.flags = FLAG_ADVANCED,
},
{
+ .label = "ldap ref follow",
+ .type = P_ENUM,
+ .p_class = P_GLOBAL,
+ .ptr = &Globals.ldap_ref_follow,
+ .enum_list = enum_bool_auto,
+ .flags = FLAG_ADVANCED,
+ },
+ {
.label = "ldap timeout",
.type = P_INTEGER,
.p_class = P_GLOBAL,
@@ -5038,6 +5047,7 @@ static void init_globals(bool first_time_only)
Globals.ldap_passwd_sync = LDAP_PASSWD_SYNC_OFF;
Globals.ldap_delete_dn = False;
Globals.ldap_replication_sleep = 1000; /* wait 1 sec for replication */
+ Globals.ldap_ref_follow = Auto;
Globals.ldap_timeout = LDAP_DEFAULT_TIMEOUT;
Globals.ldap_connection_timeout = LDAP_CONNECTION_DEFAULT_TIMEOUT;
Globals.ldap_page_size = LDAP_PAGE_SIZE;
@@ -5387,6 +5397,7 @@ FN_GLOBAL_STRING(lp_ldap_suffix, &Globals.szLdapSuffix)
FN_GLOBAL_STRING(lp_ldap_admin_dn, &Globals.szLdapAdminDn)
FN_GLOBAL_INTEGER(lp_ldap_ssl, &Globals.ldap_ssl)
FN_GLOBAL_BOOL(lp_ldap_ssl_ads, &Globals.ldap_ssl_ads)
+FN_GLOBAL_INTEGER(lp_ldap_ref_follow, &Globals.ldap_ref_follow)
FN_GLOBAL_INTEGER(lp_ldap_passwd_sync, &Globals.ldap_passwd_sync)
FN_GLOBAL_BOOL(lp_ldap_delete_dn, &Globals.ldap_delete_dn)
FN_GLOBAL_INTEGER(lp_ldap_replication_sleep, &Globals.ldap_replication_sleep)
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 6caffd74a6..5e116c95de 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -509,6 +509,7 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
TALLOC_CTX *mem_ctx,
+ const char *account_name,
const unsigned char orig_trust_passwd_hash[16],
const char *new_trust_pwd_cleartext,
const unsigned char new_trust_passwd_hash[16],
@@ -523,7 +524,7 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
cli->desthost, /* server name */
lp_workgroup(), /* domain */
global_myname(), /* client name */
- global_myname(), /* machine account name */
+ account_name, /* machine account name */
orig_trust_passwd_hash,
sec_channel_type,
&neg_flags);
diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c
index be971d8555..896ea8cc65 100644
--- a/source3/utils/net_rpc.c
+++ b/source3/utils/net_rpc.c
@@ -344,6 +344,7 @@ static NTSTATUS rpc_oldjoin_internals(struct net_context *c,
E_md4hash(trust_passwd, orig_trust_passwd_hash);
result = trust_pw_change_and_store_it(pipe_hnd, mem_ctx, c->opt_target_workgroup,
+ global_myname(),
orig_trust_passwd_hash,
sec_channel_type);
@@ -6029,7 +6030,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv)
if (c->display_usage) {
d_printf(_("Usage:\n"
"net rpc trustdom list\n"
- " List trust relationships\n"));
+ " List in- and outgoing trust relationships\n"));
return 0;
}
@@ -6300,41 +6301,41 @@ static int rpc_trustdom(struct net_context *c, int argc, const char **argv)
"add",
rpc_trustdom_add,
NET_TRANSPORT_RPC,
- N_("Add trusted domain's account"),
+ N_("Add trusting domain's account"),
N_("net rpc trustdom add\n"
- " Add trusted domain's account")
+ " Add trusting domain's account")
},
{
"del",
rpc_trustdom_del,
NET_TRANSPORT_RPC,
- N_("Remove trusted domain's account"),
+ N_("Remove trusting domain's account"),
N_("net rpc trustdom del\n"
- " Remove trusted domain's account")
+ " Remove trusting domain's account")
},
{
"establish",
rpc_trustdom_establish,
NET_TRANSPORT_RPC,
- N_("Establish trust relationship"),
+ N_("Establish outgoing trust relationship"),
N_("net rpc trustdom establish\n"
- " Establish trust relationship")
+ " Establish outgoing trust relationship")
},
{
"revoke",
rpc_trustdom_revoke,
NET_TRANSPORT_RPC,
- N_("Revoke trust relationship"),
+ N_("Revoke outgoing trust relationship"),
N_("net rpc trustdom revoke\n"
- " Revoke trust relationship")
+ " Revoke outgoing trust relationship")
},
{
"list",
rpc_trustdom_list,
NET_TRANSPORT_RPC,
- N_("List domain trusts"),
+ N_("List in- and outgoing domain trusts"),
N_("net rpc trustdom list\n"
- " List domain trusts")
+ " List in- and outgoing domain trusts")
},
{
"vampire",
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 9a8b59e55d..f86a842fb4 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -1531,7 +1531,7 @@ int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx,
while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
ret = ldb_search(ldb, local_ctx, &res, sdn, LDB_SCOPE_BASE, attrs,
- "(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain))");
+ "(|(objectClass=domain)(objectClass=builtinDomain))");
if (ret == LDB_SUCCESS) {
if (res->count == 1) {
break;
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 456ff5756c..ea4e722822 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -1,4 +1,14 @@
################################################
+# Start SUBSYSTEM DSDB_MODULE_HELPERS
+[SUBSYSTEM::DSDB_MODULE_HELPERS]
+PRIVATE_DEPENDENCIES = LIBLDB
+
+DSDB_MODULE_HELPERS_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/util.o
+
+$(eval $(call proto_header_template,$(dsdbsrcdir)/samdb/ldb_modules/util_proto.h,$(DSDB_MODULE_HELPERS_OBJ_FILES:.o=.c)))
+
+
+################################################
# Start MODULE ldb_objectguid
[MODULE::ldb_objectguid]
SUBSYSTEM = LIBLDB
@@ -15,7 +25,7 @@ ldb_objectguid_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/objectguid.o
SUBSYSTEM = LIBLDB
PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS \
LIBNDR NDR_DRSUAPI \
- NDR_DRSBLOBS LIBNDR
+ NDR_DRSBLOBS LIBNDR DSDB_MODULE_HELPERS
INIT_FUNCTION = LDB_MODULE(repl_meta_data)
# End MODULE ldb_repl_meta_data
################################################
@@ -39,7 +49,7 @@ ldb_dsdb_cache_OBJ_FILES = \
# Start MODULE ldb_schema_fsmo
[MODULE::ldb_schema_fsmo]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS
+PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS
INIT_FUNCTION = LDB_MODULE(schema_fsmo)
# End MODULE ldb_schema_fsmo
################################################
@@ -51,7 +61,7 @@ ldb_schema_fsmo_OBJ_FILES = \
# Start MODULE ldb_naming_fsmo
[MODULE::ldb_naming_fsmo]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS
+PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS
INIT_FUNCTION = LDB_MODULE(naming_fsmo)
# End MODULE ldb_naming_fsmo
################################################
@@ -63,7 +73,7 @@ ldb_naming_fsmo_OBJ_FILES = \
# Start MODULE ldb_pdc_fsmo
[MODULE::ldb_pdc_fsmo]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS
+PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS DSDB_MODULE_HELPERS
INIT_FUNCTION = LDB_MODULE(pdc_fsmo)
# End MODULE ldb_pdc_fsmo
################################################
@@ -220,7 +230,7 @@ ldb_show_deleted_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/show_deleted.o
# Start MODULE ldb_partition
[MODULE::ldb_partition]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS SAMDB DSDB_MODULE_HELPERS
INIT_FUNCTION = LDB_MODULE(partition)
# End MODULE ldb_partition
################################################
diff --git a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c
index 607bf054d2..15cad259ce 100644
--- a/source4/dsdb/samdb/ldb_modules/naming_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/naming_fsmo.c
@@ -28,6 +28,7 @@
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "../lib/util/dlinklist.h"
+#include "dsdb/samdb/ldb_modules/util.h"
static int naming_fsmo_init(struct ldb_module *module)
{
@@ -65,34 +66,15 @@ static int naming_fsmo_init(struct ldb_module *module)
}
ldb_module_set_private(module, naming_fsmo);
- ret = ldb_search(ldb, mem_ctx, &naming_res,
- naming_dn, LDB_SCOPE_BASE,
- naming_attrs, NULL);
+ ret = dsdb_module_search_dn(module, mem_ctx, &naming_res,
+ naming_dn,
+ naming_attrs);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
ldb_debug(ldb, LDB_DEBUG_WARNING,
"naming_fsmo_init: no partitions dn present: (skip loading of naming contexts details)\n");
talloc_free(mem_ctx);
return ldb_next_init(module);
}
- if (ret != LDB_SUCCESS) {
- ldb_debug_set(ldb, LDB_DEBUG_FATAL,
- "naming_fsmo_init: failed to search the cross-ref container: %s: %s",
- ldb_strerror(ret), ldb_errstring(ldb));
- talloc_free(mem_ctx);
- return ret;
- }
- if (naming_res->count == 0) {
- ldb_debug(ldb, LDB_DEBUG_WARNING,
- "naming_fsmo_init: no cross-ref container present: (skip loading of naming contexts details)\n");
- talloc_free(mem_ctx);
- return ldb_next_init(module);
- } else if (naming_res->count > 1) {
- ldb_debug_set(ldb, LDB_DEBUG_FATAL,
- "naming_fsmo_init: [%u] cross-ref containers found on a base search",
- naming_res->count);
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
naming_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, naming_fsmo, naming_res->msgs[0], "fSMORoleOwner");
if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), naming_fsmo->master_dn) == 0) {
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index b6f1a1aa23..b5e058df0b 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -706,7 +706,13 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req
if (!schema) {
return ldb_next_request(module, req);
}
- objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass");
+
+ /* As with the "real" AD we don't accept empty messages */
+ if (req->op.mod.message->num_elements == 0) {
+ ldb_set_errstring(ldb, "objectclass: modify message must have "
+ "elements/attributes!");
+ return LDB_ERR_UNWILLING_TO_PERFORM;
+ }
ac = oc_init_context(module, req);
if (ac == NULL) {
@@ -715,6 +721,7 @@ static int objectclass_modify(struct ldb_module *module, struct ldb_request *req
/* If no part of this touches the objectClass, then we don't
* need to make any changes. */
+ objectclass_element = ldb_msg_find_element(req->op.mod.message, "objectClass");
/* If the only operation is the deletion of the objectClass
* then go on with just fixing the attribute case */
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index fdb044198b..adb62d3544 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1673,7 +1673,7 @@ static int build_domain_data_request(struct ph_context *ac)
ldb = ldb_module_get_ctx(ac->module);
filter = talloc_asprintf(ac,
- "(&(objectSid=%s)(|(|(objectClass=domain)(objectClass=builtinDomain))(objectClass=samba4LocalDomain)))",
+ "(&(objectSid=%s)(|(objectClass=domain)(objectClass=builtinDomain)))",
ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
if (filter == NULL) {
ldb_oom(ldb);
diff --git a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c
index 950f87eb74..6d814f9334 100644
--- a/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/pdc_fsmo.c
@@ -27,6 +27,7 @@
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "../lib/util/dlinklist.h"
+#include "dsdb/samdb/ldb_modules/util.h"
static int pdc_fsmo_init(struct ldb_module *module)
{
@@ -64,9 +65,9 @@ static int pdc_fsmo_init(struct ldb_module *module)
}
ldb_module_set_private(module, pdc_fsmo);
- ret = ldb_search(ldb, mem_ctx, &pdc_res,
- pdc_dn, LDB_SCOPE_BASE,
- pdc_attrs, NULL);
+ ret = dsdb_module_search_dn(module, mem_ctx, &pdc_res,
+ pdc_dn,
+ pdc_attrs);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
ldb_debug(ldb, LDB_DEBUG_WARNING,
"pdc_fsmo_init: no domain object present: (skip loading of domain details)\n");
@@ -79,19 +80,6 @@ static int pdc_fsmo_init(struct ldb_module *module)
talloc_free(mem_ctx);
return ret;
}
- if (pdc_res->count == 0) {
- ldb_debug(ldb, LDB_DEBUG_WARNING,
- "pdc_fsmo_init: no domain object present: (skip loading of domain details)\n");
- talloc_free(mem_ctx);
- return ldb_next_init(module);
- } else if (pdc_res->count > 1) {
- ldb_debug_set(ldb, LDB_DEBUG_FATAL,
- "pdc_fsmo_init: [%u] domain objects found on a base search",
- pdc_res->count);
- DEBUG(0,(__location__ ": %s\n", ldb_errstring(ldb)));
- talloc_free(mem_ctx);
- return LDB_ERR_CONSTRAINT_VIOLATION;
- }
pdc_fsmo->master_dn = ldb_msg_find_attr_as_dn(ldb, mem_ctx, pdc_res->msgs[0], "fSMORoleOwner");
if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), pdc_fsmo->master_dn) == 0) {
diff --git a/source4/dsdb/samdb/ldb_modules/samldb.c b/source4/dsdb/samdb/ldb_modules/samldb.c
index 2d87a017fd..2a0bb2dfe6 100644
--- a/source4/dsdb/samdb/ldb_modules/samldb.c
+++ b/source4/dsdb/samdb/ldb_modules/samldb.c
@@ -284,8 +284,7 @@ static int samldb_get_parent_domain(struct samldb_ctx *ac)
ret = ldb_build_search_req(&req, ldb, ac,
dn, LDB_SCOPE_BASE,
"(|(objectClass=domain)"
- "(objectClass=builtinDomain)"
- "(objectClass=samba4LocalDomain))",
+ "(objectClass=builtinDomain))",
attrs,
NULL,
ac, samldb_get_parent_domain_callback,
@@ -559,10 +558,10 @@ static int samldb_get_sid_domain(struct samldb_ctx *ac)
/* get the domain component part of the provided SID */
ac->domain_sid->num_auths--;
- filter = talloc_asprintf(ac, "(&(objectSid=%s)"
- "(|(objectClass=domain)"
- "(objectClass=builtinDomain)"
- "(objectClass=samba4LocalDomain)))",
+ filter = talloc_asprintf(ac,
+ "(&(objectSid=%s)"
+ "(|(objectClass=domain)"
+ "(objectClass=builtinDomain)))",
ldap_encode_ndr_dom_sid(ac, ac->domain_sid));
if (filter == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index c482ab57df..2b6606c147 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -5,6 +5,7 @@
checkings, it also loads the dsdb_schema.
Copyright (C) Stefan Metzmacher <metze@samba.org> 2007
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
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
@@ -28,6 +29,7 @@
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "librpc/gen_ndr/ndr_drsblobs.h"
#include "param/param.h"
+#include "dsdb/samdb/ldb_modules/util.h"
static int generate_objectClasses(struct ldb_context *ldb, struct ldb_message *msg,
const struct dsdb_schema *schema);
@@ -90,13 +92,107 @@ struct schema_fsmo_search_data {
const struct dsdb_schema *schema;
};
+/*
+ Given an LDB module (pointing at the schema DB), and the DN, set the populated schema
+*/
+
+static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *module,
+ struct smb_iconv_convenience *iconv_convenience,
+ struct ldb_dn *schema_dn,
+ struct dsdb_schema **schema)
+{
+ TALLOC_CTX *tmp_ctx;
+ char *error_string;
+ int ret;
+ struct ldb_context *ldb = ldb_module_get_ctx(module);
+ struct ldb_result *schema_res;
+ struct ldb_result *a_res;
+ struct ldb_result *c_res;
+ static const char *schema_attrs[] = {
+ "prefixMap",
+ "schemaInfo",
+ "fSMORoleOwner",
+ NULL
+ };
+ unsigned flags;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ /* we don't want to trace the schema load */
+ flags = ldb_get_flags(ldb);
+ ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
+
+ /*
+ * setup the prefix mappings and schema info
+ */
+ ret = dsdb_module_search_dn(module, tmp_ctx, &schema_res,
+ schema_dn, schema_attrs);
+ if (ret == LDB_ERR_NO_SUCH_OBJECT) {
+ goto failed;
+ } else if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb,
+ "dsdb_schema: failed to search the schema head: %s",
+ ldb_errstring(ldb));
+ goto failed;
+ }
+
+ /*
+ * load the attribute definitions
+ */
+ ret = dsdb_module_search(module, tmp_ctx, &a_res,
+ schema_dn, LDB_SCOPE_ONELEVEL, NULL,
+ "(objectClass=attributeSchema)");
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb,
+ "dsdb_schema: failed to search attributeSchema objects: %s",
+ ldb_errstring(ldb));
+ goto failed;
+ }
+
+ /*
+ * load the objectClass definitions
+ */
+ ret = dsdb_module_search(module, tmp_ctx, &c_res,
+ schema_dn, LDB_SCOPE_ONELEVEL, NULL,
+ "(objectClass=classSchema)");
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb,
+ "dsdb_schema: failed to search attributeSchema objects: %s",
+ ldb_errstring(ldb));
+ goto failed;
+ }
+
+ ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
+ lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
+ schema_res, a_res, c_res, schema, &error_string);
+ if (ret != LDB_SUCCESS) {
+ ldb_asprintf_errstring(ldb,
+ "dsdb_schema load failed: %s",
+ error_string);
+ goto failed;
+ }
+ talloc_steal(mem_ctx, *schema);
+
+failed:
+ if (flags & LDB_FLG_ENABLE_TRACING) {
+ flags = ldb_get_flags(ldb);
+ ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+
static int schema_fsmo_init(struct ldb_module *module)
{
struct ldb_context *ldb;
TALLOC_CTX *mem_ctx;
struct ldb_dn *schema_dn;
struct dsdb_schema *schema;
- char *error_string = NULL;
int ret;
struct schema_fsmo_private_data *data;
@@ -134,9 +230,9 @@ static int schema_fsmo_init(struct ldb_module *module)
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = dsdb_schema_from_schema_dn(mem_ctx, ldb,
+ ret = dsdb_schema_from_schema_dn(mem_ctx, module,
lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
- schema_dn, &schema, &error_string);
+ schema_dn, &schema);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
ldb_reset_err_string(ldb);
@@ -147,9 +243,6 @@ static int schema_fsmo_init(struct ldb_module *module)
}
if (ret != LDB_SUCCESS) {
- ldb_asprintf_errstring(ldb,
- "schema_fsmo_init: dsdb_schema load failed: %s",
- error_string);
talloc_free(mem_ctx);
return ret;
}
@@ -246,7 +339,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r
struct ldb_context *ldb;
struct ldb_dn *schema_dn;
struct dsdb_schema *schema;
- char *error_string = NULL;
int ret;
TALLOC_CTX *mem_ctx;
@@ -270,9 +362,9 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r
return LDB_ERR_OPERATIONS_ERROR;
}
- ret = dsdb_schema_from_schema_dn(mem_ctx, ldb,
+ ret = dsdb_schema_from_schema_dn(mem_ctx, module,
lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
- schema_dn, &schema, &error_string);
+ schema_dn, &schema);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
ldb_reset_err_string(ldb);
@@ -283,9 +375,6 @@ static int schema_fsmo_extended(struct ldb_module *module, struct ldb_request *r
}
if (ret != LDB_SUCCESS) {
- ldb_asprintf_errstring(ldb,
- "schema_fsmo_extended: dsdb_schema load failed: %s",
- error_string);
talloc_free(mem_ctx);
return ldb_next_request(module, req);
}
diff --git a/source4/dsdb/samdb/ldb_modules/util.c b/source4/dsdb/samdb/ldb_modules/util.c
new file mode 100644
index 0000000000..476eb08ed0
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/util.c
@@ -0,0 +1,128 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 2009
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
+
+ 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/>.
+*/
+
+#include "ldb.h"
+#include "ldb_module.h"
+
+/*
+ search for attrs on one DN, in the modules below
+ */
+int dsdb_module_search_dn(struct ldb_module *module,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_result **_res,
+ struct ldb_dn *basedn,
+ const char * const *attrs)
+{
+ int ret;
+ struct ldb_request *req;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+
+ tmp_ctx = talloc_new(mem_ctx);
+
+ res = talloc_zero(tmp_ctx, struct ldb_result);
+ if (!res) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
+ basedn,
+ LDB_SCOPE_BASE,
+ NULL,
+ attrs,
+ NULL,
+ res,
+ ldb_search_default_callback,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ ret = ldb_next_request(module, req);
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+ }
+
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ if (res->count != 1) {
+ /* we may be reading a DB that does not have the 'check base on search' option... */
+ ret = LDB_ERR_NO_SUCH_OBJECT;
+ } else {
+ *_res = talloc_steal(mem_ctx, res);
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+/*
+ search for attrs in the modules below
+ */
+int dsdb_module_search(struct ldb_module *module,
+ TALLOC_CTX *mem_ctx,
+ struct ldb_result **_res,
+ struct ldb_dn *basedn, enum ldb_scope scope,
+ const char * const *attrs,
+ const char *expression)
+{
+ int ret;
+ struct ldb_request *req;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+
+ tmp_ctx = talloc_new(mem_ctx);
+
+ res = talloc_zero(tmp_ctx, struct ldb_result);
+ if (!res) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_build_search_req(&req, ldb_module_get_ctx(module), tmp_ctx,
+ basedn,
+ scope,
+ expression,
+ attrs,
+ NULL,
+ res,
+ ldb_search_default_callback,
+ NULL);
+ if (ret != LDB_SUCCESS) {
+ talloc_free(tmp_ctx);
+ return ret;
+ }
+
+ ret = ldb_next_request(module, req);
+ if (ret == LDB_SUCCESS) {
+ ret = ldb_wait(req->handle, LDB_WAIT_ALL);
+ }
+
+ talloc_free(req);
+ if (ret == LDB_SUCCESS) {
+ *_res = talloc_steal(mem_ctx, res);
+ }
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
diff --git a/source4/dsdb/samdb/ldb_modules/util.h b/source4/dsdb/samdb/ldb_modules/util.h
new file mode 100644
index 0000000000..0a1ab83c6d
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/util.h
@@ -0,0 +1,22 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+
+ Copyright (C) Andrew Tridgell 2009
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
+
+ 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/>.
+*/
+
+#include "dsdb/samdb/ldb_modules/util_proto.h"
diff --git a/source4/dsdb/schema/schema_inferiors.c b/source4/dsdb/schema/schema_inferiors.c
index 3be97b6b83..ecac74a954 100644
--- a/source4/dsdb/schema/schema_inferiors.c
+++ b/source4/dsdb/schema/schema_inferiors.c
@@ -149,19 +149,22 @@ void schema_subclasses_order_recurse(struct dsdb_schema *schema, struct dsdb_cla
return;
}
-static void schema_create_subclasses(struct dsdb_schema *schema)
+static int schema_create_subclasses(struct dsdb_schema *schema)
{
- struct dsdb_class *schema_class;
+ struct dsdb_class *schema_class, *top;
for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
struct dsdb_class *schema_class2 = dsdb_class_by_lDAPDisplayName(schema, schema_class->subClassOf);
if (schema_class2 == NULL) {
DEBUG(0,("ERROR: no subClassOf for '%s'\n", schema_class->lDAPDisplayName));
- continue;
+ return LDB_ERR_OPERATIONS_ERROR;
}
if (schema_class2 && schema_class != schema_class2) {
if (schema_class2->subclasses_direct == NULL) {
schema_class2->subclasses_direct = str_list_make_empty(schema_class2);
+ if (!schema_class2->subclasses_direct) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
}
schema_class2->subclasses_direct = str_list_add_const(schema_class2->subclasses_direct,
schema_class->lDAPDisplayName);
@@ -175,7 +178,14 @@ static void schema_create_subclasses(struct dsdb_schema *schema)
schema_class->subClass_order = 0;
}
- schema_subclasses_order_recurse(schema, dsdb_class_by_lDAPDisplayName(schema, "top"), 1);
+ top = dsdb_class_by_lDAPDisplayName(schema, "top");
+ if (!top) {
+ DEBUG(0,("ERROR: no 'top' class in loaded schema\n"));
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ schema_subclasses_order_recurse(schema, top, 1);
+ return LDB_SUCCESS;
}
static void schema_fill_possible_inferiors(struct dsdb_schema *schema, struct dsdb_class *schema_class)
@@ -294,13 +304,17 @@ static void schema_fill_from_ids(struct dsdb_schema *schema)
}
}
-void schema_fill_constructed(struct dsdb_schema *schema)
+int schema_fill_constructed(struct dsdb_schema *schema)
{
+ int ret;
struct dsdb_class *schema_class;
schema_fill_from_ids(schema);
- schema_create_subclasses(schema);
+ ret = schema_create_subclasses(schema);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
for (schema_class=schema->classes; schema_class; schema_class=schema_class->next) {
schema_fill_possible_inferiors(schema, schema_class);
@@ -318,4 +332,5 @@ void schema_fill_constructed(struct dsdb_schema *schema)
schema_class->subclasses = NULL;
schema_class->posssuperiors = NULL;
}
+ return LDB_SUCCESS;
}
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index b876ab09fc..9dd3ce0ccc 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -30,6 +30,8 @@
#include "param/param.h"
#include "lib/ldb/include/ldb_module.h"
+static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes);
+
struct dsdb_schema *dsdb_new_schema(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience)
{
struct dsdb_schema *schema = talloc_zero(mem_ctx, struct dsdb_schema);
@@ -519,7 +521,7 @@ WERROR dsdb_write_prefixes_from_schema_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_co
return WERR_OK;
}
-WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes)
+static WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, uint32_t* num_prefixes, struct dsdb_schema_oid_prefix **prefixes)
{
struct prefixMapBlob *blob;
enum ndr_err_code ndr_err;
@@ -906,7 +908,7 @@ WERROR dsdb_class_from_ldb(const struct dsdb_schema *schema,
/*
Create a DSDB schema from the ldb results provided. This is called
directly when the schema is provisioned from an on-disk LDIF file, or
- from dsdb_schema_from_schema_dn below
+ from dsdb_schema_from_schema_dn in schema_fsmo
*/
int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
@@ -1013,115 +1015,6 @@ int dsdb_schema_from_ldb_results(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
return LDB_SUCCESS;
}
-/*
- Given an LDB, and the DN, return a populated schema
-*/
-
-int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
- struct smb_iconv_convenience *iconv_convenience,
- struct ldb_dn *schema_dn,
- struct dsdb_schema **schema,
- char **error_string_out)
-{
- TALLOC_CTX *tmp_ctx;
- char *error_string;
- int ret;
-
- struct ldb_result *schema_res;
- struct ldb_result *a_res;
- struct ldb_result *c_res;
- static const char *schema_attrs[] = {
- "prefixMap",
- "schemaInfo",
- "fSMORoleOwner",
- NULL
- };
- unsigned flags;
-
- tmp_ctx = talloc_new(mem_ctx);
- if (!tmp_ctx) {
- dsdb_oom(error_string_out, mem_ctx);
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- /* we don't want to trace the schema load */
- flags = ldb_get_flags(ldb);
- ldb_set_flags(ldb, flags & ~LDB_FLG_ENABLE_TRACING);
-
- /*
- * setup the prefix mappings and schema info
- */
- ret = ldb_search(ldb, tmp_ctx, &schema_res,
- schema_dn, LDB_SCOPE_BASE, schema_attrs, NULL);
- if (ret == LDB_ERR_NO_SUCH_OBJECT) {
- goto failed;
- } else if (ret != LDB_SUCCESS) {
- *error_string_out = talloc_asprintf(mem_ctx,
- "dsdb_schema: failed to search the schema head: %s",
- ldb_errstring(ldb));
- goto failed;
- }
- if (schema_res->count != 1) {
- *error_string_out = talloc_asprintf(mem_ctx,
- "dsdb_schema: [%u] schema heads found on a base search",
- schema_res->count);
- goto failed;
- }
-
- /*
- * load the attribute definitions
- */
- ret = ldb_search(ldb, tmp_ctx, &a_res,
- schema_dn, LDB_SCOPE_ONELEVEL, NULL,
- "(objectClass=attributeSchema)");
- if (ret != LDB_SUCCESS) {
- *error_string_out = talloc_asprintf(mem_ctx,
- "dsdb_schema: failed to search attributeSchema objects: %s",
- ldb_errstring(ldb));
- goto failed;
- }
-
- /*
- * load the objectClass definitions
- */
- ret = ldb_search(ldb, tmp_ctx, &c_res,
- schema_dn, LDB_SCOPE_ONELEVEL, NULL,
- "(objectClass=classSchema)");
- if (ret != LDB_SUCCESS) {
- *error_string_out = talloc_asprintf(mem_ctx,
- "dsdb_schema: failed to search attributeSchema objects: %s",
- ldb_errstring(ldb));
- goto failed;
- }
-
- ret = dsdb_schema_from_ldb_results(tmp_ctx, ldb,
- lp_iconv_convenience(ldb_get_opaque(ldb, "loadparm")),
- schema_res, a_res, c_res, schema, &error_string);
- if (ret != LDB_SUCCESS) {
- *error_string_out = talloc_asprintf(mem_ctx,
- "dsdb_schema load failed: %s",
- error_string);
- goto failed;
- }
- talloc_steal(mem_ctx, *schema);
- talloc_free(tmp_ctx);
-
- if (flags & LDB_FLG_ENABLE_TRACING) {
- flags = ldb_get_flags(ldb);
- ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
- }
-
- return LDB_SUCCESS;
-
-failed:
- if (flags & LDB_FLG_ENABLE_TRACING) {
- flags = ldb_get_flags(ldb);
- ldb_set_flags(ldb, flags | LDB_FLG_ENABLE_TRACING);
- }
- talloc_free(tmp_ctx);
- return ret;
-}
-
static const struct {
const char *name;
diff --git a/source4/dsdb/schema/schema_set.c b/source4/dsdb/schema/schema_set.c
index 6f09f63596..9f22b32334 100644
--- a/source4/dsdb/schema/schema_set.c
+++ b/source4/dsdb/schema/schema_set.c
@@ -346,7 +346,10 @@ int dsdb_set_schema(struct ldb_context *ldb, struct dsdb_schema *schema)
return ret;
}
- schema_fill_constructed(schema);
+ ret = schema_fill_constructed(schema);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
ret = ldb_set_opaque(ldb, "dsdb_schema", schema);
if (ret != LDB_SUCCESS) {
diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c
index 4c27de7cb7..e9c924583e 100644
--- a/source4/lib/ldb/common/ldb.c
+++ b/source4/lib/ldb/common/ldb.c
@@ -1358,14 +1358,6 @@ int ldb_modify(struct ldb_context *ldb,
return ret;
}
- if (message->num_elements == 0) {
- /* this needs also to be returned when the specified object
- doesn't exist. Therefore this test is located here. */
- ldb_asprintf_errstring(ldb, "LDB message has to have elements/attributes (%s)!",
- ldb_dn_get_linearized(message->dn));
- return LDB_ERR_UNWILLING_TO_PERFORM;
- }
-
ret = ldb_build_mod_req(&req, ldb, ldb,
message,
NULL,
diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c
index ea29a09a2a..69b8ed0bf4 100644
--- a/source4/lib/ldb/common/ldb_modules.c
+++ b/source4/lib/ldb/common/ldb_modules.c
@@ -96,6 +96,12 @@ const char **ldb_modules_list_from_string(struct ldb_context *ldb, TALLOC_CTX *m
}
talloc_steal(modules, modstr);
+ if (modstr[0] == '\0') {
+ modules[0] = NULL;
+ m = (const char **)modules;
+ return m;
+ }
+
i = 0;
/* The str*r*chr walks backwards: This is how we get the inverse order mentioned above */
while ((p = strrchr(modstr, ',')) != NULL) {
@@ -331,7 +337,7 @@ int ldb_load_modules_list(struct ldb_context *ldb, const char **module_list, str
module = backend;
- for (i = 0; module_list[i] != NULL; i++) {
+ for (i = 0; module_list && module_list[i] != NULL; i++) {
struct ldb_module *current;
const struct ldb_module_ops *ops;
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 7693ffeb81..4943f81df5 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -179,6 +179,8 @@ static int ltdb_check_special_dn(struct ldb_module *module,
/* we have @ATTRIBUTES, let's check attributes are fine */
/* should we check that we deny multivalued attributes ? */
for (i = 0; i < msg->num_elements; i++) {
+ if (ldb_attr_cmp(msg->elements[i].name, "distinguishedName") == 0) continue;
+
for (j = 0; j < msg->elements[i].num_values; j++) {
if (ltdb_check_at_attributes_values(&msg->elements[i].values[j]) != 0) {
ldb_set_errstring(ldb, "Invalid attribute value in an @ATTRIBUTES entry");
@@ -205,12 +207,19 @@ static int ltdb_modified(struct ldb_module *module, struct ldb_dn *dn)
ret = ltdb_reindex(module);
}
+ /* If the modify was to a normal record, or any special except @BASEINFO, update the seq number */
if (ret == LDB_SUCCESS &&
!(ldb_dn_is_special(dn) &&
ldb_dn_check_special(dn, LTDB_BASEINFO)) ) {
ret = ltdb_increase_sequence_number(module);
}
+ /* If the modify was to @OPTIONS, reload the cache */
+ if (ldb_dn_is_special(dn) &&
+ (ldb_dn_check_special(dn, LTDB_OPTIONS)) ) {
+ ret = ltdb_cache_reload(module);
+ }
+
return ret;
}
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 869cd75465..bf2e22046a 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -429,7 +429,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
hostname = hostname.lower()
if dnsdomain is None:
- dnsdomain = lp.get("realm")
+ dnsdomain = lp.get("realm").lower()
if serverrole is None:
serverrole = lp.get("server role")
@@ -441,8 +441,6 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
raise Exception("realm '%s' in %s must match chosen realm '%s'" %
(lp.get("realm"), lp.configfile, realm))
- dnsdomain = dnsdomain.lower()
-
if serverrole == "domain controller":
if domain is None:
domain = lp.get("workgroup")
@@ -454,20 +452,21 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None,
else:
domain = netbiosname
if domaindn is None:
- domaindn = "CN=" + netbiosname
+ domaindn = "DC=" + netbiosname
assert domain is not None
domain = domain.upper()
+
if not valid_netbios_name(domain):
raise InvalidNetbiosName(domain)
- if netbiosname.upper() == realm.upper():
+ if netbiosname.upper() == realm:
raise Exception("realm %s must not be equal to netbios domain name %s", realm, netbiosname)
- if hostname.upper() == realm.upper():
+ if hostname.upper() == realm:
raise Exception("realm %s must not be equal to hostname %s", realm, hostname)
- if domain.upper() == realm.upper():
+ if domain.upper() == realm:
raise Exception("realm %s must not be equal to domain name %s", realm, domain)
if rootdn is None:
@@ -883,9 +882,9 @@ def setup_self_join(samdb, names,
"""Join a host to its own domain."""
assert isinstance(invocationid, str)
if ntdsguid is not None:
- ntdsguid_mod = "objectGUID: %s\n"%ntdsguid
+ ntdsguid_line = "objectGUID: %s\n"%ntdsguid
else:
- ntdsguid_mod = ""
+ ntdsguid_line = ""
setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), {
"CONFIGDN": names.configdn,
"SCHEMADN": names.schemadn,
@@ -901,7 +900,7 @@ def setup_self_join(samdb, names,
"DOMAIN": names.domain,
"DNSDOMAIN": names.dnsdomain,
"SAMBA_VERSION_STRING": version,
- "NTDSGUID": ntdsguid_mod,
+ "NTDSGUID": ntdsguid_line,
"DOMAIN_CONTROLLER_FUNCTIONALITY": str(domainControllerFunctionality)})
setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), {
@@ -1010,22 +1009,17 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
samdb.set_invocation_id(invocationid)
message("Adding DomainDN: %s" % names.domaindn)
- if serverrole == "domain controller":
- domain_oc = "domainDNS"
- else:
- domain_oc = "samba4LocalDomain"
#impersonate domain admin
admin_session_info = admin_session(lp, str(domainsid))
samdb.set_session_info(admin_session_info)
if domainguid is not None:
- domainguid_mod = "objectGUID: %s\n-" % domainguid
+ domainguid_line = "objectGUID: %s\n-" % domainguid
else:
- domainguid_mod = ""
+ domainguid_line = ""
setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), {
"DOMAINDN": names.domaindn,
- "DOMAIN_OC": domain_oc,
- "DOMAINGUID": domainguid_mod
+ "DOMAINGUID": domainguid_line
})
diff --git a/source4/setup/provision_basedn.ldif b/source4/setup/provision_basedn.ldif
index 0a5f618e84..eea8d4f148 100644
--- a/source4/setup/provision_basedn.ldif
+++ b/source4/setup/provision_basedn.ldif
@@ -3,6 +3,6 @@
################################
dn: ${DOMAINDN}
objectClass: top
-objectClass: ${DOMAIN_OC}
+objectClass: domaindns
instanceType: 5
${DOMAINGUID}
diff --git a/source4/setup/schema_samba4.ldif b/source4/setup/schema_samba4.ldif
index f447bf5617..ba867499d7 100644
--- a/source4/setup/schema_samba4.ldif
+++ b/source4/setup/schema_samba4.ldif
@@ -197,26 +197,29 @@ oMSyntax: 20
# Based on domainDNS, but without the DNS bits.
#
-dn: CN=Samba4-Local-Domain,${SCHEMADN}
-objectClass: top
-objectClass: classSchema
-cn: Samba4-Local-Domain
-subClassOf: top
-governsID: 1.3.6.1.4.1.7165.4.2.2
-rDNAttID: cn
-adminDisplayName: Samba4-Local-Domain
-adminDescription: Samba4-Local-Domain
-systemMayContain: msDS-Behavior-Version
-systemMayContain: managedBy
-objectClassCategory: 1
-lDAPDisplayName: samba4LocalDomain
-schemaIDGUID: 07be1647-8310-4fba-91ae-34e55d5a8293
-systemOnly: FALSE
-systemAuxiliaryClass: samDomain
-defaultSecurityDescriptor: D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)
-systemFlags: 16
-defaultHidingValue: TRUE
-defaultObjectCategory: CN=Samba4-Local-Domain,${SCHEMADN}
+#
+# Not used anymore
+#
+#dn: CN=Samba4-Local-Domain,${SCHEMADN}
+#objectClass: top
+#objectClass: classSchema
+#cn: Samba4-Local-Domain
+#subClassOf: top
+#governsID: 1.3.6.1.4.1.7165.4.2.2
+#rDNAttID: cn
+#adminDisplayName: Samba4-Local-Domain
+#adminDescription: Samba4-Local-Domain
+#systemMayContain: msDS-Behavior-Version
+#systemMayContain: managedBy
+#objectClassCategory: 1
+#lDAPDisplayName: samba4LocalDomain
+#schemaIDGUID: 07be1647-8310-4fba-91ae-34e55d5a8293
+#systemOnly: FALSE
+#systemAuxiliaryClass: samDomain
+#defaultSecurityDescriptor: D:(A;;RPLCLORC;;;DA)(A;;RPWPCRCCDCLCLORCWOWDSDDTSW;;;SY)(A;;RPLCLORC;;;AU)
+#systemFlags: 16
+#defaultHidingValue: TRUE
+#defaultObjectCategory: CN=Samba4-Local-Domain,${SCHEMADN}
dn: CN=Samba4Top,${SCHEMADN}