LCOV - code coverage report
Current view: top level - source3/smbd - dnsregister.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 2 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    DNS-SD registration
       4             :    Copyright (C) Rishi Srivatsavai 2007
       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 "smbd/smbd.h"
      22             : 
      23             : /* Uses DNS service discovery (libdns_sd) to
      24             :  * register the SMB service. SMB service is registered
      25             :  * on ".local" domain via Multicast DNS & any
      26             :  * other unicast DNS domains available.
      27             :  *
      28             :  * Users use the smbclient -B (Browse) option to
      29             :  * browse for advertised SMB services.
      30             :  */
      31             : 
      32             : #define DNS_REG_RETRY_INTERVAL (5*60)  /* in seconds */
      33             : 
      34             : #ifdef WITH_DNSSD_SUPPORT
      35             : 
      36             : #include <dns_sd.h>
      37             : 
      38             : struct dns_reg_state {
      39             :         struct tevent_context *event_ctx;
      40             :         uint16_t port;
      41             :         DNSServiceRef srv_ref;
      42             :         struct tevent_timer *te;
      43             :         int fd;
      44             :         struct tevent_fd *fde;
      45             : };
      46             : 
      47             : static int dns_reg_state_destructor(struct dns_reg_state *dns_state)
      48             : {
      49             :         if (dns_state->srv_ref != NULL) {
      50             :                 /* Close connection to the mDNS daemon */
      51             :                 DNSServiceRefDeallocate(dns_state->srv_ref);
      52             :                 dns_state->srv_ref = NULL;
      53             :         }
      54             : 
      55             :         /* Clear event handler */
      56             :         TALLOC_FREE(dns_state->te);
      57             :         TALLOC_FREE(dns_state->fde);
      58             :         dns_state->fd = -1;
      59             : 
      60             :         return 0;
      61             : }
      62             : 
      63             : static void dns_register_smbd_retry(struct tevent_context *ctx,
      64             :                                     struct tevent_timer *te,
      65             :                                     struct timeval now,
      66             :                                     void *private_data);
      67             : static void dns_register_smbd_fde_handler(struct tevent_context *ev,
      68             :                                           struct tevent_fd *fde,
      69             :                                           uint16_t flags,
      70             :                                           void *private_data);
      71             : 
      72             : static bool dns_register_smbd_schedule(struct dns_reg_state *dns_state,
      73             :                                        struct timeval tval)
      74             : {
      75             :         dns_reg_state_destructor(dns_state);
      76             : 
      77             :         dns_state->te = tevent_add_timer(dns_state->event_ctx,
      78             :                                          dns_state,
      79             :                                          tval,
      80             :                                          dns_register_smbd_retry,
      81             :                                          dns_state);
      82             :         if (!dns_state->te) {
      83             :                 return false;
      84             :         }
      85             : 
      86             :         return true;
      87             : }
      88             : 
      89             : static void dns_register_smbd_retry(struct tevent_context *ctx,
      90             :                                     struct tevent_timer *te,
      91             :                                     struct timeval now,
      92             :                                     void *private_data)
      93             : {
      94             :         struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
      95             :                                           struct dns_reg_state);
      96             :         DNSServiceErrorType err;
      97             : 
      98             :         dns_reg_state_destructor(dns_state);
      99             : 
     100             :         DEBUG(6, ("registering _smb._tcp service on port %d\n",
     101             :                   dns_state->port));
     102             : 
     103             :         /* Register service with DNS. Connects with the mDNS
     104             :          * daemon running on the local system to perform DNS
     105             :          * service registration.
     106             :          */
     107             :         err = DNSServiceRegister(&dns_state->srv_ref, 0 /* flags */,
     108             :                         kDNSServiceInterfaceIndexAny,
     109             :                         NULL /* service name */,
     110             :                         "_smb._tcp" /* service type */,
     111             :                         NULL /* domain */,
     112             :                         "" /* SRV target host name */,
     113             :                         htons(dns_state->port),
     114             :                         0 /* TXT record len */,
     115             :                         NULL /* TXT record data */,
     116             :                         NULL /* callback func */,
     117             :                         NULL /* callback context */);
     118             : 
     119             :         if (err != kDNSServiceErr_NoError) {
     120             :                 /* Failed to register service. Schedule a re-try attempt.
     121             :                  */
     122             :                 DEBUG(3, ("unable to register with mDNS (err %d)\n", err));
     123             :                 goto retry;
     124             :         }
     125             : 
     126             :         dns_state->fd = DNSServiceRefSockFD(dns_state->srv_ref);
     127             :         if (dns_state->fd == -1) {
     128             :                 goto retry;
     129             :         }
     130             : 
     131             :         dns_state->fde = tevent_add_fd(dns_state->event_ctx,
     132             :                                        dns_state,
     133             :                                        dns_state->fd,
     134             :                                        TEVENT_FD_READ,
     135             :                                        dns_register_smbd_fde_handler,
     136             :                                        dns_state);
     137             :         if (!dns_state->fde) {
     138             :                 goto retry;
     139             :         }
     140             : 
     141             :         return;
     142             :  retry:
     143             :         dns_register_smbd_schedule(dns_state,
     144             :                 timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
     145             : }
     146             : 
     147             : /* Processes reply from mDNS daemon. Returns true if a reply was received */
     148             : static void dns_register_smbd_fde_handler(struct tevent_context *ev,
     149             :                                           struct tevent_fd *fde,
     150             :                                           uint16_t flags,
     151             :                                           void *private_data)
     152             : {
     153             :         struct dns_reg_state *dns_state = talloc_get_type_abort(private_data,
     154             :                                           struct dns_reg_state);
     155             :         DNSServiceErrorType err;
     156             : 
     157             :         err = DNSServiceProcessResult(dns_state->srv_ref);
     158             :         if (err != kDNSServiceErr_NoError) {
     159             :                 DEBUG(3, ("failed to process mDNS result (err %d), re-trying\n",
     160             :                             err));
     161             :                 goto retry;
     162             :         }
     163             : 
     164             :         talloc_free(dns_state);
     165             :         return;
     166             : 
     167             :  retry:
     168             :         dns_register_smbd_schedule(dns_state,
     169             :                 timeval_current_ofs(DNS_REG_RETRY_INTERVAL, 0));
     170             : }
     171             : 
     172             : bool smbd_setup_mdns_registration(struct tevent_context *ev,
     173             :                                   TALLOC_CTX *mem_ctx,
     174             :                                   uint16_t port)
     175             : {
     176             :         struct dns_reg_state *dns_state;
     177             : 
     178             :         dns_state = talloc_zero(mem_ctx, struct dns_reg_state);
     179             :         if (dns_state == NULL) {
     180             :                 return false;
     181             :         }
     182             :         dns_state->event_ctx = ev;
     183             :         dns_state->port = port;
     184             :         dns_state->fd = -1;
     185             : 
     186             :         talloc_set_destructor(dns_state, dns_reg_state_destructor);
     187             : 
     188             :         return dns_register_smbd_schedule(dns_state, timeval_zero());
     189             : }
     190             : 
     191             : #else /* WITH_DNSSD_SUPPORT */
     192             : 
     193           0 : bool smbd_setup_mdns_registration(struct tevent_context *ev,
     194             :                                   TALLOC_CTX *mem_ctx,
     195             :                                   uint16_t port)
     196             : {
     197           0 :         return true;
     198             : }
     199             : 
     200             : #endif /* WITH_DNSSD_SUPPORT */

Generated by: LCOV version 1.13