s3:vfs: Correctly check if OFD locks should be enabled or not
[kai/samba-autobuild/.git] / source3 / smbd / files.c
index 5b3741bb8658a487da72ea76649a363b028a9e60..99b4937c99b4a892c55a95613d682c1bd84e1438 100644 (file)
@@ -22,7 +22,6 @@
 #include "smbd/globals.h"
 #include "libcli/security/security.h"
 #include "util_tdb.h"
-#include <ccan/hash/hash.h>
 #include "lib/util/bitmap.h"
 
 #define FILE_HANDLE_OFFSET 0x1000
@@ -52,6 +51,15 @@ NTSTATUS fsp_new(struct connection_struct *conn, TALLOC_CTX *mem_ctx,
                goto fail;
        }
 
+#if defined(HAVE_OFD_LOCKS)
+       fsp->use_ofd_locks = true;
+       if (lp_parm_bool(SNUM(conn),
+                        "smbd",
+                        "force process locks",
+                        false)) {
+               fsp->use_ofd_locks = false;
+       }
+#endif
        fsp->fh->ref_count = 1;
        fsp->fh->fd = -1;
 
@@ -119,7 +127,7 @@ NTSTATUS file_new(struct smb_request *req, connection_struct *conn,
         * few NULL checks, so make sure it's initialized with something. to
         * be safe until an audit can be done.
         */
-       fsp->fsp_name = synthetic_smb_fname(fsp, "", NULL, NULL);
+       fsp->fsp_name = synthetic_smb_fname(fsp, "", NULL, NULL, 0);
        if (fsp->fsp_name == NULL) {
                file_free(NULL, fsp);
                return NT_STATUS_NO_MEMORY;
@@ -171,7 +179,7 @@ void file_close_conn(connection_struct *conn)
  Close all open files for a pid and a vuid.
 ****************************************************************************/
 
-void file_close_pid(struct smbd_server_connection *sconn, uint16 smbpid,
+void file_close_pid(struct smbd_server_connection *sconn, uint16_t smbpid,
                    uint64_t vuid)
 {
        files_struct *fsp, *next;
@@ -455,22 +463,6 @@ bool file_find_subpath(files_struct *dir_fsp)
        return false;
 }
 
-/****************************************************************************
- Sync open files on a connection.
-****************************************************************************/
-
-void file_sync_all(connection_struct *conn)
-{
-       files_struct *fsp, *next;
-
-       for (fsp=conn->sconn->files; fsp; fsp=next) {
-               next=fsp->next;
-               if ((conn == fsp->conn) && (fsp->fh->fd != -1)) {
-                       sync_file(conn, fsp, True /* write through */);
-               }
-       }
-}
-
 /****************************************************************************
  Free up a fsp.
 ****************************************************************************/
@@ -479,6 +471,10 @@ void fsp_free(files_struct *fsp)
 {
        struct smbd_server_connection *sconn = fsp->conn->sconn;
 
+       if (fsp == sconn->fsp_fi_cache.fsp) {
+               ZERO_STRUCT(sconn->fsp_fi_cache);
+       }
+
        DLIST_REMOVE(sconn->files, fsp);
        SMB_ASSERT(sconn->num_files > 0);
        sconn->num_files--;
@@ -515,9 +511,21 @@ void file_free(struct smb_request *req, files_struct *fsp)
        uint64_t fnum = fsp->fnum;
 
        if (fsp->notify) {
-               struct notify_context *notify_ctx =
-                       fsp->conn->sconn->notify_ctx;
-               notify_remove(notify_ctx, fsp);
+               size_t len = fsp_fullbasepath(fsp, NULL, 0);
+               char fullpath[len+1];
+
+               fsp_fullbasepath(fsp, fullpath, sizeof(fullpath));
+
+               /*
+                * Avoid /. at the end of the path name. notify can't
+                * deal with it.
+                */
+               if (len > 1 && fullpath[len-1] == '.' &&
+                   fullpath[len-2] == '/') {
+                       fullpath[len-2] = '\0';
+               }
+
+               notify_remove(fsp->conn->sconn->notify_ctx, fsp, fullpath);
                TALLOC_FREE(fsp->notify);
        }
 
@@ -537,14 +545,7 @@ void file_free(struct smb_request *req, files_struct *fsp)
         * Clear all possible chained fsp
         * pointers in the SMB2 request queue.
         */
-       if (req != NULL && req->smb2req) {
-               remove_smb2_chained_fsp(fsp);
-       }
-
-       /* Closing a file can invalidate the positive cache. */
-       if (fsp == sconn->fsp_fi_cache.fsp) {
-               ZERO_STRUCT(sconn->fsp_fi_cache);
-       }
+       remove_smb2_chained_fsp(fsp);
 
        /* Drop all remaining extensions. */
        vfs_remove_all_fsp_extensions(fsp);
@@ -559,7 +560,7 @@ void file_free(struct smb_request *req, files_struct *fsp)
  Get an fsp from a packet given a 16 bit fnum.
 ****************************************************************************/
 
-files_struct *file_fsp(struct smb_request *req, uint16 fid)
+files_struct *file_fsp(struct smb_request *req, uint16_t fid)
 {
        struct smbXsrv_open *op;
        NTSTATUS status;
@@ -688,8 +689,8 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
 ****************************************************************************/
 
 NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *from,
-                     uint32 access_mask, uint32 share_access,
-                     uint32 create_options, files_struct *to)
+                     uint32_t access_mask, uint32_t share_access,
+                     uint32_t create_options, files_struct *to)
 {
        /* this can never happen for print files */
        SMB_ASSERT(from->print_file == NULL);
@@ -729,6 +730,7 @@ NTSTATUS file_name_hash(connection_struct *conn,
        char tmpbuf[PATH_MAX];
        char *fullpath, *to_free;
        ssize_t len;
+       TDB_DATA key;
 
        /* Set the hash of the full pathname. */
 
@@ -737,7 +739,8 @@ NTSTATUS file_name_hash(connection_struct *conn,
        if (len == -1) {
                return NT_STATUS_NO_MEMORY;
        }
-       *p_name_hash = hash(fullpath, len+1, 0);
+       key = (TDB_DATA) { .dptr = (uint8_t *)fullpath, .dsize = len+1 };
+       *p_name_hash = tdb_jenkins_hash(&key);
 
        DEBUG(10,("file_name_hash: %s hash 0x%x\n",
                  fullpath,
@@ -773,10 +776,13 @@ const struct GUID *fsp_client_guid(const files_struct *fsp)
        return &fsp->conn->sconn->client->connections->smb2.client.guid;
 }
 
-uint32_t fsp_lease_type(struct files_struct *fsp)
+size_t fsp_fullbasepath(struct files_struct *fsp, char *buf, size_t buflen)
 {
-       if (fsp->oplock_type == LEASE_OPLOCK) {
-               return fsp->lease->lease.lease_state;
-       }
-       return map_oplock_to_lease_type(fsp->oplock_type);
+       int len;
+
+       len = snprintf(buf, buflen, "%s/%s", fsp->conn->connectpath,
+                      fsp->fsp_name->base_name);
+       SMB_ASSERT(len>0);
+
+       return len;
 }