nbt_server: Remove some unused parameters
[samba.git] / source4 / nbt_server / dgram / netlogon.c
index e3f52928bf4d2cd021f398429292c0749e2e324c..879e21dc63832fd6daa16425c3a2a5eaecfb824c 100644 (file)
@@ -4,10 +4,11 @@
    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 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "dlinklist.h"
 #include "nbt_server/nbt_server.h"
-#include "smbd/service_task.h"
 #include "lib/socket/socket.h"
+#include <ldb.h>
+#include "dsdb/samdb/samdb.h"
+#include "auth/auth.h"
+#include "param/param.h"
+#include "smbd/service_task.h"
+#include "dsdb/samdb/ldb_modules/util.h"
+#include "libcli/security/security.h"
+#include "nbt_server/dgram/proto.h"
+#include "libds/common/roles.h"
 
 /*
   reply to a GETDC request
  */
-static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, 
+static void nbtd_netlogon_getdc(struct nbtd_interface *iface,
                                struct nbt_dgram_packet *packet, 
-                               const char *src_address, int src_port,
+                               const struct socket_address *src,
                                struct nbt_netlogon_packet *netlogon)
 {
        struct nbt_name *name = &packet->data.msg.dest_name;
-       struct nbt_netlogon_packet reply;
+       struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
        struct nbt_netlogon_response_from_pdc *pdc;
+       struct ldb_context *samctx;
+       struct nbt_netlogon_response netlogon_response;
 
        /* only answer getdc requests on the PDC or LOGON names */
        if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
                return;
        }
 
+       samctx = iface->nbtsrv->sam_ctx;
+
+       if (lpcfg_server_role(iface->nbtsrv->task->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC
+           || !samdb_is_pdc(samctx)) {
+               DEBUG(2, ("Not a PDC, so not processing LOGON_PRIMARY_QUERY\n"));
+               return;         
+       }
+
+       if (strcasecmp_m(name->name, lpcfg_workgroup(iface->nbtsrv->task->lp_ctx)) != 0) {
+               DEBUG(5,("GetDC requested for a domian %s that we don't host\n", name->name));
+               return;
+       }
+
        /* 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.data.get_pdc;
 
-       pdc->pdc_name         = lp_netbios_name();
+       pdc->command = NETLOGON_RESPONSE_FROM_PDC;
+       pdc->pdc_name         = lpcfg_netbios_name(iface->nbtsrv->task->lp_ctx);
        pdc->unicode_pdc_name = pdc->pdc_name;
-       pdc->domain_name      = lp_workgroup();
+       pdc->domain_name      = lpcfg_workgroup(iface->nbtsrv->task->lp_ctx);
        pdc->nt_version       = 1;
        pdc->lmnt_token       = 0xFFFF;
        pdc->lm20_token       = 0xFFFF;
 
-
-       packet->data.msg.dest_name.type = 0;
-
-       dgram_mailslot_netlogon_reply(dgmslot->dgmsock, 
+       dgram_mailslot_netlogon_reply(reply_iface->dgmsock, 
                                      packet, 
+                                     lpcfg_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 nbt_dgram_packet *packet, 
-                                const char *src_address, int src_port,
-                                struct nbt_netlogon_packet *netlogon)
+static void nbtd_netlogon_samlogon(struct nbtd_interface *iface,
+                                  struct nbt_dgram_packet *packet, 
+                                  const struct socket_address *src,
+                                  struct nbt_netlogon_packet *netlogon)
 {
        struct nbt_name *name = &packet->data.msg.dest_name;
-       struct nbt_netlogon_packet reply;
-       struct nbt_netlogon_response_from_pdc2 *pdc;
+       struct nbtd_interface *reply_iface = nbtd_find_reply_iface(iface, src->addr, false);
        struct ldb_context *samctx;
-       const char *attrs[] = {"realm", "dnsDomain", "objectGUID", NULL};
-       struct ldb_message **res;
-       int ret;
-       const char **services = lp_server_services();
+       const char *my_ip = reply_iface->ip_address; 
+       struct dom_sid *sid;
+       struct nbt_netlogon_response netlogon_response;
+       NTSTATUS status;
 
-       /* only answer getdc requests on the PDC or LOGON names */
-       if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
+       if (!my_ip) {
+               DEBUG(0, ("Could not obtain own IP address for datagram socket\n"));
                return;
        }
 
-       samctx = samdb_connect(packet);
-       if (samctx == NULL) {
-               DEBUG(2,("Unable to open sam in getdc reply\n"));
+       /* only answer getdc requests on the PDC or LOGON names */
+       if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) {
                return;
        }
 
-       /* try and find the domain */
-       ret = gendb_search(samctx, samctx, NULL, &res, attrs, 
-                          "(&(name=%s)(objectClass=domainDNS))", name->name);
-       if (ret != 1) {
-               DEBUG(2,("Unable to find domain '%s' in sam\n", name->name));
-               return;
-       }
+       samctx = iface->nbtsrv->sam_ctx;
 
-       /* setup a GETDC reply */
-       ZERO_STRUCT(reply);
-       if (netlogon->req.pdc2.user_name[0]) {
-               reply.command = NETLOGON_RESPONSE_FROM_PDC_USER;
+       if (netlogon->req.logon.sid_size) {
+               sid = &netlogon->req.logon.sid;
        } else {
-               reply.command = NETLOGON_RESPONSE_FROM_PDC2;
+               sid = NULL;
        }
-       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 (lp_parm_bool(-1, "gensec", "krb5", True)) {
-               pdc->server_type |= NBT_SERVER_KDC;
-       }
-       if (str_list_check(services, "ldap")) {
-               pdc->server_type |= NBT_SERVER_LDAP;
+
+       status = fill_netlogon_samlogon_response(samctx, packet, NULL, name->name, sid, NULL, 
+                                                netlogon->req.logon.user_name, netlogon->req.logon.acct_control, src->addr, 
+                                                netlogon->req.logon.nt_version, iface->nbtsrv->task->lp_ctx, &netlogon_response.data.samlogon, false);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(2,("NBT netlogon query failed domain=%s sid=%s version=%d - %s\n",
+                        name->name, dom_sid_string(packet, sid), netlogon->req.logon.nt_version, nt_errstr(status)));
+               return;
        }
 
-       pdc->domain_uuid      = samdb_result_guid(res[0], "objectGUID");
-       pdc->forest           = samdb_result_string(res[0], "realm", lp_realm());
-       pdc->dns_domain       = samdb_result_string(res[0], "dnsDomain", lp_realm());
-
-       /* TODO: get our full DNS name from somewhere else */
-       pdc->pdc_dns_name     = talloc_asprintf(packet, "%s.%s", 
-                                               lp_netbios_name(), pdc->dns_domain);
-       pdc->domain           = name->name;
-       pdc->pdc_name         = lp_netbios_name();
-       pdc->user_name        = netlogon->req.pdc2.user_name;
-       /* TODO: we need to make sure these are in our DNS zone */
-       pdc->site_name        = "Default-First-Site-Name";
-       pdc->site_name2       = "Default-First-Site-Name";
-       pdc->unknown          = 0x10; /* what is this? */
-       pdc->unknown2         = 2; /* and this ... */
-       pdc->pdc_ip           = socket_get_my_addr(dgmslot->dgmsock->sock, packet);
-       pdc->nt_version       = 13;
-       pdc->lmnt_token       = 0xFFFF;
-       pdc->lm20_token       = 0xFFFF;
+       netlogon_response.response_type = NETLOGON_SAMLOGON;
 
        packet->data.msg.dest_name.type = 0;
 
-       dgram_mailslot_netlogon_reply(dgmslot->dgmsock, 
+       dgram_mailslot_netlogon_reply(reply_iface->dgmsock, 
                                      packet, 
-                                     netlogon->req.pdc2.mailslot_name,
-                                     &reply);
+                                     lpcfg_netbios_name(iface->nbtsrv->task->lp_ctx),
+                                     netlogon->req.logon.mailslot_name,
+                                     &netlogon_response);
 }
 
 
@@ -159,11 +146,11 @@ 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 *src_address, int src_port)
+                                   struct socket_address *src)
 {
        NTSTATUS status = NT_STATUS_NO_MEMORY;
        struct nbtd_interface *iface = 
-               talloc_get_type(dgmslot->private, struct nbtd_interface);
+               talloc_get_type(dgmslot->private_data, struct nbtd_interface);
        struct nbt_netlogon_packet *netlogon = 
                talloc(dgmslot, struct nbt_netlogon_packet);
        struct nbtd_iface_name *iname;
@@ -180,23 +167,23 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot,
                goto failed;
        }
 
