const char *domain_name = NULL;
const char *pdc_ip;
bool different_domain = true;
+ bool force_remote_lookup = false;
uint32_t valid_flags;
+ uint32_t this_dc_valid_flags;
int dc_level;
ZERO_STRUCTP(r->out.info);
* ...
*/
- dc_level = dsdb_dc_functional_level(sam_ctx);
valid_flags = DSGETDC_VALID_FLAGS;
- if (dc_level >= DS_DOMAIN_FUNCTION_2012) {
- valid_flags |= DS_DIRECTORY_SERVICE_8_REQUIRED;
- }
- if (dc_level >= DS_DOMAIN_FUNCTION_2012_R2) {
- valid_flags |= DS_DIRECTORY_SERVICE_9_REQUIRED;
- }
- if (dc_level >= DS_DOMAIN_FUNCTION_2016) {
- valid_flags |= DS_DIRECTORY_SERVICE_10_REQUIRED;
- }
+
if (r->in.flags & ~valid_flags) {
/*
* TODO: add tests to prove this (maybe based on the
different_domain = false;
}
+ if (!different_domain) {
+ dc_level = dsdb_dc_functional_level(sam_ctx);
+
+ /*
+ * Do not return a local response if we do not support the
+ * functional level or feature (eg web services)
+ */
+ this_dc_valid_flags = valid_flags;
+
+ /* Samba does not implement this */
+ this_dc_valid_flags &= ~DS_WEB_SERVICE_REQUIRED;
+
+ if (dc_level < DS_DOMAIN_FUNCTION_2012) {
+ this_dc_valid_flags &= ~DS_DIRECTORY_SERVICE_8_REQUIRED;
+ }
+ if (dc_level < DS_DOMAIN_FUNCTION_2012_R2) {
+ this_dc_valid_flags &= ~DS_DIRECTORY_SERVICE_9_REQUIRED;
+ }
+ if (dc_level < DS_DOMAIN_FUNCTION_2016) {
+ this_dc_valid_flags &= ~DS_DIRECTORY_SERVICE_10_REQUIRED;
+ }
+ if (r->in.flags & ~this_dc_valid_flags) {
+ DBG_INFO("Forcing remote lookup to find another DC "
+ "in this domain %s with more features, "
+ "as this Samba DC is Functional level %d but flags are 0x08%x\n",
+ r->in.domain_name, dc_level, (unsigned int)r->in.flags);
+ force_remote_lookup = true;
+ }
+ }
+
/* Proof server site parameter "site_name" if it was specified */
server_site_name = samdb_server_site_name(sam_ctx, state);
W_ERROR_HAVE_NO_MEMORY(server_site_name);
- if (different_domain || (r->in.site_name != NULL &&
- (strcasecmp_m(r->in.site_name,
- server_site_name) != 0))) {
+ if (force_remote_lookup
+ || different_domain
+ || (r->in.site_name != NULL &&
+ (strcasecmp_m(r->in.site_name,
+ server_site_name) != 0))) {
struct dcerpc_binding_handle *irpc_handle = NULL;
struct tevent_req *subreq = NULL;