2 Unix SMB/CIFS implementation.
4 Winbind daemon connection manager
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
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 3 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program. If not, see <http://www.gnu.org/licenses/>.
30 * Negative connection cache implemented in terms of gencache API
32 * The negative connection cache stores names of servers which have
33 * been unresponsive so that we don't waste time repeatedly trying
34 * to contact them. It used to use an in-memory linked list, but
35 * this limited its utility to a single process
40 * prefix used for all entries put into the general cache
42 static const char NEGATIVE_CONN_CACHE_PREFIX
[] = "NEG_CONN_CACHE";
45 * Marshalls the domain and server name into the key for the gencache
48 * @param[in] domain required
49 * @param[in] server may be a FQDN or an IP address
50 * @return the resulting string, which the caller is responsible for
52 * @retval NULL returned on error
54 static char *negative_conn_cache_keystr(const char *domain
, const char *server
)
56 const char NEGATIVE_CONN_CACHE_KEY_FMT
[] = "%s/%s,%s";
59 SMB_ASSERT(domain
!= NULL
);
63 keystr
= talloc_asprintf(talloc_tos(),NEGATIVE_CONN_CACHE_KEY_FMT
,
64 NEGATIVE_CONN_CACHE_PREFIX
, domain
, server
);
66 DEBUG(0, ("negative_conn_cache_keystr: malloc error\n"));
73 * Marshalls the NT status into a printable value field for the gencache
77 * @return the resulting string, which the caller is responsible for
79 * @retval NULL returned on error
81 static char *negative_conn_cache_valuestr(NTSTATUS status
)
83 char *valuestr
= NULL
;
85 valuestr
= talloc_asprintf(talloc_tos(), "%x", NT_STATUS_V(status
));
86 if (valuestr
== NULL
) {
87 DEBUG(0, ("negative_conn_cache_valuestr: malloc error\n"));
94 * Un-marshalls the NT status from a printable field for the gencache
97 * @param[in] value The value field from the record
98 * @return the decoded NT status
99 * @retval NT_STATUS_OK returned on error
101 static NTSTATUS
negative_conn_cache_valuedecode(const char *value
)
103 NTSTATUS result
= NT_STATUS_OK
;
105 SMB_ASSERT(value
!= NULL
);
106 if (sscanf(value
, "%x", &(NT_STATUS_V(result
))) != 1)
107 DEBUG(0, ("negative_conn_cache_valuestr: unable to parse "
108 "value field '%s'\n", value
));
113 * Function passed to gencache_iterate to remove any matching items
116 * @param[in] key Key to the record found and to be deleted
117 * @param[in] value Value to the record (ignored)
118 * @param[in] timeout Timeout remaining for the record (ignored)
119 * @param[in] dptr Handle for passing additional data (ignored)
121 static void delete_matches(const char *key
, const char *value
,
122 time_t timeout
, void *dptr
)
129 * Checks for a given domain/server record in the negative cache
132 * @param[in] server may be either a FQDN or an IP address
133 * @return The cached failure status
134 * @retval NT_STATUS_OK returned if no record is found or an error occurs
136 NTSTATUS
check_negative_conn_cache( const char *domain
, const char *server
)
138 NTSTATUS result
= NT_STATUS_OK
;
142 key
= negative_conn_cache_keystr(domain
, server
);
146 if (gencache_get(key
, &value
, (time_t *) NULL
))
147 result
= negative_conn_cache_valuedecode(value
);
149 DEBUG(9,("check_negative_conn_cache returning result %d for domain %s "
150 "server %s\n", NT_STATUS_V(result
), domain
, server
));
157 * Delete any negative cache entry for the given domain/server
160 * @param[in] server may be either a FQDN or an IP address
162 void delete_negative_conn_cache(const char *domain
, const char *server
)
166 key
= negative_conn_cache_keystr(domain
, server
);
171 DEBUG(9,("delete_negative_conn_cache removing domain %s server %s\n",
180 * Add an entry to the failed connection cache
183 * @param[in] server may be a FQDN or an IP addr in printable form
184 * @param[in] result error to cache; must not be NT_STATUS_OK
186 void add_failed_connection_entry(const char *domain
, const char *server
,
192 SMB_ASSERT(!NT_STATUS_IS_OK(result
));
194 key
= negative_conn_cache_keystr(domain
, server
);
196 DEBUG(0, ("add_failed_connection_entry: key creation error\n"));
200 value
= negative_conn_cache_valuestr(result
);
202 DEBUG(0, ("add_failed_connection_entry: value creation error\n"));
206 if (gencache_set(key
, value
,
207 time((time_t *) NULL
)
208 + FAILED_CONNECTION_CACHE_TIMEOUT
))
209 DEBUG(9,("add_failed_connection_entry: added domain %s (%s) "
210 "to failed conn cache\n", domain
, server
));
212 DEBUG(1,("add_failed_connection_entry: failed to add "
213 "domain %s (%s) to failed conn cache\n",
223 * Deletes all records from the negative connection cache in all domains
225 void flush_negative_conn_cache( void )
227 flush_negative_conn_cache_for_domain("*");
232 * Deletes all records for a specified domain from the negative connection
235 * @param[in] domain String to match against domain portion of keys, or "*"
236 * to match all domains
238 void flush_negative_conn_cache_for_domain(const char *domain
)
240 char *key_pattern
= NULL
;
242 key_pattern
= negative_conn_cache_keystr(domain
,"*");
243 if (key_pattern
== NULL
) {
244 DEBUG(0, ("flush_negative_conn_cache_for_domain: "
245 "key creation error\n"));
249 gencache_iterate(delete_matches
, (void *) NULL
, key_pattern
);
250 DEBUG(8, ("flush_negative_conn_cache_for_domain: flushed domain %s\n",
254 TALLOC_FREE(key_pattern
);