LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_ping_dc.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 45 60 75.0 %
Date: 2024-02-28 12:06:22 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    async implementation of WINBINDD_PING_DC
       4             :    Copyright (C) Volker Lendecke 2009
       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 "librpc/gen_ndr/ndr_winbind_c.h"
      23             : 
      24             : struct winbindd_ping_dc_state {
      25             :         const char *dcname;
      26             :         NTSTATUS result;
      27             : };
      28             : 
      29             : static void winbindd_ping_dc_done(struct tevent_req *subreq);
      30             : 
      31          57 : struct tevent_req *winbindd_ping_dc_send(TALLOC_CTX *mem_ctx,
      32             :                                          struct tevent_context *ev,
      33             :                                          struct winbindd_cli_state *cli,
      34             :                                          struct winbindd_request *request)
      35             : {
      36           0 :         struct tevent_req *req, *subreq;
      37           0 :         struct winbindd_ping_dc_state *state;
      38           0 :         struct winbindd_domain *domain;
      39             : 
      40          57 :         req = tevent_req_create(mem_ctx, &state,
      41             :                                 struct winbindd_ping_dc_state);
      42          57 :         if (req == NULL) {
      43           0 :                 return NULL;
      44             :         }
      45             : 
      46          57 :         if (request->domain_name[0] == '\0') {
      47             :                 /* preserve old behavior, when no domain name is given */
      48           4 :                 domain = find_our_domain();
      49             :         } else {
      50          53 :                 domain = find_trust_from_name_noinit(request->domain_name);
      51             :         }
      52          57 :         if (domain == NULL) {
      53           4 :                 tevent_req_nterror(req, NT_STATUS_NO_SUCH_DOMAIN);
      54           4 :                 return tevent_req_post(req, ev);
      55             :         }
      56          53 :         if (domain->internal) {
      57          26 :                 const char *d = lp_dnsdomain();
      58          26 :                 const char *n = lp_netbios_name();
      59             : 
      60             :                 /*
      61             :                  * Internal domains are passdb based, we can always
      62             :                  * contact them.
      63             :                  */
      64             : 
      65          26 :                 if (d != NULL) {
      66           0 :                         char *h;
      67          26 :                         h = strlower_talloc(mem_ctx, n);
      68          26 :                         if (tevent_req_nomem(h, req)) {
      69           0 :                                 return tevent_req_post(req, ev);
      70             :                         }
      71             : 
      72          26 :                         state->dcname = talloc_asprintf(state, "%s.%s", h, d);
      73          26 :                         TALLOC_FREE(h);
      74             : 
      75          26 :                         if (tevent_req_nomem(state->dcname, req)) {
      76           0 :                                 return tevent_req_post(req, ev);
      77             :                         }
      78             :                 } else {
      79           0 :                         state->dcname = talloc_strdup(state, n);
      80           0 :                         if (tevent_req_nomem(state->dcname, req)) {
      81           0 :                                 return tevent_req_post(req, ev);
      82             :                         }
      83             :                 }
      84             : 
      85          26 :                 tevent_req_done(req);
      86          26 :                 return tevent_req_post(req, ev);
      87             :         }
      88             : 
      89          27 :         subreq = dcerpc_wbint_PingDc_send(state, ev, dom_child_handle(domain),
      90          27 :                                           &state->dcname);
      91          27 :         if (tevent_req_nomem(subreq, req)) {
      92           0 :                 return tevent_req_post(req, ev);
      93             :         }
      94          27 :         tevent_req_set_callback(subreq, winbindd_ping_dc_done, req);
      95          27 :         return req;
      96             : }
      97             : 
      98          27 : static void winbindd_ping_dc_done(struct tevent_req *subreq)
      99             : {
     100          27 :         struct tevent_req *req = tevent_req_callback_data(
     101             :                 subreq, struct tevent_req);
     102          27 :         struct winbindd_ping_dc_state *state = tevent_req_data(
     103             :                 req, struct winbindd_ping_dc_state);
     104           0 :         NTSTATUS status, result;
     105             : 
     106          27 :         status = dcerpc_wbint_PingDc_recv(subreq, state, &result);
     107          27 :         state->result = result;
     108          27 :         if (any_nt_status_not_ok(status, result, &status)) {
     109           4 :                 tevent_req_nterror(req, status);
     110           4 :                 return;
     111             :         }
     112          23 :         tevent_req_done(req);
     113             : }
     114             : 
     115          57 : NTSTATUS winbindd_ping_dc_recv(struct tevent_req *req,
     116             :                                struct winbindd_response *presp)
     117             : {
     118          57 :         struct winbindd_ping_dc_state *state = tevent_req_data(
     119             :                 req, struct winbindd_ping_dc_state);
     120           0 :         NTSTATUS status;
     121             : 
     122          57 :         if (tevent_req_is_nterror(req, &status)) {
     123           8 :                 return status;
     124             :         }
     125             : 
     126          49 :         if (!NT_STATUS_IS_OK(state->result)) {
     127           0 :                 set_auth_errors(presp, state->result);
     128             :         }
     129             : 
     130          49 :         if (state->dcname) {
     131          49 :                 presp->extra_data.data = talloc_strdup(presp, state->dcname);
     132          49 :                 if (presp->extra_data.data == NULL) {
     133           0 :                         return NT_STATUS_NO_MEMORY;
     134             :                 }
     135          49 :                 presp->length += strlen((char *)presp->extra_data.data) + 1;
     136             :         }
     137             : 
     138          49 :         tevent_req_received(req);
     139          49 :         return NT_STATUS_OK;
     140             : }

Generated by: LCOV version 1.14