Add parallel cache for share_access entries, one per connection struct.
authorJeremy Allison <jra@samba.org>
Fri, 11 Jan 2013 18:47:56 +0000 (10:47 -0800)
committerKarolin Seeger <kseeger@samba.org>
Mon, 14 Jan 2013 18:03:28 +0000 (19:03 +0100)
Needed as we cannot change the VFS ABI for 4.0.x, but need to add the
equivalent of 'uint32_t share_access' to the struct vuid_cache referenced
in connection_struct.

Exports 2 accessor functions - lifetime managed by talloc on the conn
struct list.

Signed-off-by: Jeremy Allison <jra@samba.org>
source3/smbd/conn.c
source3/smbd/proto.h

index bc5a03b4eb09034d59d538d1ee9f783fef42a106..e6f81a9b10bc66ea4e76a85dd81f6da35cd7f90e 100644 (file)
 #include "smbd/globals.h"
 #include "lib/util/bitmap.h"
 
+/*******************************************************************
+ Static cache for storing per-user share access value. This really
+ belongs inside the vuid_cache.array struct but we can't change the
+ VFS ABI for 4.0.x. This is fixed in 4.1.x. JRA.
+********************************************************************/
+
+struct connection_share_access_list {
+       struct connection_share_access_list *next, *prev;
+       connection_struct *conn;
+       uint32_t vuid_cache_share_access_array[VUID_CACHE_SIZE];
+};
+
+static struct connection_share_access_list *conn_share_access_list;
+
+/*******************************************************************
+ Destructor function for per-user share access value.
+********************************************************************/
+
+static int free_csal_entry(struct connection_share_access_list *csal)
+{
+       DLIST_REMOVE(conn_share_access_list, csal);
+       return 0;
+}
+
+/*******************************************************************
+ Utility function to find a per-user share access value struct.
+********************************************************************/
+
+static struct connection_share_access_list *find_csal_entry(connection_struct *conn)
+{
+       struct connection_share_access_list *csal;
+
+       for (csal = conn_share_access_list; csal; csal = csal->next) {
+               if (csal->conn == conn) {
+                       DLIST_PROMOTE(conn_share_access_list, csal);
+                       return csal;
+               }
+       }
+       return NULL;
+}
+
+/*******************************************************************
+ Accessor functions for per-user share access value.
+ These are the only two functions exposed externally.
+********************************************************************/
+
+uint32_t get_connection_share_access_list_entry(connection_struct *conn,
+                                               unsigned int i)
+{
+       struct connection_share_access_list *csal =
+                       find_csal_entry(conn);
+
+       if (csal == NULL) {
+               /*
+                * This is a faked up connection struct
+                * for internal purposes.
+                * Return full access.
+                */
+               return SEC_RIGHTS_FILE_ALL;
+       }
+
+       return csal->vuid_cache_share_access_array[i];
+}
+
+void set_connection_share_access_list_entry(connection_struct *conn,
+                                               unsigned int i,
+                                               uint32_t val)
+{
+       struct connection_share_access_list *csal =
+                       find_csal_entry(conn);
+
+       if (csal == NULL) {
+               return;
+       }
+
+       csal->vuid_cache_share_access_array[i] = val;
+}
+
 /****************************************************************************
  Return the number of open connections.
 ****************************************************************************/
@@ -60,19 +138,24 @@ bool conn_snum_used(struct smbd_server_connection *sconn,
 connection_struct *conn_new(struct smbd_server_connection *sconn)
 {
        connection_struct *conn;
+       struct connection_share_access_list *csal;
 
        if (!(conn=talloc_zero(NULL, connection_struct)) ||
            !(conn->params = talloc(conn, struct share_params)) ||
            !(conn->connectpath = talloc_strdup(conn, "")) ||
-           !(conn->origpath = talloc_strdup(conn, ""))) {
+           !(conn->origpath = talloc_strdup(conn, "")) ||
+           !(csal = talloc_zero(conn, struct connection_share_access_list))) {
                DEBUG(0,("TALLOC_ZERO() failed!\n"));
                TALLOC_FREE(conn);
                return NULL;
        }
+       talloc_set_destructor(csal, free_csal_entry);
+
        conn->sconn = sconn;
        conn->force_group_gid = (gid_t)-1;
 
        DLIST_ADD(sconn->connections, conn);
+       DLIST_ADD(conn_share_access_list, csal);
        sconn->num_connections++;
 
        return conn;
index 4fdcd2653de17b3cc9dd6c9246d6135a85eed723..6cf915ad562d96f1fdd8ad46518eac1734ff7ddc 100644 (file)
@@ -145,6 +145,11 @@ bool recursive_rmdir(TALLOC_CTX *ctx,
 
 /* The following definitions come from smbd/conn.c  */
 
+uint32_t get_connection_share_access_list_entry(connection_struct *conn,
+                                               unsigned int i);
+void set_connection_share_access_list_entry(connection_struct *conn,
+                                               unsigned int i,
+                                               uint32_t val);
 int conn_num_open(struct smbd_server_connection *sconn);
 bool conn_snum_used(struct smbd_server_connection *sconn, int snum);
 connection_struct *conn_new(struct smbd_server_connection *sconn);