-       DEBUG(2,("netlogon request to %s from %s:%d\n", 
-                nbt_name_string(netlogon, name), src_address, src_port));
-       status = dgram_mailslot_netlogon_parse(dgmslot, netlogon, packet, netlogon);
+       DEBUG(5,("netlogon request to %s from %s:%d\n",
+                nbt_name_string(netlogon, name), src->addr, src->port));
+       status = dgram_mailslot_netlogon_parse_request(netlogon, packet,
+                                                      netlogon);
        if (!NT_STATUS_IS_OK(status)) goto failed;
 
-       NDR_PRINT_DEBUG(nbt_netlogon_packet, netlogon);
-
        switch (netlogon->command) {
-       case NETLOGON_QUERY_FOR_PDC:
-               nbtd_netlogon_getdc(dgmslot, packet, src_address, src_port, netlogon);
+       case LOGON_PRIMARY_QUERY:
+               nbtd_netlogon_getdc(iface, packet, src, netlogon);
                break;
-       case NETLOGON_QUERY_FOR_PDC2:
-               nbtd_netlogon_getdc2(dgmslot, packet, src_address, src_port, netlogon);
+       case LOGON_SAM_LOGON_REQUEST:
+               nbtd_netlogon_samlogon(iface, packet, src, netlogon);
                break;
        default:
                DEBUG(2,("unknown netlogon op %d from %s:%d\n", 
-                        netlogon->command, src_address, src_port));
+                        netlogon->command, src->addr, src->port));
+               NDR_PRINT_DEBUG(nbt_netlogon_packet, netlogon);
                break;
        }
 
@@ -204,7 +191,8 @@ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot,
        return;
 
 failed:
-       DEBUG(2,("nbtd netlogon handler failed from %s:%d - %s\n",
-                src_address, src_port, nt_errstr(status)));
+       DEBUG(2,("nbtd netlogon handler failed from %s:%d to %s - %s\n",
+                src->addr, src->port, nbt_name_string(netlogon, name),
+                nt_errstr(status)));
        talloc_free(netlogon);
 }