Copyright (C) Andrew Bartlett 2002.
Copyright (C) Gerald Carter 2003.
Copyright (C) Tim Potter 2003.
+ Copyright (C) Guenther Deschner 2008.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
#include "includes.h"
+#include "system/filesys.h"
+#include "librpc/gen_ndr/ndr_krb5pac.h"
+#include "../libcli/security/security.h"
+#include "util_tdb.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;
+ }
+
+ path = cache_path(NETSAMLOGON_TDB);
+again:
+ tdb = tdb_open_log(path, 0, TDB_DEFAULT|TDB_INCOMPATIBLE_HASH,
+ 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;
}
- return (netsamlogon_tdb != NULL);
+ netsamlogon_tdb = tdb;
+ return true;
+
+clear:
+ if (!first_try) {
+ return false;
+ }
+ first_try = false;
+
+ DEBUG(0,("retry after truncate for '%s'\n", path));
+ truncate(path, 0);
+ goto again;
}
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(const struct dom_sid *user_sid)
{
- 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;
- }
+ fstring keystr;
- 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));
-
- /* Clear UG/SID cache entry */
-
- 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;
+ }
- DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str));
+ /* Prepare key as DOMAIN-SID/USER-RID string */
+ sid_to_fstring(keystr, 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);
}
/***********************************************************************
bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
{
TDB_DATA data;
- fstring keystr, tmp;
+ fstring keystr;
bool result = false;
- DOM_SID user_sid;
+ struct dom_sid user_sid;
time_t t = time(NULL);
TALLOC_CTX *mem_ctx;
DATA_BLOB blob;
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));
+ sid_to_fstring(keystr, &user_sid);
DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr));
/* Prepare data */
- if (!(mem_ctx = TALLOC_P( NULL, int))) {
+ if (!(mem_ctx = talloc( NULL, int))) {
DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n"));
return false;
}
/* 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;
free the user_info struct (malloc()'d memory)
***********************************************************************/
-struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid)
+struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const struct dom_sid *user_sid)
{
struct netr_SamInfo3 *info3 = NULL;
TDB_DATA data;
return NULL;
}
- info3 = TALLOC_ZERO_P(mem_ctx, struct netr_SamInfo3);
+ info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
if (!info3) {
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;
}
- info3 = talloc_memdup(mem_ctx, &r.info3, sizeof(r.info3));
+ info3 = (struct netr_SamInfo3 *)talloc_memdup(mem_ctx, &r.info3,
+ sizeof(r.info3));
done:
SAFE_FREE(data.dptr);
#endif
}
-bool netsamlogon_cache_have(const DOM_SID *user_sid)
+bool netsamlogon_cache_have(const struct dom_sid *user_sid)
{
TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have");
struct netr_SamInfo3 *info3 = NULL;