s3:libsmb: remove unused functions in clispnego.c
[sfrench/samba-autobuild/.git] / source3 / libsmb / samlogon_cache.c
index 235880910cdaca423de4a261d73674fb3ecb0988..c408082e8060e054ad51529c32614f7be018cfbc 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"
 
@@ -33,12 +37,48 @@ 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;
+       char *path = NULL;
+       int ret;
+       struct tdb_context *tdb;
+
+       if (netsamlogon_tdb) {
+               return true;
+       }
+
+       path = cache_path(NETSAMLOGON_TDB);
+       if (path == NULL) {
+               return false;
+       }
+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;
+       talloc_free(path);
+       return true;
+
+clear:
+       if (!first_try) {
+               talloc_free(path);
+               return false;
        }
+       first_try = false;
 
-       return (netsamlogon_tdb != NULL);
+       DEBUG(0,("retry after truncate for '%s'\n", path));
+       truncate(path, 0);
+       goto again;
 }
 
 
@@ -59,48 +99,23 @@ 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(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;
-       }
-
-       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 */
+       fstring keystr;
 
-       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);
 }
 
 /***********************************************************************
@@ -111,11 +126,11 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, 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;
+       TALLOC_CTX *tmp_ctx = talloc_stackframe();
        DATA_BLOB blob;
        enum ndr_err_code ndr_err;
        struct netsamlogoncache_entry r;
@@ -130,19 +145,27 @@ 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))) {
-               DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n"));
-               return false;
+       if (info3->base.full_name.string == NULL) {
+               struct netr_SamInfo3 *cached_info3;
+               const char *full_name = NULL;
+
+               cached_info3 = netsamlogon_cache_get(tmp_ctx, &user_sid);
+               if (cached_info3 != NULL) {
+                       full_name = cached_info3->base.full_name.string;
+               }
+
+               if (full_name != NULL) {
+                       info3->base.full_name.string = talloc_strdup(info3, full_name);
+               }
        }
 
        /* only Samba fills in the username, not sure why NT doesn't */
@@ -159,22 +182,22 @@ 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, &r,
+       ndr_err = ndr_push_struct_blob(&blob, tmp_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"));
-               TALLOC_FREE(mem_ctx);
+               TALLOC_FREE(tmp_ctx);
                return false;
        }
 
        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;
        }
 
-       TALLOC_FREE(mem_ctx);
+       TALLOC_FREE(tmp_ctx);
 
        return result;
 }
@@ -184,11 +207,11 @@ 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;
-       fstring keystr, tmp;
+       fstring keystr;
        enum ndr_err_code ndr_err;
        DATA_BLOB blob;
        struct netsamlogoncache_entry r;
@@ -196,11 +219,11 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *
        if (!netsamlogon_cache_init()) {
                DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n",
                        NETSAMLOGON_TDB));
-               return false;
+               return NULL;
        }
 
        /* 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_get: SID [%s]\n", keystr));
        data = tdb_fetch_bystring( netsamlogon_tdb, keystr );
 
@@ -208,28 +231,27 @@ 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 = (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 (DEBUGLEVEL >= 10) {
-               NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
-       }
-
        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);
+               tdb_delete_bystring(netsamlogon_tdb, keystr);
                TALLOC_FREE(info3);
                goto done;
        }
 
+       if (DEBUGLEVEL >= 10) {
+               NDR_PRINT_DEBUG(netsamlogoncache_entry, &r);
+       }
+
        info3 = (struct netr_SamInfo3 *)talloc_memdup(mem_ctx, &r.info3,
                                                      sizeof(r.info3));
 
@@ -244,7 +266,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *
           --jerry */
        {
                time_t          now = time(NULL);
-               uint32          time_diff;
+               uint32_t        time_diff;
 
                /* is the entry expired? */
                time_diff = now - t;
@@ -258,7 +280,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;