tdb_store: check returns for 0, not -1.
[samba.git] / source3 / libsmb / samlogon_cache.c
index 7af93cf2e042de6b5c2f7473fdbf9b992bb69cc5..618a570c4e05a20d89ef3886d8570663f3accdc0 100644 (file)
 */
 
 #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"
 
@@ -34,12 +37,43 @@ static TDB_CONTEXT *netsamlogon_tdb = NULL;
 
 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|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;
+       }
+
+       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;
 }
 
 
@@ -60,14 +94,9 @@ bool netsamlogon_cache_shutdown(void)
  Clear cache getpwnam and getgroups entries from the winbindd cache
 ***********************************************************************/
 
-void netsamlogon_clear_cached_user(struct netr_SamInfo3 *info3)
+void netsamlogon_clear_cached_user(const struct dom_sid *user_sid)
 {
-       DOM_SID user_sid;
-       fstring keystr, tmp;
-
-       if (!info3) {
-               return;
-       }
+       fstring keystr;
 
        if (!netsamlogon_cache_init()) {
                DEBUG(0,("netsamlogon_clear_cached_user: cannot open "
@@ -75,11 +104,9 @@ void netsamlogon_clear_cached_user(struct netr_SamInfo3 *info3)
                        NETSAMLOGON_TDB));
                return;
        }
-       sid_copy(&user_sid, info3->base.domain_sid);
-       sid_append_rid(&user_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_clear_cached_user: SID [%s]\n", keystr));
 
@@ -94,9 +121,9 @@ void netsamlogon_clear_cached_user(struct netr_SamInfo3 *info3)
 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;
@@ -113,17 +140,16 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
                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;
        }
@@ -142,7 +168,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
                NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
        }
 
-       ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &r,
+       ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &r,
                                       (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry);
        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
                DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n"));
@@ -153,7 +179,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
        data.dsize = blob.length;
        data.dptr = blob.data;
 
-       if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) {
+       if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) == 0) {
                result = true;
        }
 
@@ -167,7 +193,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
  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;
@@ -191,14 +217,14 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *
                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_blob_const(data.dptr, data.dsize);
 
-       ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &r,
+       ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
                                      (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry);
 
        if (DEBUGLEVEL >= 10) {
@@ -240,7 +266,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *
 #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;