LCOV - code coverage report
Current view: top level - source3/libsmb - conncache.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 28 72 38.9 %
Date: 2021-09-23 10:06:22 Functions: 3 7 42.9 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Winbind daemon connection manager
       5             : 
       6             :    Copyright (C) Tim Potter             2001
       7             :    Copyright (C) Andrew Bartlett        2002
       8             :    Copyright (C) Gerald (Jerry) Carter  2003
       9             :    Copyright (C) Marc VanHeyningen      2008
      10             :    Copyright (C) Volker Lendecke        2009
      11             : 
      12             :    This program is free software; you can redistribute it and/or modify
      13             :    it under the terms of the GNU General Public License as published by
      14             :    the Free Software Foundation; either version 3 of the License, or
      15             :    (at your option) any later version.
      16             : 
      17             :    This program is distributed in the hope that it will be useful,
      18             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :    GNU General Public License for more details.
      21             : 
      22             :    You should have received a copy of the GNU General Public License
      23             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             : */
      25             : 
      26             : 
      27             : #include "includes.h"
      28             : #include "lib/gencache.h"
      29             : 
      30             : /**
      31             :  * @file
      32             :  * Negative connection cache implemented in terms of gencache API
      33             :  *
      34             :  * The negative connection cache stores names of servers which have
      35             :  * been unresponsive so that we don't waste time repeatedly trying
      36             :  * to contact them.  It used to use an in-memory linked list, but
      37             :  * this limited its utility to a single process
      38             :  */
      39             : 
      40             : 
      41             : /**
      42             :  * Marshalls the domain and server name into the key for the gencache
      43             :  * record
      44             :  *
      45             :  * @param[in] domain required
      46             :  * @param[in] server may be a FQDN or an IP address
      47             :  * @return the resulting string, which the caller is responsible for
      48             :  *   SAFE_FREE()ing
      49             :  * @retval NULL returned on error
      50             :  */
      51        4591 : static char *negative_conn_cache_keystr(const char *domain, const char *server)
      52             : {
      53        4591 :         char *keystr = NULL;
      54             : 
      55        4591 :         if (domain == NULL) {
      56           0 :                 return NULL;
      57             :         }
      58        4591 :         if (server == NULL)
      59           0 :                 server = "";
      60             : 
      61        4591 :         keystr = talloc_asprintf(talloc_tos(), "NEG_CONN_CACHE/%s,%s",
      62             :                                  domain, server);
      63        4591 :         if (keystr == NULL) {
      64           0 :                 DEBUG(0, ("negative_conn_cache_keystr: malloc error\n"));
      65             :         }
      66             : 
      67        4591 :         return keystr;
      68             : }
      69             : 
      70             : /**
      71             :  * Marshalls the NT status into a printable value field for the gencache
      72             :  * record
      73             :  *
      74             :  * @param[in] status
      75             :  * @return the resulting string, which the caller is responsible for
      76             :  *   SAFE_FREE()ing
      77             :  * @retval NULL returned on error
      78             :  */
      79           0 : static char *negative_conn_cache_valuestr(NTSTATUS status)
      80             : {
      81           0 :         char *valuestr = NULL;
      82             : 
      83           0 :         valuestr = talloc_asprintf(talloc_tos(), "%x", NT_STATUS_V(status));
      84           0 :         if (valuestr == NULL) {
      85           0 :                 DEBUG(0, ("negative_conn_cache_valuestr: malloc error\n"));
      86             :         }
      87             : 
      88           0 :         return valuestr;
      89             : }
      90             : 
      91             : /**
      92             :  * Un-marshalls the NT status from a printable field for the gencache
      93             :  * record
      94             :  *
      95             :  * @param[in] value  The value field from the record
      96             :  * @return the decoded NT status
      97             :  * @retval NT_STATUS_OK returned on error
      98             :  */
      99           0 : static NTSTATUS negative_conn_cache_valuedecode(const char *value)
     100             : {
     101           0 :         unsigned int v = NT_STATUS_V(NT_STATUS_INTERNAL_ERROR);
     102             : 
     103           0 :         if (value == NULL) {
     104           0 :                 return NT_STATUS_INTERNAL_ERROR;
     105             :         }
     106           0 :         if (sscanf(value, "%x", &v) != 1) {
     107           0 :                 DEBUG(0, ("negative_conn_cache_valuedecode: unable to parse "
     108             :                           "value field '%s'\n", value));
     109             :         }
     110           0 :         return NT_STATUS(v);
     111             : }
     112             : 
     113             : /**
     114             :  * Function passed to gencache_iterate to remove any matching items
     115             :  * from the list
     116             :  *
     117             :  * @param[in] key Key to the record found and to be deleted
     118             :  * @param[in] value Value to the record (ignored)
     119             :  * @param[in] timeout Timeout remaining for the record (ignored)
     120             :  * @param[in] dptr Handle for passing additional data (ignored)
     121             :  */
     122           0 : static void delete_matches(const char *key, const char *value,
     123             :     time_t timeout, void *dptr)
     124             : {
     125           0 :         gencache_del(key);
     126           0 : }
     127             : 
     128             : 
     129             : /**
     130             :  * Checks for a given domain/server record in the negative cache
     131             :  *
     132             :  * @param[in] domain
     133             :  * @param[in] server may be either a FQDN or an IP address
     134             :  * @return The cached failure status
     135             :  * @retval NT_STATUS_OK returned if no record is found or an error occurs
     136             :  */
     137        2197 : NTSTATUS check_negative_conn_cache( const char *domain, const char *server)
     138             : {
     139        2197 :         NTSTATUS result = NT_STATUS_OK;
     140        2197 :         char *key = NULL;
     141        2197 :         char *value = NULL;
     142             : 
     143        2197 :         key = negative_conn_cache_keystr(domain, server);
     144        2197 :         if (key == NULL)
     145           0 :                 goto done;
     146             : 
     147        2197 :         if (gencache_get(key, talloc_tos(), &value, NULL))
     148           0 :                 result = negative_conn_cache_valuedecode(value);
     149        3358 :  done:
     150        2197 :         DEBUG(9,("check_negative_conn_cache returning result %d for domain %s "
     151             :                   "server %s\n", NT_STATUS_V(result), domain, server));
     152        2197 :         TALLOC_FREE(key);
     153        2197 :         TALLOC_FREE(value);
     154        2197 :         return result;
     155             : }
     156             : 
     157             : /**
     158             :  * Add an entry to the failed connection cache
     159             :  *
     160             :  * @param[in] domain
     161             :  * @param[in] server may be a FQDN or an IP addr in printable form
     162             :  * @param[in] result error to cache; must not be NT_STATUS_OK
     163             :  */
     164           0 : void add_failed_connection_entry(const char *domain, const char *server,
     165             :     NTSTATUS result)
     166             : {
     167           0 :         char *key = NULL;
     168           0 :         char *value = NULL;
     169             : 
     170           0 :         if (NT_STATUS_IS_OK(result)) {
     171             :                 /* Nothing failed here */
     172           0 :                 return;
     173             :         }
     174             : 
     175           0 :         key = negative_conn_cache_keystr(domain, server);
     176           0 :         if (key == NULL) {
     177           0 :                 DEBUG(0, ("add_failed_connection_entry: key creation error\n"));
     178           0 :                 goto done;
     179             :         }
     180             : 
     181           0 :         value = negative_conn_cache_valuestr(result);
     182           0 :         if (value == NULL) {
     183           0 :                 DEBUG(0, ("add_failed_connection_entry: value creation error\n"));
     184           0 :                 goto done;
     185             :         }
     186             : 
     187           0 :         if (gencache_set(key, value,
     188           0 :                          time(NULL) + FAILED_CONNECTION_CACHE_TIMEOUT))
     189           0 :                 DEBUG(9,("add_failed_connection_entry: added domain %s (%s) "
     190             :                           "to failed conn cache\n", domain, server ));
     191             :         else
     192           0 :                 DEBUG(1,("add_failed_connection_entry: failed to add "
     193             :                           "domain %s (%s) to failed conn cache\n",
     194             :                           domain, server));
     195             : 
     196           0 :  done:
     197           0 :         TALLOC_FREE(key);
     198           0 :         TALLOC_FREE(value);
     199           0 :         return;
     200             : }
     201             : 
     202             : /**
     203             :  * Deletes all records for a specified domain from the negative connection
     204             :  * cache
     205             :  *
     206             :  * @param[in] domain String to match against domain portion of keys, or "*"
     207             :  *  to match all domains
     208             :  */
     209        2394 : void flush_negative_conn_cache_for_domain(const char *domain)
     210             : {
     211        2394 :         char *key_pattern = NULL;
     212             : 
     213        2394 :         key_pattern = negative_conn_cache_keystr(domain,"*");
     214        2394 :         if (key_pattern == NULL) {
     215           0 :                 DEBUG(0, ("flush_negative_conn_cache_for_domain: "
     216             :                           "key creation error\n"));
     217           0 :                 goto done;
     218             :         }
     219             : 
     220        2394 :         gencache_iterate(delete_matches, NULL, key_pattern);
     221        2394 :         DEBUG(8, ("flush_negative_conn_cache_for_domain: flushed domain %s\n",
     222             :                   domain));
     223             : 
     224        2394 :  done:
     225        2394 :         TALLOC_FREE(key_pattern);
     226        2394 :         return;
     227             : }

Generated by: LCOV version 1.13