Hi all!

Attached patch can be seen as proposal to discuss behavior of gencache in
case when it is used in applications running under non-priviledged
accounts so that O_RDWR|O_CREAT always fails against system-wide
lock_path("gencache.tdb") (which is usually created by smbd/nmbd).

The patch adds error resistence and tries to re-open gencache.tdb in
O_RDONLY mode if O_RDWR|O_CREAT failed. This allows the application to use
existing entries but forbids cache updates.

Simo proposed to have per-account gencache.tdb in such case
(~/.smb/gencache.tdb?) but I'm not sure it is good to put such behavior
into the level where gencache exists (lib/). Any other thoughts?

-- 
/ Alexander Bokovoy
---
It's not reality or how you perceive things that's important -- it's
what you're taking for it...
--- samba-3.0.tag/source/lib/gencache.c.orig_alt        2003-01-27 22:02:24 +0200
+++ samba-3.0.tag/source/lib/gencache.c 2003-02-05 18:24:06 +0200
@@ -28,9 +28,13 @@
 
 #define TIMEOUT_LEN 12
 #define CACHE_DATA_FMT "%12u/%s"
+typedef enum {
+        GENCACHE_RDRW,
+        GENCACHE_RDONLY
+} gencache_access_t;
 
 static TDB_CONTEXT *cache;
-
+static gencache_access_t cache_type;
 /**
  * @file gencache.c
  * @brief Generic, persistent and shared between processes cache mechanism
@@ -64,6 +68,15 @@
 
        cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
                             O_RDWR|O_CREAT, 0644);
+        cache_type = GENCACHE_RDRW;
+        
+        if (!cache) {
+               DEBUG(5, ("Opening cache file at %s in read-write mode failed, try to 
+open it read-only\n",
+                          cache_fname));
+               cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
+                                    O_RDONLY, 0644);
+                cache_type = GENCACHE_RDONLY;
+        }
 
        SAFE_FREE(cache_fname);
        if (!cache) {
@@ -111,7 +124,7 @@
        /* fail completely if get null pointers passed */
        SMB_ASSERT(keystr && value);
 
-       if (!gencache_init()) return False;
+       if (!gencache_init() || (cache_type == GENCACHE_RDONLY)) return False;
        
        asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value);
        keybuf.dptr = strdup(keystr);
@@ -152,7 +165,7 @@
        /* fail completely if get null pointers passed */
        SMB_ASSERT(keystr && valstr);
 
-       if (!gencache_init()) return False;
+       if (!gencache_init() || (cache_type == GENCACHE_RDONLY)) return False;
                        
        /* 
         * Check whether entry exists in the cache
@@ -203,7 +216,7 @@
        /* fail completely if get null pointers passed */
        SMB_ASSERT(keystr);
 
-       if (!gencache_init()) return False;     
+       if (!gencache_init() || (cache_type == GENCACHE_RDONLY)) return False;  
        
        keybuf.dptr = strdup(keystr);
        keybuf.dsize = strlen(keystr);

Reply via email to