*/
#include "includes.h"
+#include "librpc/gen_ndr/ndr_krb5pac.h"
#define NETSAMLOGON_TDB "netsamlogon_cache.tdb"
bool netsamlogon_cache_init(void)
{
- if (!netsamlogon_tdb) {
- netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0,
- TDB_DEFAULT, O_RDWR | O_CREAT, 0600);
+ bool first_try = true;
+ const char *path = NULL;
+ int ret;
+ struct tdb_context *tdb;
+
+ if (netsamlogon_tdb) {
+ return true;
}
- return (netsamlogon_tdb != NULL);
+ path = cache_path(NETSAMLOGON_TDB);
+again:
+ tdb = tdb_open_log(path, 0, TDB_DEFAULT,
+ O_RDWR | O_CREAT, 0600);
+ if (tdb == NULL) {
+ DEBUG(0,("tdb_open_log('%s') - failed\n", path));
+ goto clear;
+ }
+
+ ret = tdb_check(tdb, NULL, NULL);
+ if (ret != 0) {
+ tdb_close(tdb);
+ DEBUG(0,("tdb_check('%s') - failed\n", path));
+ goto clear;
+ }
+
+ netsamlogon_tdb = tdb;
+ return true;
+
+clear:
+ if (!first_try) {
+ return false;
+ }
+ first_try = false;
+
+ DEBUG(0,("retry after CLEAR_IF_FIRST for '%s'\n", path));
+ tdb = tdb_open_log(path, 0, TDB_CLEAR_IF_FIRST,
+ O_RDWR | O_CREAT, 0600);
+ if (tdb) {
+ tdb_close(tdb);
+ goto again;
+ }
+ DEBUG(0,("tdb_open_log(%s) with CLEAR_IF_FIRST - failed\n", path));
+
+ return false;
}
Clear cache getpwnam and getgroups entries from the winbindd cache
***********************************************************************/
-void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, struct netr_SamInfo3 *info3)
+void netsamlogon_clear_cached_user(struct netr_SamInfo3 *info3)
{
- bool got_tdb = false;
- DOM_SID sid;
- fstring key_str, sid_string;
-
- /* We may need to call this function from smbd which will not have
- winbindd_cache.tdb open. Open the tdb if a NULL is passed. */
-
- if (!tdb) {
- tdb = tdb_open_log(lock_path("winbindd_cache.tdb"),
- WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- TDB_DEFAULT, O_RDWR, 0600);
- if (!tdb) {
- DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n"));
- return;
- }
- got_tdb = true;
- }
-
- sid_copy(&sid, info3->base.domain_sid);
- sid_append_rid(&sid, info3->base.rid);
-
- /* Clear U/SID cache entry */
-
- fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, &sid));
-
- DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str));
-
- tdb_delete(tdb, string_tdb_data(key_str));
+ DOM_SID user_sid;
+ fstring keystr, tmp;
- /* Clear UG/SID cache entry */
+ if (!info3) {
+ return;
+ }
- fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, &sid));
+ if (!netsamlogon_cache_init()) {
+ DEBUG(0,("netsamlogon_clear_cached_user: cannot open "
+ "%s for write!\n",
+ NETSAMLOGON_TDB));
+ return;
+ }
+ sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid);
- DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str));
+ /* Prepare key as DOMAIN-SID/USER-RID string */
+ slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid));
- tdb_delete(tdb, string_tdb_data(key_str));
+ DEBUG(10,("netsamlogon_clear_cached_user: SID [%s]\n", keystr));
- if (got_tdb) {
- tdb_close(tdb);
- }
+ tdb_delete_bystring(netsamlogon_tdb, keystr);
}
/***********************************************************************
return false;
}
- sid_copy(&user_sid, info3->base.domain_sid);
- sid_append_rid(&user_sid, info3->base.rid);
+ sid_compose(&user_sid, info3->base.domain_sid, info3->base.rid);
/* Prepare key as DOMAIN-SID/USER-RID string */
slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid));
/* so we fill it in since winbindd_getpwnam() makes use of it */
if (!info3->base.account_name.string) {
- info3->base.account_name.string = talloc_strdup(mem_ctx, username);
+ info3->base.account_name.string = talloc_strdup(info3, username);
}
r.timestamp = t;
goto done;
}
- blob.data = (uint8 *)data.dptr;
- blob.length = data.dsize;
+ blob = data_blob_const(data.dptr, data.dsize);
ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
(ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry);
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
DEBUG(0,("netsamlogon_cache_get: failed to pull entry from cache\n"));
tdb_delete(netsamlogon_tdb, data);
+ TALLOC_FREE(info3);
goto done;
}