Show that the NTLOGON and NETLOGON mailslots are *very* similar.
authorAndrew Bartlett <abartlet@samba.org>
Sat, 17 May 2008 03:24:29 +0000 (13:24 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 17 May 2008 03:24:29 +0000 (13:24 +1000)
Rework the mailslot infrustructure to cope, passing down the mailslot
name so that we can implement both in the same callback function.

Andrew Bartlett
(This used to be commit 89fdd77891529aa74bb920994b8b5959aae8ac2d)

source4/libcli/dgram/dgramsocket.c
source4/libcli/dgram/libdgram.h
source4/nbt_server/config.mk
source4/nbt_server/dgram/browse.c
source4/nbt_server/dgram/netlogon.c
source4/nbt_server/dgram/request.c
source4/nbt_server/irpc.c
source4/torture/nbt/dgram.c

index 06b7bd57714bab1415dd379121a3f4b6d03a6021..2cdda654efbd1a66714b6fe65bac2fa847b818e0 100644 (file)
@@ -88,7 +88,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock)
                struct dgram_mailslot_handler *dgmslot;
                dgmslot = dgram_mailslot_find(dgmsock, mailslot_name);
                if (dgmslot) {
-                       dgmslot->handler(dgmslot, packet, src);
+                       dgmslot->handler(dgmslot, packet, mailslot_name, src);
                } else {
                        DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name));
                }
index e1209e7a546f40eba7c5a71e269907a259beab05..51408d029e63a92944822960e360a301e22d42f7 100644 (file)
@@ -70,6 +70,7 @@ struct nbt_dgram_socket {
 
 typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, 
                                         struct nbt_dgram_packet *, 
+                                        const char *mailslot_name,
                                         struct socket_address *src);
 
 struct dgram_mailslot_handler {
index 84e6b661bff2ba7ec35255b939d3cde8752bf8ab..eb1aea65d79594555bdd0c043c57d15c826730b9 100644 (file)
@@ -44,7 +44,7 @@ PRIVATE_DEPENDENCIES = \
 # End SUBSYSTEM NBTD_DGRAM
 #######################
 
-NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o ntlogon.o browse.o)
+NBTD_DGRAM_OBJ_FILES = $(addprefix nbt_server/dgram/, request.o netlogon.o browse.o)
 
 #######################
 # Start SUBSYSTEM NBTD
index 2e12fa114a6af1f7086ee23481631a5740927382..36f0160e1b30de0af3db759a952f441643ce4878 100644 (file)
@@ -49,6 +49,7 @@ static const char *nbt_browse_opcode_string(enum nbt_browse_opcode r)
 */
 void nbtd_mailslot_browse_handler(struct dgram_mailslot_handler *dgmslot, 
                                  struct nbt_dgram_packet *packet, 
+                                 const char *mailslot_name,
                                  struct socket_address *src)
 {
        struct nbt_browse_packet *browse = talloc(dgmslot, struct nbt_browse_packet);
index 7fae6bc1f6c67d8db04e82b9c62a0f01a1b5697c..ae24a7cd2b1dfef862c1428556d53cc2bc337796 100644 (file)
@@ -4,7 +4,8 @@
    NBT datagram netlogon server
 
    Copyright (C) Andrew Tridgell       2005
-   
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
+  
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
@@ -26,9 +27,9 @@
 #include "dsdb/samdb/samdb.h"
 #include "auth/auth.h"
 #include "util/util_ldb.h"
-#include "librpc/gen_ndr/ndr_nbt.h"
 #include "param/param.h"
 #include "smbd/service_task.h"
+#include "cldap_server/cldap_server.h"
 
 /*
   reply to a GETDC request
 static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, 
                                struct nbtd_interface *iface,
                                struct nbt_dgram_packet *packet, 
+                               const char *mailslot_name,
                                const struct socket_address *src,
                                struct nbt_netlogon_packet *netlogon)
 {
        struct nbt_name *name = &packet->data.msg.dest_name;
        struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
-       struct nbt_netlogon_packet reply;
        struct nbt_netlogon_response_from_pdc *pdc;
        const char *ref_attrs[] = {"nETBIOSName", NULL};
        struct ldb_message **ref_res;
        struct ldb_context *samctx;
        struct ldb_dn *partitions_basedn;
+       struct nbt_netlogon_response netlogon_response;
        int ret;
 
-       /* only answer getdc requests on the PDC or LOGON names */
-       if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
+       /* only answer getdc requests on the PDC name */
+       if (name->type != NBT_NAME_PDC) {
                return;
        }
 
@@ -72,10 +74,11 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
        }
 
        /* setup a GETDC reply */
