root/source4/nbt_server/irpc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nbtd_information
  2. getdc_recv_netlogon_reply
  3. nbtd_getdcname
  4. nbtd_register_irpc

   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 "smbd/service_task.h"
  25 #include "smbd/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 static NTSTATUS nbtd_information(struct irpc_message *msg, 
     /* [<][>][^][v][top][bottom][index][help] */
  37                                  struct nbtd_information *r)
  38 {
  39         struct nbtd_server *server = talloc_get_type(msg->private_data,
  40                                                      struct nbtd_server);
  41 
  42         switch (r->in.level) {
  43         case NBTD_INFO_STATISTICS:
  44                 r->out.info.stats = &server->stats;
  45                 break;
  46         }
  47 
  48         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 static void getdc_recv_netlogon_reply(struct dgram_mailslot_handler *dgmslot, 
     /* [<][>][^][v][top][bottom][index][help] */
  64                                       struct nbt_dgram_packet *packet, 
  65                                       struct socket_address *src)
  66 {
  67         struct getdc_state *s =
  68                 talloc_get_type(dgmslot->private_data, struct getdc_state);
  69         const char *p;
  70         struct nbt_netlogon_response netlogon;
  71         NTSTATUS status;
  72 
  73         status = dgram_mailslot_netlogon_parse_response(dgmslot, packet, packet,
  74                                                         &netlogon);
  75         if (!NT_STATUS_IS_OK(status)) {
  76                 DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n",
  77                           nt_errstr(status)));
  78                 goto done;
  79         }
  80 
  81         /* We asked for version 1 only */
  82         if (netlogon.response_type == NETLOGON_SAMLOGON
  83             && netlogon.data.samlogon.ntver != NETLOGON_NT_VERSION_1) {
  84                 status = NT_STATUS_INVALID_NETWORK_RESPONSE;
  85                 goto done;
  86         }
  87 
  88         p = netlogon.data.samlogon.data.nt4.server;
  89 
  90         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));
  94 
  95         if (*p == '\\') p += 1;
  96         if (*p == '\\') p += 1;
  97         
  98         s->req->out.dcname = talloc_strdup(s->req, p);
  99         if (s->req->out.dcname == NULL) {
 100                 DEBUG(0, ("talloc failed\n"));
 101                 status = NT_STATUS_NO_MEMORY;
 102                 goto done;
 103         }
 104 
 105         status = NT_STATUS_OK;
 106 
 107  done:
 108         irpc_send_reply(s->msg, status);
 109 }
 110 
 111 static NTSTATUS nbtd_getdcname(struct irpc_message *msg, 
     /* [<][>][^][v][top][bottom][index][help] */
 112                                struct nbtd_getdcname *req)
 113 {
 114         struct nbtd_server *server =
 115                 talloc_get_type(msg->private_data, struct nbtd_server);
 116         struct nbtd_interface *iface = nbtd_find_request_iface(server, req->in.ip_address, true);
 117         struct getdc_state *s;
 118         struct nbt_netlogon_packet p;
 119         struct NETLOGON_SAM_LOGON_REQUEST *r;
 120         struct nbt_name src, dst;
 121         struct socket_address *dest;
 122         struct dgram_mailslot_handler *handler;
 123         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
 124 
 125         DEBUG(0, ("nbtd_getdcname called\n"));
 126 
 127         s = talloc(msg, struct getdc_state);
 128         NT_STATUS_HAVE_NO_MEMORY(s);
 129 
 130         s->msg = msg;
 131         s->req = req;
 132         
 133         handler = dgram_mailslot_temp(iface->dgmsock, NBT_MAILSLOT_GETDC,
 134                                       getdc_recv_netlogon_reply, s);
 135         NT_STATUS_HAVE_NO_MEMORY(handler);
 136         
 137         ZERO_STRUCT(p);
 138         p.command = LOGON_SAM_LOGON_REQUEST;
 139         r = &p.req.logon;
 140         r->request_count = 0;
 141         r->computer_name = req->in.my_computername;
 142         r->user_name = req->in.my_accountname;
 143         r->mailslot_name = handler->mailslot_name;
 144         r->acct_control = req->in.account_control;
 145         r->sid = *req->in.domain_sid;
 146         r->nt_version = NETLOGON_NT_VERSION_1;
 147         r->lmnt_token = 0xffff;
 148         r->lm20_token = 0xffff;
 149 
 150         make_nbt_name_client(&src, req->in.my_computername);
 151         make_nbt_name(&dst, req->in.domainname, 0x1c);
 152 
 153         dest = socket_address_from_strings(msg, iface->dgmsock->sock->backend_name, 
 154                                            req->in.ip_address, 138);
 155         NT_STATUS_HAVE_NO_MEMORY(dest);
 156 
 157         status = dgram_mailslot_netlogon_send(iface->dgmsock, 
 158                                               &dst, dest,
 159                                               NBT_MAILSLOT_NETLOGON, 
 160                                               &src, &p);
 161         if (!NT_STATUS_IS_OK(status)) {
 162                 DEBUG(0, ("dgram_mailslot_ntlogon_send failed: %s\n",
 163                           nt_errstr(status)));
 164                 return status;
 165         }
 166 
 167         msg->defer_reply = true;
 168         return NT_STATUS_OK;
 169 }
 170 
 171 
 172 /*
 173   register the irpc handlers for the nbt server
 174 */
 175 void nbtd_register_irpc(struct nbtd_server *nbtsrv)
     /* [<][>][^][v][top][bottom][index][help] */
 176 {
 177         NTSTATUS status;
 178         struct task_server *task = nbtsrv->task;
 179 
 180         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_INFORMATION, 
 181                                nbtd_information, nbtsrv);
 182         if (!NT_STATUS_IS_OK(status)) {
 183                 task_server_terminate(task, "nbtd failed to setup monitoring");
 184                 return;
 185         }
 186 
 187         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_GETDCNAME,
 188                                nbtd_getdcname, nbtsrv);
 189         if (!NT_STATUS_IS_OK(status)) {
 190                 task_server_terminate(task, "nbtd failed to setup getdcname "
 191                                       "handler");
 192                 return;
 193         }
 194 
 195         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_PROXY_WINS_CHALLENGE,
 196                                nbtd_proxy_wins_challenge, nbtsrv);
 197         if (!NT_STATUS_IS_OK(status)) {
 198                 task_server_terminate(task, "nbtd failed to setup wins challenge "
 199                                       "handler");
 200                 return;
 201         }
 202 
 203         status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_PROXY_WINS_RELEASE_DEMAND,
 204                                nbtd_proxy_wins_release_demand, nbtsrv);
 205         if (!NT_STATUS_IS_OK(status)) {
 206                 task_server_terminate(task, "nbtd failed to setup wins release demand "
 207                                       "handler");
 208                 return;
 209         }
 210 }

/* [<][>][^][v][top][bottom][index][help] */