]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Now we're using OpenDir_fsp() all the time, make sure we don't leak file...
authorJeremy Allison <jra@samba.org>
Wed, 17 Jul 2019 22:21:21 +0000 (15:21 -0700)
committerRalph Boehme <slow@samba.org>
Tue, 6 Aug 2019 14:23:34 +0000 (14:23 +0000)
We must always set dir_hnd->fsp, even in the fallback to
SMB_VFS_OPENDIR() case. Remember if we had to fall back
and fix the destructor to close the additional file
descriptor if we did.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/dir.c

index 3646b7d744e6fe3f755c144d830ad38d38159330..e4c348724ba5f83be4357e2c6e758b2b04e2c3d5 100644 (file)
@@ -59,6 +59,7 @@ struct smb_Dir {
        unsigned int file_number;
        files_struct *fsp; /* Back pointer to containing fsp, only
                              set from OpenDir_fsp(). */
+       bool fallback_opendir;
 };
 
 struct dptr_struct {
@@ -1433,16 +1434,24 @@ static int smb_Dir_destructor(struct smb_Dir *dir_hnd)
        if (dir_hnd->dir != NULL) {
                SMB_VFS_CLOSEDIR(dir_hnd->conn, dir_hnd->dir);
                if (dir_hnd->fsp != NULL) {
+                       files_struct *fsp = dir_hnd->fsp;
                        /*
                         * The SMB_VFS_CLOSEDIR above
                         * closes the underlying fd inside
-                        * dirp->fsp.
+                        * dirp->fsp, unless fallback_opendir
+                        * was set in which case the fd
+                        * in dir_hnd->fsp->fh->fd isn't
+                        * the one being closed. Close
+                        * it separately.
                         */
-                       dir_hnd->fsp->fh->fd = -1;
-                       if (dir_hnd->fsp->dptr != NULL) {
-                               SMB_ASSERT(dir_hnd->fsp->dptr->dir_hnd ==
+                       if (dir_hnd->fallback_opendir) {
+                               SMB_VFS_CLOSE(fsp);
+                       }
+                       fsp->fh->fd = -1;
+                       if (fsp->dptr != NULL) {
+                               SMB_ASSERT(fsp->dptr->dir_hnd ==
                                        dir_hnd);
-                               dir_hnd->fsp->dptr->dir_hnd = NULL;
+                               fsp->dptr->dir_hnd = NULL;
                        }
                        dir_hnd->fsp = NULL;
                }
@@ -1690,6 +1699,15 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn,
                        errno = ENOMEM;
                        goto fail;
                }
+               /*
+                * Remember if we used the fallback.
+                * We need to change the destructor
+                * to also close the fsp file descriptor
+                * in this case as it isn't the same
+                * one the directory handle uses.
+                */
+               dir_hnd->fsp = fsp;
+               dir_hnd->fallback_opendir = true;
        }
 
        talloc_set_destructor(dir_hnd, smb_Dir_destructor);