Make cli_session_setup_guest chainable
[ira/wip.git] / source3 / libsmb / dsgetdcname.c
index 08ab8cad145f2b8e7eac84143e43a55642ce72eb..5606b8e7c97fbfee38a7de628772b6db35fb32ae 100644 (file)
@@ -311,7 +311,7 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response *
 /****************************************************************
 ****************************************************************/
 
-#define RETURN_ON_FALSE(x) if (!x) return false;
+#define RETURN_ON_FALSE(x) if (!(x)) return false;
 
 static bool check_cldap_reply_required_flags(uint32_t ret_flags,
                                             uint32_t req_flags)
@@ -656,7 +656,7 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx,
                 * back to netbios lookups is that our DNS server doesn't know
                 * anything about the DC's   -- jerry */
 
-               if (!is_zero_addr(&r->ss)) {
+               if (!is_zero_addr((struct sockaddr *)(void *)&r->ss)) {
                        count++;
                        continue;
                }
@@ -1040,6 +1040,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx,
                        r->data.nt4 = logon1;
                        r->ntver = nt_version;
 
+                       map_netlogon_samlogon_response(r);
+
                        namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list);
 
                        goto make_reply;
@@ -1117,6 +1119,27 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx,
                                  num_dcs, info);
 }
 
+static bool is_closest_site(struct netr_DsRGetDCNameInfo *info)
+{
+       if (info->dc_flags & DS_SERVER_CLOSEST) {
+               return true;
+       }
+
+       if (!info->client_site_name) {
+               return true;
+       }
+
+       if (!info->dc_site_name) {
+               return false;
+       }
+
+       if (strcmp(info->client_site_name, info->dc_site_name) == 0) {
+               return true;
+       }
+
+       return false;
+}
+
 /********************************************************************
  dsgetdcname.
 
@@ -1134,6 +1157,8 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx,
        NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
        struct netr_DsRGetDCNameInfo *myinfo = NULL;
        char *query_site = NULL;
+       bool first = true;
+       struct netr_DsRGetDCNameInfo *first_info = NULL;
 
        DEBUG(10,("dsgetdcname: domain_name: %s, "
                  "domain_guid: %s, site_name: %s, flags: 0x%08x\n",
@@ -1161,7 +1186,6 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx,
        status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid,
                                    flags, query_site, &myinfo);
        if (NT_STATUS_IS_OK(status)) {
-               *info = myinfo;
                goto done;
        }
 
@@ -1174,12 +1198,27 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx,
                                        domain_guid, flags, query_site,
                                        &myinfo);
 
-       if (NT_STATUS_IS_OK(status)) {
-               *info = myinfo;
-       }
-
  done:
        SAFE_FREE(query_site);
 
-       return status;
+       if (!NT_STATUS_IS_OK(status)) {
+               if (!first) {
+                       *info = first_info;
+                       return NT_STATUS_OK;
+               }
+               return status;
+       }
+
+       if (!first) {
+               TALLOC_FREE(first_info);
+       } else if (!is_closest_site(myinfo)) {
+               first = false;
+               first_info = myinfo;
+               /* TODO: may use the next_closest_site here */
+               query_site = SMB_STRDUP(myinfo->client_site_name);
+               goto rediscover;
+       }
+
+       *info = myinfo;
+       return NT_STATUS_OK;
 }