LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_wins_byname.c (source / functions) Hit Total Coverage
Test: coverage report for fix-15632 9995c5c2 Lines: 46 65 70.8 %
Date: 2024-04-13 12:30:31 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    async implementation of WINBINDD_WINS_BYNAME
       4             :    Copyright (C) Volker Lendecke 2011
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "winbindd.h"
      22             : #include "libsmb/namequery.h"
      23             : #include "librpc/gen_ndr/ndr_winbind_c.h"
      24             : #include "libsmb/nmblib.h"
      25             : #include "lib/util/string_wrappers.h"
      26             : 
      27             : struct winbindd_wins_byname_state {
      28             :         struct tevent_context *ev;
      29             :         struct winbindd_request *request;
      30             :         struct sockaddr_storage *addrs;
      31             :         size_t num_addrs;
      32             : };
      33             : 
      34             : static void winbindd_wins_byname_wins_done(struct tevent_req *subreq);
      35             : static void winbindd_wins_byname_bcast_done(struct tevent_req *subreq);
      36             : 
      37           4 : struct tevent_req *winbindd_wins_byname_send(TALLOC_CTX *mem_ctx,
      38             :                                              struct tevent_context *ev,
      39             :                                              struct winbindd_cli_state *cli,
      40             :                                              struct winbindd_request *request)
      41             : {
      42           0 :         struct tevent_req *req, *subreq;
      43           0 :         struct winbindd_wins_byname_state *state;
      44             : 
      45           4 :         req = tevent_req_create(mem_ctx, &state,
      46             :                                 struct winbindd_wins_byname_state);
      47           4 :         if (req == NULL) {
      48           0 :                 return NULL;
      49             :         }
      50           4 :         state->ev = ev;
      51           4 :         state->request = request;
      52             : 
      53             :         /* Ensure null termination */
      54           4 :         request->data.winsreq[sizeof(request->data.winsreq)-1]='\0';
      55             : 
      56           4 :         D_NOTICE("[%s (%u)] Winbind external command WINS_BYNAME start.\n"
      57             :                  "Resolving wins byname for '%s'.\n",
      58             :                  cli->client_name,
      59             :                  (unsigned int)cli->pid,
      60             :                  request->data.winsreq);
      61             : 
      62           4 :         subreq = resolve_wins_send(state, ev, state->request->data.winsreq,
      63             :                                    0x20);
      64           4 :         if (tevent_req_nomem(subreq, req)) {
      65           0 :                 return tevent_req_post(req, ev);
      66             :         }
      67           4 :         tevent_req_set_callback(subreq, winbindd_wins_byname_wins_done, req);
      68           4 :         return req;
      69             : }
      70             : 
      71           4 : static void winbindd_wins_byname_wins_done(struct tevent_req *subreq)
      72             : {
      73           4 :         struct tevent_req *req = tevent_req_callback_data(
      74             :                 subreq, struct tevent_req);
      75           4 :         struct winbindd_wins_byname_state *state = tevent_req_data(
      76             :                 req, struct winbindd_wins_byname_state);
      77           0 :         NTSTATUS status;
      78             : 
      79           4 :         status = resolve_wins_recv(subreq, talloc_tos(), &state->addrs,
      80             :                                    &state->num_addrs, NULL);
      81           4 :         TALLOC_FREE(subreq);
      82           4 :         if (NT_STATUS_IS_OK(status)) {
      83           0 :                 tevent_req_done(req);
      84           0 :                 return;
      85             :         }
      86           4 :         subreq = name_resolve_bcast_send(state, state->ev,
      87           4 :                                          state->request->data.winsreq, 0x20);
      88           4 :         if (tevent_req_nomem(subreq, req)) {
      89           0 :                 return;
      90             :         }
      91           4 :         tevent_req_set_callback(subreq, winbindd_wins_byname_bcast_done, req);
      92             : }
      93             : 
      94           4 : static void winbindd_wins_byname_bcast_done(struct tevent_req *subreq)
      95             : {
      96           4 :         struct tevent_req *req = tevent_req_callback_data(
      97             :                 subreq, struct tevent_req);
      98           4 :         struct winbindd_wins_byname_state *state = tevent_req_data(
      99             :                 req, struct winbindd_wins_byname_state);
     100           0 :         NTSTATUS status;
     101             : 
     102           4 :         status = name_resolve_bcast_recv(subreq, talloc_tos(), &state->addrs,
     103             :                                          &state->num_addrs);
     104           4 :         TALLOC_FREE(subreq);
     105           4 :         if (tevent_req_nterror(req, status)) {
     106           0 :                 return;
     107             :         }
     108           4 :         tevent_req_done(req);
     109             : }
     110             : 
     111           4 : NTSTATUS winbindd_wins_byname_recv(struct tevent_req *req,
     112             :                                    struct winbindd_response *presp)
     113             : {
     114           4 :         struct winbindd_wins_byname_state *state = tevent_req_data(
     115             :                 req, struct winbindd_wins_byname_state);
     116           0 :         char *response;
     117           0 :         NTSTATUS status;
     118           0 :         size_t i;
     119             : 
     120           4 :         if (tevent_req_is_nterror(req, &status)) {
     121           0 :                 return status;
     122             :         }
     123             : 
     124           4 :         response = talloc_strdup(talloc_tos(), "");
     125           4 :         if (response == NULL) {
     126           0 :                 return NT_STATUS_NO_MEMORY;
     127             :         }
     128             : 
     129           4 :         D_NOTICE("Winbind external command WINS_BYNAME end.\n"
     130             :                  "Received %zu address(es).\n",
     131             :                  state->num_addrs);
     132           8 :         for (i=0; i<state->num_addrs; i++) {
     133           0 :                 char addr[INET6_ADDRSTRLEN];
     134           4 :                 print_sockaddr(addr, sizeof(addr), &state->addrs[i]);
     135           4 :                 D_NOTICE("%zu: %s\n", i, addr);
     136           4 :                 talloc_asprintf_addbuf(
     137             :                         &response, "%s%s", addr,
     138           4 :                         i < (state->num_addrs-1) ? " " : "");
     139             :         }
     140             : 
     141           4 :         talloc_asprintf_addbuf(
     142           4 :                 &response, "\t%s\n", state->request->data.winsreq);
     143           4 :         if (response == NULL) {
     144           0 :                 return NT_STATUS_NO_MEMORY;
     145             :         }
     146             : 
     147           4 :         if (talloc_get_size(response) > sizeof(presp->data.winsresp)) {
     148           0 :                 TALLOC_FREE(response);
     149           0 :                 return NT_STATUS_MARSHALL_OVERFLOW;
     150             :         }
     151           4 :         fstrcpy(presp->data.winsresp, response);
     152           4 :         TALLOC_FREE(response);
     153           4 :         return NT_STATUS_OK;
     154             : }

Generated by: LCOV version 1.14