LCOV - code coverage report
Current view: top level - source3/utils - net_dns.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 75 119 63.0 %
Date: 2024-05-31 13:13:24 Functions: 3 3 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             : #include "auth/gensec/gensec.h"
      27             : #include "auth_generic.h"
      28             : 
      29             : #if defined(HAVE_KRB5)
      30             : 
      31             : /*********************************************************************
      32             : *********************************************************************/
      33             : 
      34          65 : static DNS_ERROR DoDNSUpdateNegotiateGensec(const char *pszServerName,
      35             :                                             const char *pszDomainName,
      36             :                                             const char *keyname,
      37             :                                             enum dns_ServerType srv_type,
      38             :                                             struct cli_credentials *creds,
      39             :                                             TALLOC_CTX *mem_ctx,
      40             :                                             struct gensec_security **_gensec)
      41             : {
      42          65 :         TALLOC_CTX *frame = talloc_stackframe();
      43          65 :         struct auth_generic_state *ans = NULL;
      44           0 :         NTSTATUS status;
      45           0 :         DNS_ERROR err;
      46             : 
      47          65 :         status = auth_generic_client_prepare(mem_ctx, &ans);
      48          65 :         if (!NT_STATUS_IS_OK(status)) {
      49           0 :                 err = ERROR_DNS_GSS_ERROR;
      50           0 :                 goto error;
      51             :         }
      52          65 :         talloc_steal(frame, ans);
      53             : 
      54          65 :         status = auth_generic_set_creds(ans, creds);
      55          65 :         if (!NT_STATUS_IS_OK(status)) {
      56           0 :                 err = ERROR_DNS_GSS_ERROR;
      57           0 :                 goto error;
      58             :         }
      59             : 
      60          65 :         status = gensec_set_target_service(ans->gensec_security,
      61             :                                            "dns");
      62          65 :         if (!NT_STATUS_IS_OK(status)) {
      63           0 :                 err = ERROR_DNS_GSS_ERROR;
      64           0 :                 goto error;
      65             :         }
      66             : 
      67          65 :         status = gensec_set_target_hostname(ans->gensec_security,
      68             :                                             pszServerName);
      69          65 :         if (!NT_STATUS_IS_OK(status)) {
      70           0 :                 err = ERROR_DNS_GSS_ERROR;
      71           0 :                 goto error;
      72             :         }
      73             : 
      74          65 :         gensec_want_feature(ans->gensec_security, GENSEC_FEATURE_SIGN);
      75             : 
      76          65 :         status = auth_generic_client_start(ans, GENSEC_OID_KERBEROS5);
      77          65 :         if (!NT_STATUS_IS_OK(status)) {
      78           0 :                 err = ERROR_DNS_GSS_ERROR;
      79           0 :                 goto error;
      80             :         }
      81             : 
      82          65 :         err = dns_negotiate_sec_ctx(pszServerName,
      83             :                                     keyname,
      84          65 :                                     ans->gensec_security,
      85             :                                     srv_type);
      86          65 :         if (!ERR_DNS_IS_OK(err)) {
      87           0 :                 goto error;
      88             :         }
      89             : 
      90          65 :         *_gensec = talloc_move(mem_ctx, &ans->gensec_security);
      91          65 :  error:
      92          65 :         TALLOC_FREE(frame);
      93             : 
      94          65 :         return err;
      95             : }
      96             : 
      97          68 : DNS_ERROR DoDNSUpdate(char *pszServerName,
      98             :                       const char *pszDomainName,
      99             :                       const char *pszHostName,
     100             :                       struct cli_credentials *creds,
     101             :                       const struct sockaddr_storage *sslist,
     102             :                       size_t num_addrs,
     103             :                       uint32_t flags,
     104             :                       uint32_t ttl,
     105             :                       bool remove_host)
     106             : {
     107           0 :         DNS_ERROR err;
     108           0 :         struct dns_connection *conn;
     109           0 :         TALLOC_CTX *mem_ctx;
     110           0 :         struct dns_update_request *req, *resp;
     111             : 
     112          68 :         DEBUG(10,("DoDNSUpdate called with flags: 0x%08x\n", flags));
     113             : 
     114          68 :         if (!(flags & DNS_UPDATE_SIGNED) &&
     115           0 :             !(flags & DNS_UPDATE_UNSIGNED) &&
     116           0 :             !(flags & DNS_UPDATE_PROBE)) {
     117           0 :                 return ERROR_DNS_INVALID_PARAMETER;
     118             :         }
     119             : 
     120          68 :         if ( !remove_host && ((num_addrs <= 0) || !sslist) ) {
     121           0 :                 return ERROR_DNS_INVALID_PARAMETER;
     122             :         }
     123             : 
     124          68 :         if (!(mem_ctx = talloc_init("DoDNSUpdate"))) {
     125           0 :                 return ERROR_DNS_NO_MEMORY;
     126             :         }
     127             : 
     128          68 :         err = dns_open_connection( pszServerName, DNS_TCP, mem_ctx, &conn );
     129          68 :         if (!ERR_DNS_IS_OK(err)) {
     130           0 :                 goto error;
     131             :         }
     132             : 
     133          68 :         if (flags & DNS_UPDATE_PROBE) {
     134             : 
     135             :                 /*
     136             :                  * Probe if everything's fine
     137             :                  */
     138             : 
     139          68 :                 err = dns_create_probe(mem_ctx, pszDomainName, pszHostName,
     140             :                                        num_addrs, sslist, &req);
     141          68 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     142             : 
     143          65 :                 err = dns_update_transaction(mem_ctx, conn, req, &resp);
     144             : 
     145          65 :                 if (!ERR_DNS_IS_OK(err)) {
     146           0 :                         DEBUG(3,("DoDNSUpdate: failed to probe DNS\n"));
     147           0 :                         goto error;
     148             :                 }
     149             : 
     150          65 :                 if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
     151           0 :                     (flags & DNS_UPDATE_PROBE_SUFFICIENT)) {
     152           0 :                         TALLOC_FREE(mem_ctx);
     153           0 :                         return ERROR_DNS_SUCCESS;
     154             :                 }
     155             :         }
     156             : 
     157          65 :         if (flags & DNS_UPDATE_UNSIGNED) {
     158             : 
     159             :                 /*
     160             :                  * First try without signing
     161             :                  */
     162             : 
     163          65 :                 err = dns_create_update_request(mem_ctx,
     164             :                                                 pszDomainName,
     165             :                                                 pszHostName,
     166             :                                                 sslist,
     167             :                                                 num_addrs,
     168             :                                                 ttl,
     169             :                                                 &req);
     170          65 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     171             : 
     172          65 :                 err = dns_update_transaction(mem_ctx, conn, req, &resp);
     173          65 :                 if (!ERR_DNS_IS_OK(err)) {
     174           0 :                         DEBUG(3,("DoDNSUpdate: unsigned update failed\n"));
     175           0 :                         goto error;
     176             :                 }
     177             : 
     178          65 :                 if ((dns_response_code(resp->flags) == DNS_NO_ERROR) &&
     179           0 :                     (flags & DNS_UPDATE_UNSIGNED_SUFFICIENT)) {
     180           0 :                         TALLOC_FREE(mem_ctx);
     181           0 :                         return ERROR_DNS_SUCCESS;
     182             :                 }
     183             :         }
     184             : 
     185             :         /*
     186             :          * Okay, we have to try with signing
     187             :          */
     188          65 :         if (flags & DNS_UPDATE_SIGNED) {
     189          65 :                 struct gensec_security *gensec = NULL;
     190          65 :                 char *keyname = NULL;
     191             : 
     192          65 :                 err = dns_create_update_request(mem_ctx,
     193             :                                                 pszDomainName,
     194             :                                                 pszHostName,
     195             :                                                 sslist,
     196             :                                                 num_addrs,
     197             :                                                 ttl,
     198             :                                                 &req);
     199          65 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     200             : 
     201          65 :                 if (!(keyname = dns_generate_keyname( mem_ctx ))) {
     202           0 :                         err = ERROR_DNS_NO_MEMORY;
     203           0 :                         goto error;
     204             :                 }
     205             : 
     206          65 :                 err = DoDNSUpdateNegotiateGensec(pszServerName,
     207             :                                                  pszDomainName,
     208             :                                                  keyname,
     209             :                                                  DNS_SRV_ANY,
     210             :                                                  creds,
     211             :                                                  mem_ctx,
     212             :                                                  &gensec);
     213             : 
     214             :                 /* retry using the Windows 2000 DNS hack */
     215          65 :                 if (!ERR_DNS_IS_OK(err)) {
     216           0 :                         err = DoDNSUpdateNegotiateGensec(pszServerName,
     217             :                                                          pszDomainName,
     218             :                                                          keyname,
     219             :                                                          DNS_SRV_WIN2000,
     220             :                                                          creds,
     221             :                                                          mem_ctx,
     222             :                                                          &gensec);
     223             :                 }
     224             : 
     225          65 :                 if (!ERR_DNS_IS_OK(err))
     226           0 :                         goto error;
     227             : 
     228          65 :                 err = dns_sign_update(req, gensec, keyname,
     229             :                                       "gss.microsoft.com", time(NULL), 3600);
     230             : 
     231          65 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     232             : 
     233          65 :                 err = dns_update_transaction(mem_ctx, conn, req, &resp);
     234          65 :                 if (!ERR_DNS_IS_OK(err)) goto error;
     235             : 
     236          97 :                 err = (dns_response_code(resp->flags) == DNS_NO_ERROR) ?
     237          32 :                         ERROR_DNS_SUCCESS : ERROR_DNS_UPDATE_FAILED;
     238             : 
     239          65 :                 if (!ERR_DNS_IS_OK(err)) {
     240          20 :                         DEBUG(3,("DoDNSUpdate: signed update failed\n"));
     241             :                 }
     242             :         }
     243             : 
     244             : 
     245           0 : error:
     246          68 :         TALLOC_FREE(mem_ctx);
     247          68 :         return err;
     248             : }
     249             : 
     250             : /*********************************************************************
     251             : *********************************************************************/
     252             : 
     253          48 : int get_my_ip_address( struct sockaddr_storage **pp_ss )
     254             : 
     255             : {
     256           0 :         int i, n;
     257          48 :         struct sockaddr_storage *list = NULL;
     258          48 :         int count = 0;
     259             : 
     260             :         /* Honor the configured list of interfaces to register */
     261             : 
     262          48 :         load_interfaces();
     263          48 :         n = iface_count();
     264             : 
     265          48 :         if (n <= 0) {
     266           0 :                 return -1;
     267             :         }
     268             : 
     269          48 :         if ( (list = SMB_MALLOC_ARRAY( struct sockaddr_storage, n )) == NULL ) {
     270           0 :                 return -1;
     271             :         }
     272             : 
     273         274 :         for ( i=0; i<n; i++ ) {
     274         226 :                 const struct sockaddr_storage *nic_sa_storage = NULL;
     275             : 
     276         226 :                 if ((nic_sa_storage = iface_n_sockaddr_storage(i)) == NULL)
     277           0 :                         continue;
     278             : 
     279             :                 /* Don't register loopback addresses */
     280         226 :                 if (is_loopback_addr((const struct sockaddr *)nic_sa_storage)) {
     281           0 :                         continue;
     282             :                 }
     283             : 
     284             :                 /* Don't register link-local addresses */
     285         226 :                 if (is_linklocal_addr(nic_sa_storage)) {
     286           0 :                         continue;
     287             :                 }
     288             : 
     289         226 :                 memcpy(&list[count++], nic_sa_storage, sizeof(struct sockaddr_storage));
     290             :         }
     291          48 :         *pp_ss = list;
     292             : 
     293          48 :         return count;
     294             : }
     295             : 
     296             : #endif  /* defined(HAVE_KRB5) */

Generated by: LCOV version 1.14