s4:netlogon RPC server - DsRGetDcNameEx - set the DNS name flags correctly
[obnox/samba/samba-obnox.git] / source4 / cldap_server / netlogon.c
index 92f7a4a752f7ef64c950f8e78e72896b2e4069d5..9d9f45e8bb0279d200884019c0a4a2ade893082f 100644 (file)
@@ -37,6 +37,7 @@
 #include "param/param.h"
 #include "../lib/tsocket/tsocket.h"
 #include "libds/common/flag_mapping.h"
+#include "lib/util/util_net.h"
 
 /*
   fill in the cldap netlogon union for a given version
@@ -133,22 +134,11 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                                                 "(&(objectCategory=DomainDNS)(objectGUID=%s))", 
                                                 ldb_binary_encode(mem_ctx, guid_val));
                } else { /* domain_sid case */
-                       struct dom_sid *sid;
-                       struct ldb_val sid_val;
-                       enum ndr_err_code ndr_err;
-                       
-                       /* Rather than go via the string, just push into the NDR form */
-                       ndr_err = ndr_push_struct_blob(&sid_val, mem_ctx, &sid,
-                                                      (ndr_push_flags_fn_t)ndr_push_dom_sid);
-                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                               return NT_STATUS_INVALID_PARAMETER;
-                       }
-
                        ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
-                                                NULL, LDB_SCOPE_SUBTREE, 
-                                                dom_attrs, 
-                                                "(&(objectCategory=DomainDNS)(objectSid=%s))",
-                                                ldb_binary_encode(mem_ctx, sid_val));
+                                        NULL, LDB_SCOPE_SUBTREE,
+                                        dom_attrs,
+                                        "(&(objectCategory=DomainDNS)(objectSid=%s))",
+                                        dom_sid_string(mem_ctx, domain_sid));
                }
                
                if (ret != LDB_SUCCESS) {
@@ -234,14 +224,8 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                
        server_type      = 
                DS_SERVER_DS | DS_SERVER_TIMESERV |
-               DS_SERVER_CLOSEST |
                DS_SERVER_GOOD_TIMESERV;
 
-#if 0
-       /* w2k8-r2 as a DC does not claim these */
-       server_type |= DS_DNS_CONTROLLER | DS_DNS_DOMAIN;
-#endif
-
        if (samdb_is_pdc(sam_ctx)) {
                server_type |= DS_SERVER_PDC;
        }
@@ -266,13 +250,6 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                server_type |= DS_SERVER_WRITABLE;
        }
 
-#if 0
-       /* w2k8-r2 as a sole DC does not claim this */
-       if (ldb_dn_compare(ldb_get_root_basedn(sam_ctx), ldb_get_default_basedn(sam_ctx)) == 0) {
-               server_type |= DS_DNS_FOREST_ROOT;
-       }
-#endif
-
        pdc_name         = talloc_asprintf(mem_ctx, "\\\\%s",
                                           lpcfg_netbios_name(lp_ctx));
        NT_STATUS_HAVE_NO_MEMORY(pdc_name);
@@ -286,22 +263,27 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                                           dns_domain);
        NT_STATUS_HAVE_NO_MEMORY(pdc_dns_name);
        flatname         = lpcfg_workgroup(lp_ctx);
+
        server_site      = samdb_server_site_name(sam_ctx, mem_ctx);
        NT_STATUS_HAVE_NO_MEMORY(server_site);
        client_site      = samdb_client_site_name(sam_ctx, mem_ctx,
                                                  src_address, NULL);
        NT_STATUS_HAVE_NO_MEMORY(client_site);
+       if (strcasecmp(server_site, client_site) == 0) {
+               server_type |= DS_SERVER_CLOSEST;
+       }
+
        load_interface_list(mem_ctx, lp_ctx, &ifaces);
-       /*
-        * TODO: the caller should pass the address which the client
-        * used to trigger this call, as the client is able to reach
-        * this ip.
-        */
        if (src_address) {
                pdc_ip = iface_list_best_ip(ifaces, src_address);
        } else {
                pdc_ip = iface_list_first_v4(ifaces);
        }
+       if (pdc_ip == NULL || !is_ipaddress_v4(pdc_ip)) {
+               /* this matches windows behaviour */
+               pdc_ip = "127.0.0.1";
+       }
+
        ZERO_STRUCTP(netlogon);
 
        /* check if either of these bits is present */
@@ -325,7 +307,7 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
                netlogon->data.nt5_ex.server_site  = server_site;
                netlogon->data.nt5_ex.client_site  = client_site;
                if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
-                       /* Clearly this needs to be fixed up for IPv6 */
+                       /* note that this is always a IPV4 address */
                        extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP;
                        netlogon->data.nt5_ex.sockaddr.sockaddr_family    = 2;
                        netlogon->data.nt5_ex.sockaddr.pdc_ip       = pdc_ip;