LCOV - code coverage report
Current view: top level - source3/utils - net_dns.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 52 77 67.5 %
Date: 2021-09-23 10:06:22 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /* 
       2             :    Samba Unix/Linux Dynamic DNS Update
       3             :    net ads commands
       4             : 
       5             :    Copyright (C) Krishna Ganugapati (krishnag@centeris.com)         2006
       6             :    Copyright (C) Gerald Carter                                      2006
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.  
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "utils/net.h"
      24             : #include "../lib/addns/dns.h"
      25             : #include "utils/net_dns.h"
      26             : 
      27             : #if defined(HAVE_KRB5)
      28             : 
      29             : /*********************************************************************
      30             : *********************************************************************/
      31             : 
      32          26 : DNS_ERROR DoDNSUpdate(char *pszServerName,
      33             :                       const char *pszDomainName, const char *pszHostName,
      34             :                       const struct sockaddr_storage *sslist, size_t num_addrs,
      35             :                       uint32_t flags, bool remove_host)
      36             : {
      37             :         DNS_ERROR err;
      38             :         struct dns_connection *conn;
      39             :         TALLOC_CTX *mem_ctx;
      40             :         OM_uint32 minor;
      41             :         struct dns_update_request *req, *resp;
      42             : 
      43          26 :         DEBUG(10,("DoDNSUpdate called with flags: 0x%08x\n", flags));
      44             : 
      45          26 :         if (!(flags & DNS_UPDATE_SIGNED) &&
      46           0 :             !(flags & DNS_UPDATE_UNSIGNED) &&
      47           0 :             !(flags & DNS_UPDATE_PROBE)) {
      48           0 :                 return ERROR_DNS_INVALID_PARAMETER;
      49             :         }
      50             : 
      51          26 :         if ( !remove_host && ((num_addrs <= 0) || !sslist) ) {
      52           0 :                 return ERROR_DNS_INVALID_PARAMETER;
      53             :         }
      54             : 
      55          26 :         if (!(mem_ctx = talloc_init("DoDNSUpdate"))) {
      56           0 :                 return ERROR_DNS_NO_MEMORY;
      57             :         }
      58             : 
      59          26 :         err = dns_open_connection( pszServerName, DNS_TCP, mem_ctx, &conn );
      60          26 :         if (!ERR_DNS_IS_OK(err)) {
      61           0 :                 goto error;
      62             :         }
      63             : 
      64          26 :         if (flags & DNS_UPDATE_PROBE) {
      65             : 
      66             :                 /*
      67             :                  * Probe if everything's fine
      68             :                  */
      69             : 
      70          26 :                 err = dns_create_probe(mem_ctx, pszDomainName, pszHostName,
      71             :                                        num_addrs, sslist, &req);
      72          26 :                 if (!ERR_DNS_IS_OK(err)) goto error;
      73             : 
      74          26 :                 err = dns_update_transaction(mem_ctx, conn, req, &resp);
      75             : 
      76          26 :                 if (!ERR_DNS_IS_OK(err)) {
      77           0 :                         DEBUG(3,("DoDNSUpdate: failed to probe DNS\n"));
      78           0 :                         goto error;
      79             :                 }
      80             : 
      81          26 :                 if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
      82           0 :                     (flags & DNS_UPDATE_PROBE_SUFFICIENT)) {
      83           0 :                         TALLOC_FREE(mem_ctx);
      84           0 :                         return ERROR_DNS_SUCCESS;
      85             :                 }
      86             :         }
      87             : 
      88          26 :         if (flags & DNS_UPDATE_UNSIGNED) {
      89             : 
      90             :                 /*
      91             :                  * First try without signing
      92             :                  */
      93             : 
      94          26 :                 err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName,
      95             :                                                 sslist, num_addrs, &req);
      96          26 :                 if (!ERR_DNS_IS_OK(err)) goto error;
      97             : 
      98          26 :                 err = dns_update_transaction(mem_ctx, conn, req, &resp);
      99          26 :                 if (!ERR_DNS_IS_OK(err)) {
     100           0 :                         DEBUG(3,("DoDNSUpdate: unsigned update failed\n"));
     101           0 :                         goto error;
     102             :                 }
     103             : 
     104          26 :                 if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
     105           0 :                     (flags & DNS_UPDATE_UNSIGNED_SUFFICIENT)) {
     106           0 :                         TALLOC_FREE(mem_ctx);
     107           0 :                         return ERROR_DNS_SUCCESS;
     108             :                 }
     109             :         }
     110             : 
     111             :         /*
     112             :          * Okay, we have to try with signing
     113             :          */
     114          26 :         if (flags & DNS_UPDATE_SIGNED) {
     115             :                 gss_ctx_id_t gss_context;
     116             :                 char *keyname;
     117             : 
     118          26 :                 err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName,
     119             :                                                 sslist, num_addrs, &req);
     120          26 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     121             : 
     122          26 :                 if (!(keyname = dns_generate_keyname( mem_ctx ))) {
     123           0 :                         err = ERROR_DNS_NO_MEMORY;
     124           0 :                         goto error;
     125             :                 }
     126             : 
     127          26 :                 err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
     128             :                                              keyname, &gss_context, DNS_SRV_ANY );
     129             : 
     130             :                 /* retry using the Windows 2000 DNS hack */
     131          26 :                 if (!ERR_DNS_IS_OK(err)) {
     132           0 :                         err = dns_negotiate_sec_ctx( pszDomainName, pszServerName,
     133             :                                                      keyname, &gss_context, 
     134             :                                                      DNS_SRV_WIN2000 );
     135             :                 }
     136             : 
     137          26 :                 if (!ERR_DNS_IS_OK(err))
     138           0 :                         goto error;
     139             : 
     140          26 :                 err = dns_sign_update(req, gss_context, keyname,
     141             :                                       "gss.microsoft.com", time(NULL), 3600);
     142             : 
     143          26 :                 gss_delete_sec_context(&minor, &gss_context, GSS_C_NO_BUFFER);
     144             : 
     145          26 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     146             : 
     147          26 :                 err = dns_update_transaction(mem_ctx, conn, req, &resp);
     148          26 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     149             : 
     150          26 :                 err = (dns_response_code(resp->flags) == DNS_NO_ERROR) ?
     151             :                         ERROR_DNS_SUCCESS : ERROR_DNS_UPDATE_FAILED;
     152             : 
     153          26 :                 if (!ERR_DNS_IS_OK(err)) {
     154           4 :                         DEBUG(3,("DoDNSUpdate: signed update failed\n"));
     155             :                 }
     156             :         }
     157             : 
     158             : 
     159          13 : error:
     160          26 :         TALLOC_FREE(mem_ctx);
     161          26 :         return err;
     162             : }
     163             : 
     164             : /*********************************************************************
     165             : *********************************************************************/
     166             : 
     167          34 : int get_my_ip_address( struct sockaddr_storage **pp_ss )
     168             : 
     169             : {
     170             :         int i, n;
     171          34 :         struct sockaddr_storage *list = NULL;
     172          34 :         int count = 0;
     173             : 
     174             :         /* Honor the configured list of interfaces to register */
     175             : 
     176          34 :         load_interfaces();
     177          34 :         n = iface_count();
     178             : 
     179          34 :         if (n <= 0) {
     180           0 :                 return -1;
     181             :         }
     182             : 
     183          34 :         if ( (list = SMB_MALLOC_ARRAY( struct sockaddr_storage, n )) == NULL ) {
     184           0 :                 return -1;
     185             :         }
     186             : 
     187         202 :         for ( i=0; i<n; i++ ) {
     188         168 :                 const struct sockaddr_storage *nic_sa_storage = NULL;
     189             : 
     190         168 :                 if ((nic_sa_storage = iface_n_sockaddr_storage(i)) == NULL)
     191           0 :                         continue;
     192             : 
     193             :                 /* Don't register loopback addresses */
     194         168 :                 if (is_loopback_addr((const struct sockaddr *)nic_sa_storage)) {
     195           0 :                         continue;
     196             :                 }
     197             : 
     198             :                 /* Don't register link-local addresses */
     199         168 :                 if (is_linklocal_addr(nic_sa_storage)) {
     200           0 :                         continue;
     201             :                 }
     202             : 
     203         168 :                 memcpy(&list[count++], nic_sa_storage, sizeof(struct sockaddr_storage));
     204             :         }
     205          34 :         *pp_ss = list;
     206             : 
     207          34 :         return count;
     208             : }
     209             : 
     210             : #endif  /* defined(HAVE_KRB5) */

Generated by: LCOV version 1.13