-       ZERO_STRUCT(reply);
-       reply.command = NETLOGON_RESPONSE_FROM_PDC;
-       pdc = &reply.req.response;
+       ZERO_STRUCT(netlogon_response);
+       netlogon_response.response_type = NETLOGON_GET_PDC;
+       pdc = &netlogon_response.get_pdc;
 
+       pdc->command = NETLOGON_RESPONSE_FROM_PDC;
        pdc->pdc_name         = lp_netbios_name(iface->nbtsrv->task->lp_ctx);
        pdc->unicode_pdc_name = pdc->pdc_name;
        pdc->domain_name      = samdb_result_string(ref_res[0], "nETBIOSName", name->name);;
@@ -83,38 +86,32 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot,
        pdc->lmnt_token       = 0xFFFF;
        pdc->lm20_token       = 0xFFFF;
 
-
-       packet->data.msg.dest_name.type = 0;
-
        dgram_mailslot_netlogon_reply(reply_iface->dgmsock, 
                                      packet, 
                                      lp_netbios_name(iface->nbtsrv->task->lp_ctx),
                                      netlogon->req.pdc.mailslot_name,
-                                     &reply);
+                                     &netlogon_response);
 }
 
 
 /*
   reply to a ADS style GETDC request
  */
-static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
-                                struct nbtd_interface *iface,
-                                struct nbt_dgram_packet *packet, 
-                                const struct socket_address *src,
-                                struct nbt_netlogon_packet *netlogon)
+static void nbtd_netlogon_samlogon(struct dgram_mailslot_handler *dgmslot,
+                                  struct nbtd_interface *iface,
+                                  struct nbt_dgram_packet *packet, 
+                                  const char *mailslot_name,
+                                  const struct socket_address *src,
+                                  struct nbt_netlogon_packet *netlogon)
 {
        struct nbt_name *name = &packet->data.msg.dest_name;
        struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
-       struct nbt_netlogon_packet reply;
-       struct nbt_netlogon_response_from_pdc2 *pdc;
        struct ldb_context *samctx;
-       const char *ref_attrs[] = {"nETBIOSName", "dnsRoot", "ncName", NULL};
-       const char *dom_attrs[] = {"objectGUID", NULL};
-       struct ldb_message **ref_res, **dom_res;
-       int ret;
-       const char **services = lp_server_services(iface->nbtsrv->task->lp_ctx);
        const char *my_ip = reply_iface->ip_address; 
-       struct ldb_dn *partitions_basedn;
+       struct dom_sid *sid;
+       struct nbt_netlogon_response netlogon_response;
+       NTSTATUS status;
+
        if (!my_ip) {
                DEBUG(0, ("Could not obtain own IP address for datagram socket\n"));
                return;
@@ -131,90 +128,30 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
                return;
        }
 
-       partitions_basedn = samdb_partitions_dn(samctx, packet);
-
-       ret = gendb_search(samctx, packet, partitions_basedn, &ref_res, ref_attrs,
-                                 "(&(&(nETBIOSName=%s)(objectclass=crossRef))(ncName=*))", 
-                                 name->name);
-       
-       if (ret != 1) {
-               DEBUG(2,("Unable to find domain reference '%s' in sam\n", name->name));
-               return;
+       if (netlogon->req.logon.sid_size) {
+               if (strcasecmp(mailslot_name, NBT_MAILSLOT_NTLOGON) == 0) {
+                       /* SID not permitted on NTLOGON (for some reason...) */ 
+                       return;
+               }
+               sid = &netlogon->req.logon.sid;
+       } else {
+               sid = NULL;
        }
 
-       /* try and find the domain */
-       ret = gendb_search_dn(samctx, packet, 
-                             samdb_result_dn(samctx, samctx, ref_res[0], "ncName", NULL), 
-                             &dom_res, dom_attrs);
-       if (ret != 1) {
-               DEBUG(2,("Unable to find domain from reference '%s' in sam\n",
-                        ldb_dn_get_linearized(ref_res[0]->dn)));
+       status = fill_netlogon_samlogon_response(samctx, packet, name->name, sid, NULL, 
+                                                netlogon->req.logon.user_name, src->addr, 
+                                                netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.samlogon);
+       if (!NT_STATUS_IS_OK(status)) {
                return;
        }
 
-       /* setup a GETDC reply */
-       ZERO_STRUCT(reply);
-       reply.command = NETLOGON_RESPONSE_FROM_PDC2;
-
-#if 0
-       /* newer testing shows that the reply command type is not
-          changed based on whether a username is given in the
-          reply. This was what was causing the w2k join to be so
-          slow */
-       if (netlogon->req.pdc2.user_name[0]) {
-               reply.command = NETLOGON_RESPONSE_FROM_PDC_USER;
-       }
-#endif
-
-       pdc = &reply.req.response2;
-
-       /* TODO: accurately depict which services we are running */
-       pdc->server_type      = 
-               NBT_SERVER_PDC | NBT_SERVER_GC | 
-               NBT_SERVER_DS | NBT_SERVER_TIMESERV |
-               NBT_SERVER_CLOSEST | NBT_SERVER_WRITABLE | 
-               NBT_SERVER_GOOD_TIMESERV;
-
-       /* hmm, probably a better way to do this */
-       if (str_list_check(services, "ldap")) {
-               pdc->server_type |= NBT_SERVER_LDAP;
-       }
-
-       if (str_list_check(services, "kdc")) {
-               pdc->server_type |= NBT_SERVER_KDC;
-       }
-
-       pdc->domain_uuid      = samdb_result_guid(dom_res[0], "objectGUID");
-       pdc->forest           = samdb_result_string(ref_res[0], "dnsRoot", 
-                                                   lp_realm(iface->nbtsrv->task->lp_ctx));
-       pdc->dns_domain       = samdb_result_string(ref_res[0], "dnsRoot", 
-                                                   lp_realm(iface->nbtsrv->task->lp_ctx));
-
-       /* TODO: get our full DNS name from somewhere else */
-       pdc->pdc_dns_name     = talloc_asprintf(packet, "%s.%s", 
-                                               strlower_talloc(packet, 
-                                                               lp_netbios_name(iface->nbtsrv->task->lp_ctx)), 
-                                               pdc->dns_domain);
-       pdc->domain           = samdb_result_string(ref_res[0], "nETBIOSName", name->name);;
-       pdc->pdc_name         = lp_netbios_name(iface->nbtsrv->task->lp_ctx);
-       pdc->user_name        = netlogon->req.pdc2.user_name;
-       /* TODO: we need to make sure these are in our DNS zone */
-       pdc->server_site      = "Default-First-Site-Name";
-       pdc->client_site      = "Default-First-Site-Name";
-       pdc->unknown          = 0x10; /* what is this? */
-       pdc->unknown2         = 2; /* and this ... */
-       pdc->pdc_ip           = my_ip;
-       pdc->nt_version       = 13;
-       pdc->lmnt_token       = 0xFFFF;
-       pdc->lm20_token       = 0xFFFF;
-
        packet->data.msg.dest_name.type = 0;
 
        dgram_mailslot_netlogon_reply(reply_iface->dgmsock, 
                                      packet, 
                                      lp_netbios_name(iface->nbtsrv->task->lp_ctx),
-                                     netlogon->req.pdc2.mailslot_name,
-                                     &reply);
+                                     netlogon->req.logon.mailslot_name,
+                                     &netlogon_response);
 }
 
 
@@ -223,6 +160,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot,
 */
 void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, 
                                    struct nbt_dgram_packet *packet, 
+                                   const char *mailslot_name,
                                    struct socket_address *src)
 {
        NTSTATUS status = NT_STATUS_NO_MEMORY;
@@ -246,15 +184,17 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot,
 
        DEBUG(2,("netlogon request to %s from %s:%d\n", 
                 nbt_name_string(netlogon, name), src->addr, src->port));
-       status = dgram_mailslot_netlogon_parse(dgmslot, netlogon, packet, netlogon);
+       status = dgram_mailslot_netlogon_parse_request(dgmslot, netlogon, packet, netlogon);
        if (!NT_STATUS_IS_OK(status)) goto failed;
 
        switch (netlogon->command) {
-       case NETLOGON_QUERY_FOR_PDC:
-               nbtd_netlogon_getdc(dgmslot, iface, packet, src, netlogon);
+       case LOGON_PRIMARY_QUERY:
+               nbtd_netlogon_getdc(dgmslot, iface, packet, mailslot_name, 
+                                   src, netlogon);
                break;
-       case NETLOGON_QUERY_FOR_PDC2:
-               nbtd_netlogon_getdc2(dgmslot, iface, packet, src, netlogon);
+       case LOGON_SAM_LOGON_REQUEST:
+               nbtd_netlogon_samlogon(dgmslot, iface, packet, mailslot_name, 
+                                      src, netlogon);
                break;
        default:
                DEBUG(2,("unknown netlogon op %d from %s:%d\n", 
index 205a5442092adea2eefec67eb02a38a5e0f8d656..277b64741d1890adb7e8f1c706958e9e48a9ad37 100644 (file)
@@ -35,8 +35,10 @@ static const struct {
        const char *mailslot_name;
        dgram_mailslot_handler_t handler;
 } mailslot_handlers[] = {
+       /* Handle both NTLOGON and NETLOGON in the same function, as
+        * they are very similar */
        { NBT_MAILSLOT_NETLOGON, nbtd_mailslot_netlogon_handler },
-       { NBT_MAILSLOT_NTLOGON,  nbtd_mailslot_ntlogon_handler },
+       { NBT_MAILSLOT_NTLOGON,  nbtd_mailslot_netlogon_handler },
        { NBT_MAILSLOT_BROWSE,   nbtd_mailslot_browse_handler }
 };
 
index d184d05388bc804fd00dc5ca0e37afdad173964d..3a70c98041aec18e5ea478a2c50ce90c46a1875a 100644 (file)
@@ -60,8 +60,9 @@ struct getdc_state {
 };
 
 static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, 
-                                    struct nbt_dgram_packet *packet, 
-                                    struct socket_address *src)
+                                     struct nbt_dgram_packet *packet, 
+                                     const char *mailslot_name,
+                                     struct socket_address *src)
 {
        struct getdc_state *s =
                talloc_get_type(dgmslot->private, struct getdc_state);
@@ -69,8 +70,8 @@ static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot,
        struct nbt_netlogon_response netlogon;
        NTSTATUS status;
 
-       status = dgram_mailslot_netlogon_parse(dgmslot, packet, packet,
-                                              &netlogon);
+       status = dgram_mailslot_netlogon_parse_response(dgmslot, packet, packet,
+                                                       &netlogon);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n",
                          nt_errstr(status)));
index 38cc20b3b9ae9633246473db976c52690b0ae120..ce5758977d832f17c5562ce00953714be538ae4d 100644 (file)
@@ -39,6 +39,7 @@
 */
 static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, 
                             struct nbt_dgram_packet *packet, 
+                            const char *mailslot_name,
                             struct socket_address *src)
 {
        NTSTATUS status;
@@ -378,6 +379,30 @@ static bool nbt_test_ntlogon(struct torture_context *tctx)
                event_loop_once(dgmsock->event_ctx);
        }
 
+       ZERO_STRUCT(logon);
+       logon.command = LOGON_PRIMARY_QUERY;
+       logon.req.pdc.computer_name = TEST_NAME;
+       logon.req.pdc.mailslot_name = dgmslot->mailslot_name;
+       logon.req.pdc.unicode_name  = TEST_NAME;
+       logon.req.pdc.nt_version    = 1;
+       logon.req.pdc.lmnt_token    = 0xFFFF;
+       logon.req.pdc.lm20_token    = 0xFFFF;
+
+       make_nbt_name_client(&myname, TEST_NAME);
+
+       dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, 
+                                          address, lp_dgram_port(tctx->lp_ctx));
+       torture_assert(tctx, dest != NULL, "Error getting address");
+       status = dgram_mailslot_netlogon_send(dgmsock, 
+                                             &name, dest, 
+                                             NBT_MAILSLOT_NTLOGON, 
+                                             &myname, &logon);
+       torture_assert_ntstatus_ok(tctx, status, "Failed to send ntlogon request");
+
+       while (timeval_elapsed(&tv) < 5 && replies == 0) {
+               event_loop_once(dgmsock->event_ctx);
+       }
+
        torture_leave_domain(join_ctx);
        return true;
 }