LCOV - code coverage report
Current view: top level - source4/nbt_server - irpc.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 11 93 11.8 %
Date: 2024-04-21 15:09:00 Functions: 1 4 25.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    irpc services for the NBT server
       5             : 
       6             :    Copyright (C) Andrew Tridgell        2005
       7             :    Copyright (C) Volker Lendecke        2005
       8             :    
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             :    
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             :    
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "samba/service_task.h"
      25             : #include "samba/service.h"
      26             : #include "nbt_server/nbt_server.h"
      27             : #include "nbt_server/wins/winsserver.h"
      28             : #include "librpc/gen_ndr/ndr_irpc.h"
      29             : #include "lib/socket/socket.h"
      30             : #include "libcli/resolve/resolve.h"
      31             : #include "librpc/gen_ndr/ndr_nbt.h"
      32             : 
      33             : /*
      34             :   serve out the nbt statistics
      35             : */
      36           0 : static NTSTATUS nbtd_information(struct irpc_message *msg, 
      37             :                                  struct nbtd_information *r)
      38             : {
      39           0 :         struct nbtd_server *server = talloc_get_type(msg->private_data,
      40             :                                                      struct nbtd_server);
      41             : 
      42           0 :         switch (r->in.level) {
      43           0 :         case NBTD_INFO_STATISTICS:
      44           0 :                 r->out.info.stats = &server->stats;
      45           0 :                 break;
      46             :         }
      47             : 
      48           0 :         return NT_STATUS_OK;
      49             : }
      50             : 
      51             : 
      52             : /*
      53             :   winbind needs to be able to do a getdc request, but most (all?) windows
      54             :   servers always send the reply to port 138, regardless of the request
      55             :   port. To cope with this we use a irpc request to the NBT server
      56             :   which has port 138 open, and thus can receive the replies
      57             : */
      58             : struct getdc_state {
      59             :         struct irpc_message *msg;
      60             :         struct nbtd_getdcname *req;
      61             : };
      62             : 
      63           0 : static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, 
      64             :                                       struct nbt_dgram_packet *packet, 
      65             :                                       struct socket_address *src)
      66             : {
      67           0 :         struct getdc_state *s =
      68           0 :                 talloc_get_type(dgmslot->private_data, struct getdc_state);
      69           0 :         const char *p;
      70           0 :         struct nbt_netlogon_response netlogon;
      71           0 :         NTSTATUS status;
      72             : 
      73           0 :         status = dgram_mailslot_netlogon_parse_response(packet, packet,
      74             :                                                         &netlogon);
      75           0 :         if (!NT_STATUS_IS_OK(status)) {
      76           0 :                 DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n",
      77             :                           nt_errstr(status)));
      78           0 :                 goto done;
      79             :         }
      80             : 
      81             :         /* We asked for version 1 only */
      82           0 :         if (netlogon.response_type == NETLOGON_SAMLOGON
      83           0 :             && netlogon.data.samlogon.ntver != NETLOGON_NT_VERSION_1) {
      84           0 :                 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
      85           0 :                 goto done;
      86             :         }
      87             : 
      88           0 :         p = netlogon.data.samlogon.data.nt4.pdc_name;
      89             : 
      90           0 :         DEBUG(10, ("NTLOGON_SAM_LOGON_REPLY: server: %s, user: %s, "
      91             :                    "domain: %s\n", p,
      92             :                    netlogon.data.samlogon.data.nt4.user_name,
      93             :                    netlogon.data.samlogon.data.nt4.domain_name));
      94             : 
      95           0 :         if (*p == '\\') p += 1;
      96           0 :         if (*p == '\\') p += 1;
      97             :         
      98           0 :         s->req->out.dcname = talloc_strdup(s->req, p);
      99           0 :         if (s->req->out.dcname == NULL) {
     100           0 :                 DEBUG(0, ("talloc failed\n"));
     101           0 :                 status = NT_STATUS_NO_MEMORY;
     102           0 :                 goto done;
     103             :         }
     104             : 
     105           0 :         status = NT_STATUS_OK;
     106             : 
     107           0 :  done:
     108           0 :         irpc_send_reply(s->msg, status);
     109           0 : }
     110             : 
     111           0 : static NTSTATUS nbtd_getdcname(struct irpc_message *msg, 
     112             :                                struct nbtd_getdcname *req)
     113             : {
     114           0 :         struct nbtd_server *server =
     115           0 :                 talloc_get_type(msg->private_data, struct nbtd_server);
     116           0 :         struct nbtd_interface *iface = nbtd_find_request_iface(server, req->in.ip_address, true);
     117           0 :         struct getdc_state *s;
     118           0 :         struct nbt_netlogon_packet p;
     119           0 :         struct NETLOGON_SAM_LOGON_REQUEST *r;
     120           0 :         struct nbt_name src, dst;
     121           0 :         struct socket_address *dest;
     122           0 :         struct dgram_mailslot_handler *handler;
     123           0 :         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
     124             : 
     125           0 :         DEBUG(0, ("nbtd_getdcname called\n"));
     126             : 
     127           0 :         s = talloc(msg, struct getdc_state);
     128           0 :         NT_STATUS_HAVE_NO_MEMORY(s);
     129             : 
     130           0 :         s->msg = msg;
     131           0 :         s->req = req;
     132             :         
     133           0 :         handler = dgram_mailslot_temp(iface->dgmsock, NBT_MAILSLOT_GETDC,
     134             :                                       getdc_recv_netlogon_reply, s);
     135           0 :         NT_STATUS_HAVE_NO_MEMORY(handler);
     136             :         
     137           0 :         ZERO_STRUCT(p);
     138           0 :         p.command = LOGON_SAM_LOGON_REQUEST;
     139           0 :         r = &p.req.logon;
     140           0 :         r->request_count = 0;
     141           0 :         r->computer_name = req->in.my_computername;
     142           0 :         r->user_name = req->in.my_accountname;
     143           0 :         r->mailslot_name = handler->mailslot_name;
     144           0 :         r->acct_control = req->in.account_control;
     145           0 :         r->sid = *req->in.domain_sid;
     146           0 :         r->nt_version = NETLOGON_NT_VERSION_1;
     147           0 :         r->lmnt_token = 0xffff;
     148           0 :         r->lm20_token = 0xffff;
     149             : 
     150           0 :         make_nbt_name_client(&src, req->in.my_computername);
     151           0 :         make_nbt_name(&dst, req->in.domainname, 0x1c);
     152             : 
     153           0 :         dest = socket_address_from_strings(msg, iface->dgmsock->sock->backend_name, 
     154             :                                            req->in.ip_address, 138);
     155           0 :         NT_STATUS_HAVE_NO_MEMORY(dest);
     156             : 
     157           0 :         status = dgram_mailslot_netlogon_send(iface->dgmsock, 
     158             :                                               &dst, dest,
     159             :                                               NBT_MAILSLOT_NETLOGON, 
     160             :                                               &src, &p);
     161           0 :         if (!NT_STATUS_IS_OK(status)) {
     162           0 :                 DEBUG(0, ("dgram_mailslot_ntlogon_send failed: %s\n",
     163             :                           nt_errstr(status)));
     164           0 :                 return status;
     165             :         }
     166             : 
     167           0 :         msg->defer_reply = true;
     168           0 :         return NT_STATUS_OK;
     169             : }
     170             : 
     171             : 
     172             : /*
     173             :   register the irpc handlers for the nbt server
     174             : */
     175          65 : void nbtd_register_irpc(struct nbtd_server *nbtsrv)
     176             : {
     177           2 :         NTSTATUS status;
     178          65 :         struct task_server *task = nbtsrv->task;
     179             : 
     180          65 :         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_INFORMATION, 
     181             :                                nbtd_information, nbtsrv);
     182          65 :         if (!NT_STATUS_IS_OK(status)) {
     183           0 :                 task_server_terminate(task, "nbtd failed to setup monitoring", true);
     184           0 :                 return;
     185             :         }
     186             : 
     187          65 :         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_GETDCNAME,
     188             :                                nbtd_getdcname, nbtsrv);
     189          65 :         if (!NT_STATUS_IS_OK(status)) {
     190           0 :                 task_server_terminate(task, "nbtd failed to setup getdcname "
     191             :                                       "handler", true);
     192           0 :                 return;
     193             :         }
     194             : 
     195          65 :         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_PROXY_WINS_CHALLENGE,
     196             :                                nbtd_proxy_wins_challenge, nbtsrv);
     197          65 :         if (!NT_STATUS_IS_OK(status)) {
     198           0 :                 task_server_terminate(task, "nbtd failed to setup wins challenge "
     199             :                                       "handler", true);
     200           0 :                 return;
     201             :         }
     202             : 
     203          65 :         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_PROXY_WINS_RELEASE_DEMAND,
     204             :                                nbtd_proxy_wins_release_demand, nbtsrv);
     205          65 :         if (!NT_STATUS_IS_OK(status)) {
     206           0 :                 task_server_terminate(task, "nbtd failed to setup wins release demand "
     207             :                                       "handler", true);
     208           0 :                 return;
     209             :         }
     210             : }

Generated by: LCOV version 1.14