From e6ba224432bfcd64802222a3544bc38c179727cd Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Tue, 18 Sep 2012 14:24:38 -0400 Subject: AD: Detect domain controller compatibility version --- src/providers/ldap/sdap.c | 30 ++++++++++++++++++++++++++++++ src/providers/ldap/sdap.h | 13 +++++++++++++ src/providers/ldap/sdap_async.c | 1 + 3 files changed, 44 insertions(+) diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index 11ba9cf34..5c4a00557 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -903,6 +903,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, char *endptr = NULL; int ret; int i; + uint32_t dc_level; so = talloc_zero(memctx, struct sdap_server_opts); if (!so) { @@ -974,6 +975,35 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, } } } + + /* Detect Active Directory version if available */ + ret = sysdb_attrs_get_uint32_t(rootdse, + SDAP_ROOTDSE_ATTR_AD_VERSION, + &dc_level); + if (ret == EOK) { + /* Validate that the DC level matches an expected value */ + switch(dc_level) { + case DS_BEHAVIOR_WIN2000: + case DS_BEHAVIOR_WIN2003: + case DS_BEHAVIOR_WIN2008: + case DS_BEHAVIOR_WIN2008R2: + case DS_BEHAVIOR_WIN2012: + opts->dc_functional_level = dc_level; + DEBUG(SSSDBG_CONF_SETTINGS, + ("Setting AD compatibility level to [%d]\n", + opts->dc_functional_level)); + break; + default: + DEBUG(SSSDBG_MINOR_FAILURE, + ("Received invalid value for AD compatibility level. " + "Continuing without AD performance enhancements\n")); + } + } else if (ret != ENOENT) { + DEBUG(SSSDBG_MINOR_FAILURE, + ("Error detecting Active Directory compatibility level " + "(%s). Continuing without AD performance enhancements\n", + strerror(ret))); + } } if (!last_usn_name) { diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 01c33e421..d844ad636 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -129,6 +129,7 @@ struct sdap_ppolicy_data { #define SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS "namingContexts" #define SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT "defaultNamingContext" +#define SDAP_ROOTDSE_ATTR_AD_VERSION "domainControllerFunctionality" #define SDAP_IPA_USN "entryUSN" #define SDAP_IPA_LAST_USN "lastUSN" @@ -364,6 +365,17 @@ struct sdap_search_base { const char *filter; }; +/* Values from + * http://msdn.microsoft.com/en-us/library/cc223272%28v=prot.13%29.aspx + */ +enum dc_functional_level { + DS_BEHAVIOR_WIN2000 = 0, + DS_BEHAVIOR_WIN2003 = 2, + DS_BEHAVIOR_WIN2008 = 3, + DS_BEHAVIOR_WIN2008R2 = 4, + DS_BEHAVIOR_WIN2012 = 5 +}; + struct sdap_options { struct dp_option *basic; struct sdap_attr_map *gen_map; @@ -397,6 +409,7 @@ struct sdap_options { struct sdap_search_base **autofs_search_bases; bool support_matching_rule; + enum dc_functional_level dc_functional_level; }; struct sdap_server_opts { diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index 42c8dd680..e0440625d 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -855,6 +855,7 @@ struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx, "supportedFeatures", "supportedLDAPVersion", "supportedSASLMechanisms", + SDAP_ROOTDSE_ATTR_AD_VERSION, SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT, SDAP_IPA_LAST_USN, SDAP_AD_LAST_USN, NULL -- cgit