diff options
author | Garming Sam <garming@catalyst.net.nz> | 2017-03-20 15:37:12 +1300 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2017-05-30 08:06:06 +0200 |
commit | eaf2c3e21dffde4dad89ce2e6c6a5061cc9f435f (patch) | |
tree | d43501f8d58d107d805fd8ee111b83d0956b9f9b /source3 | |
parent | 3dcee68fa998b9cf10ac34d6b3720d79475ac8c9 (diff) | |
download | samba-eaf2c3e21dffde4dad89ce2e6c6a5061cc9f435f.tar.gz |
libads: Check cldap flags in libads/ldap
Pass down request flags and check they are respected with the response
flags. Otherwise, error out and pretend the connection never happened.
Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source3')
-rw-r--r-- | source3/libads/cldap.c | 38 | ||||
-rw-r--r-- | source3/libads/cldap.h | 3 | ||||
-rw-r--r-- | source3/libads/ldap.c | 12 | ||||
-rw-r--r-- | source3/libsmb/dsgetdcname.c | 37 |
4 files changed, 52 insertions, 38 deletions
diff --git a/source3/libads/cldap.c b/source3/libads/cldap.c index 586a04a0e42..f4022a19905 100644 --- a/source3/libads/cldap.c +++ b/source3/libads/cldap.c @@ -22,6 +22,7 @@ #include "includes.h" #include "../libcli/cldap/cldap.h" +#include "../librpc/gen_ndr/ndr_netlogon.h" #include "../lib/tsocket/tsocket.h" #include "../lib/util/tevent_ntstatus.h" #include "libads/cldap.h" @@ -47,6 +48,43 @@ struct cldap_multi_netlogon_state { static void cldap_multi_netlogon_done(struct tevent_req *subreq); static void cldap_multi_netlogon_next(struct tevent_req *subreq); +/**************************************************************** +****************************************************************/ + +#define RETURN_ON_FALSE(x) if (!(x)) return false; + +bool check_cldap_reply_required_flags(uint32_t ret_flags, + uint32_t req_flags) +{ + if (req_flags == 0) { + return true; + } + + if (req_flags & DS_PDC_REQUIRED) + RETURN_ON_FALSE(ret_flags & NBT_SERVER_PDC); + + if (req_flags & DS_GC_SERVER_REQUIRED) + RETURN_ON_FALSE(ret_flags & NBT_SERVER_GC); + + if (req_flags & DS_ONLY_LDAP_NEEDED) + RETURN_ON_FALSE(ret_flags & NBT_SERVER_LDAP); + + if ((req_flags & DS_DIRECTORY_SERVICE_REQUIRED) || + (req_flags & DS_DIRECTORY_SERVICE_PREFERRED)) + RETURN_ON_FALSE(ret_flags & NBT_SERVER_DS); + + if (req_flags & DS_KDC_REQUIRED) + RETURN_ON_FALSE(ret_flags & NBT_SERVER_KDC); + + if (req_flags & DS_TIMESERV_REQUIRED) + RETURN_ON_FALSE(ret_flags & NBT_SERVER_TIMESERV); + + if (req_flags & DS_WRITABLE_REQUIRED) + RETURN_ON_FALSE(ret_flags & NBT_SERVER_WRITABLE); + + return true; +} + /* * Do a parallel cldap ping to the servers. The first "min_servers" * are fired directly, the remaining ones in 100msec intervals. If diff --git a/source3/libads/cldap.h b/source3/libads/cldap.h index 9e42782052a..7fa1bdf8d60 100644 --- a/source3/libads/cldap.h +++ b/source3/libads/cldap.h @@ -27,6 +27,9 @@ /* The following definitions come from libads/cldap.c */ +bool check_cldap_reply_required_flags(uint32_t ret_flags, + uint32_t req_flags); + struct tevent_req *cldap_multi_netlogon_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, const struct tsocket_address * const *servers, diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index fdb729e90da..b2c57480f1e 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -279,7 +279,12 @@ static bool ads_try_connect(ADS_STRUCT *ads, bool gc, SAFE_FREE(ads->config.client_site_name); SAFE_FREE(ads->server.workgroup); - ads->config.flags = cldap_reply.server_type; + if (!check_cldap_reply_required_flags(cldap_reply.server_type, + ads->config.flags)) { + ret = false; + goto out; + } + ads->config.ldap_server_name = SMB_STRDUP(cldap_reply.pdc_dns_name); ads->config.realm = SMB_STRDUP(cldap_reply.dns_domain); if (!strupper_m(ads->config.realm)) { @@ -305,6 +310,9 @@ static bool ads_try_connect(ADS_STRUCT *ads, bool gc, sitename_store( cldap_reply.domain_name, cldap_reply.client_site); sitename_store( cldap_reply.dns_domain, cldap_reply.client_site); + /* Leave this until last so that the flags are not clobbered */ + ads->config.flags = cldap_reply.server_type; + ret = true; out: @@ -334,7 +342,9 @@ static NTSTATUS cldap_ping_list(ADS_STRUCT *ads,const char *domain, check_negative_conn_cache(domain, server))) continue; + /* Returns ok only if it matches the correct server type */ ok = ads_try_connect(ads, false, &ip_list[i].ss); + if (ok) { return NT_STATUS_OK; } diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index b5bc51dffae..92fc312c6a4 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -279,43 +279,6 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response * /**************************************************************** ****************************************************************/ -#define RETURN_ON_FALSE(x) if (!(x)) return false; - -static bool check_cldap_reply_required_flags(uint32_t ret_flags, - uint32_t req_flags) -{ - if (req_flags == 0) { - return true; - } - - if (req_flags & DS_PDC_REQUIRED) - RETURN_ON_FALSE(ret_flags & NBT_SERVER_PDC); - - if (req_flags & DS_GC_SERVER_REQUIRED) - RETURN_ON_FALSE(ret_flags & NBT_SERVER_GC); - - if (req_flags & DS_ONLY_LDAP_NEEDED) - RETURN_ON_FALSE(ret_flags & NBT_SERVER_LDAP); - - if ((req_flags & DS_DIRECTORY_SERVICE_REQUIRED) || - (req_flags & DS_DIRECTORY_SERVICE_PREFERRED)) - RETURN_ON_FALSE(ret_flags & NBT_SERVER_DS); - - if (req_flags & DS_KDC_REQUIRED) - RETURN_ON_FALSE(ret_flags & NBT_SERVER_KDC); - - if (req_flags & DS_TIMESERV_REQUIRED) - RETURN_ON_FALSE(ret_flags & NBT_SERVER_TIMESERV); - - if (req_flags & DS_WRITABLE_REQUIRED) - RETURN_ON_FALSE(ret_flags & NBT_SERVER_WRITABLE); - - return true; -} - -/**************************************************************** -****************************************************************/ - static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, const char *domain_name, const struct GUID *domain_guid, |