s3: Remove use of iconv_convenience.
[vlendec/samba-autobuild/.git] / source3 / libsmb / samlogon_cache.c
index 0d855f4c6c7f40f7a850b963d144b8d954ea1998..738e4b328139cd2df0bffaee4f2c8d1af644a4de 100644 (file)
@@ -22,6 +22,7 @@
 */
 
 #include "includes.h"
+#include "librpc/gen_ndr/ndr_krb5pac.h"
 
 #define NETSAMLOGON_TDB        "netsamlogon_cache.tdb"
 
@@ -33,12 +34,50 @@ 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,
+                          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;
 }
 
 
@@ -59,48 +98,29 @@ bool netsamlogon_cache_shutdown(void)
  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);
 }
 
 /***********************************************************************
@@ -130,8 +150,7 @@ 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));
@@ -149,7 +168,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3)
        /* 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;
@@ -213,8 +232,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *
                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);
@@ -226,6 +244,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *
        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;
        }