r2660: - converted the libcli/raw/ library to use talloc_increase_ref_count()
authorAndrew Tridgell <tridge@samba.org>
Sun, 26 Sep 2004 11:30:20 +0000 (11:30 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:59:18 +0000 (12:59 -0500)
  rather than manual reference counts

- properly support SMBexit in the cifs and posix backends

- added a logoff method to all backends

With these changes the RAW-CONTEXT test now passes against the posix backend
(This used to be commit c315d6ac1cc40546fde1474702a6d66d07ee13c8)

24 files changed:
source4/include/cli_context.h
source4/libcli/cliconnect.c
source4/libcli/raw/clisession.c
source4/libcli/raw/clisocket.c
source4/libcli/raw/clitransport.c
source4/libcli/raw/clitree.c
source4/librpc/rpc/dcerpc_smb.c
source4/librpc/rpc/dcerpc_util.c
source4/ntvfs/cifs/vfs_cifs.c
source4/ntvfs/ipc/vfs_ipc.c
source4/ntvfs/nbench/vfs_nbench.c
source4/ntvfs/ntvfs.h
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/pvfs_qfileinfo.c
source4/ntvfs/posix/pvfs_read.c
source4/ntvfs/posix/pvfs_setfileinfo.c
source4/ntvfs/posix/pvfs_write.c
source4/ntvfs/posix/vfs_posix.c
source4/ntvfs/posix/vfs_posix.h
source4/ntvfs/simple/vfs_simple.c
source4/rpc_server/dcerpc_server.c
source4/smb_server/reply.c
source4/torture/basic/secleak.c
source4/torture/raw/context.c

index 1bfa8dfd24aec89dd1bceeccac29f759ddafd732..fa6e293cd910ceeeb8b7528337f96a996c606fa0 100644 (file)
@@ -63,9 +63,6 @@ struct smbcli_negotiate {
        
 /* this is the context for a SMB socket associated with the socket itself */
 struct smbcli_socket {
-       /* when the reference count reaches zero then the socket is destroyed */
-       int reference_count;
-
        struct in_addr dest_ip;
        /* dest hostname (which may or may not be a DNS name) */
        char *hostname;
@@ -99,9 +96,6 @@ struct smbcli_options {
 
 /* this is the context for the client transport layer */
 struct smbcli_transport {
-       /* when the reference count reaches zero then the transport is destroyed */
-       int reference_count;
-
        /* socket level info */
        struct smbcli_socket *socket;
 
@@ -184,9 +178,6 @@ struct smbcli_transport {
 
 /* this is the context for the session layer */
 struct smbcli_session {        
-       /* when the reference count reaches zero then the session is destroyed */
-       int reference_count;    
-       
        /* transport layer info */
        struct smbcli_transport *transport;
        
@@ -207,9 +198,6 @@ struct smbcli_session {
    smbcli_tree context: internal state for a tree connection. 
  */
 struct smbcli_tree {
-       /* when the reference count reaches zero then the tree is destroyed */
-       int reference_count;    
-
        /* session layer info */
        struct smbcli_session *session;
 
index 27caaa9df99000d35f0cea752e0efeded43491e1..f7720703051afb361be21bb024ceb6c3f0f60c3b 100644 (file)
@@ -31,13 +31,13 @@ BOOL smbcli_socket_connect(struct smbcli_state *cli, const char *server)
        if (!sock) return False;
 
        if (!smbcli_sock_connect_byname(sock, server, 0)) {
-               smbcli_sock_close(sock);
+               talloc_free(sock);
                return False;
        }
        
        cli->transport = smbcli_transport_init(sock);
        if (!cli->transport) {
-               smbcli_sock_close(sock);
+               talloc_free(sock);
                return False;
        }
 
@@ -112,8 +112,6 @@ NTSTATUS smbcli_send_tconX(struct smbcli_state *cli, const char *sharename,
        cli->tree = smbcli_tree_init(cli->session);
        if (!cli->tree) return NT_STATUS_UNSUCCESSFUL;
 
-       cli->tree->reference_count++;
-
        mem_ctx = talloc_init("tcon");
        if (!mem_ctx) {
                return NT_STATUS_NO_MEMORY;
@@ -188,7 +186,6 @@ NTSTATUS smbcli_full_connection(struct smbcli_state **ret_cli,
        (*ret_cli)->tree = tree;
        (*ret_cli)->session = tree->session;
        (*ret_cli)->transport = tree->session->transport;
-       tree->reference_count++;
 
 done:
        talloc_free(mem_ctx);
@@ -225,9 +222,6 @@ struct smbcli_state *smbcli_state_init(void)
 void smbcli_shutdown(struct smbcli_state *cli)
 {
        if (!cli) return;
-       if (cli->tree) {
-               cli->tree->reference_count++;
-               smbcli_tree_close(cli->tree);
-       }
+       talloc_free(cli->tree);
        talloc_free(cli);
 }
index 516da2fa2e0a4789b39519a54c7e57eea2c0fdef..0c6c80d94c4d470bd29ca87cea91a9a6de5acbf9 100644 (file)
        if (!req) return NULL; \
 } while (0)
 
+
+/*
+  destroy a smbcli_session
+*/
+static int session_destroy(void *ptr)
+{
+       struct smbcli_session *session = ptr;
+       talloc_free(session->transport);
+       return 0;
+}
+
 /****************************************************************************
  Initialize the session context
 ****************************************************************************/
@@ -42,20 +53,10 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport)
        session->transport = transport;
        session->pid = (uint16_t)getpid();
        session->vuid = UID_FIELD_INVALID;
-       session->transport->reference_count++;
 
-       return session;
-}
+       talloc_set_destructor(session, session_destroy);
 
-/****************************************************************************
-reduce reference_count and destroy is <= 0
-****************************************************************************/
-void smbcli_session_close(struct smbcli_session *session)
-{
-       session->reference_count--;
-       if (session->reference_count <= 0) {
-               smbcli_transport_close(session->transport);
-       }
+       return session;
 }
 
 /****************************************************************************
@@ -590,16 +591,27 @@ NTSTATUS smb_raw_ulogoff(struct smbcli_session *session)
 
 
 /****************************************************************************
- Send a SMBexit
-****************************************************************************/
-NTSTATUS smb_raw_exit(struct smbcli_session *session)
+ Send a exit (async send)
+*****************************************************************************/
+struct smbcli_request *smb_raw_exit_send(struct smbcli_session *session)
 {
        struct smbcli_request *req;
 
-       req = smbcli_request_setup_session(session, SMBexit, 0, 0);
+       SETUP_REQUEST_SESSION(SMBexit, 0, 0);
 
-       if (smbcli_request_send(req)) {
-               smbcli_request_receive(req);
+       if (!smbcli_request_send(req)) {
+               smbcli_request_destroy(req);
+               return NULL;
        }
-       return smbcli_request_destroy(req);
+
+       return req;
+}
+
+/****************************************************************************
+ Send a exit (sync interface)
+*****************************************************************************/
+NTSTATUS smb_raw_exit(struct smbcli_session *session)
+{
+       struct smbcli_request *req = smb_raw_exit_send(session);
+       return smbcli_request_simple_recv(req);
 }
index 8481bc73e2e00cf833c79be9cbb9ff86faefc6f1..37188f4e7722e9c8b5732c5c94e95d0f7b6045d9 100644 (file)
 
 #include "includes.h"
 
+/*
+  destroy a socket
+ */
+static int sock_destructor(void *ptr)
+{
+       struct smbcli_socket *sock = ptr;
+       if (sock->fd != -1) {
+               close(sock->fd);
+               sock->fd = -1;
+       }
+       return 0;
+}
 
 /*
   create a smbcli_socket context
@@ -37,11 +49,13 @@ struct smbcli_socket *smbcli_sock_init(void)
        ZERO_STRUCTP(sock);
        sock->fd = -1;
        sock->port = 0;
+
        /* 20 second default timeout */
        sock->timeout = 20000;
-
        sock->hostname = NULL;
 
+       talloc_set_destructor(sock, sock_destructor);
+
        return sock;
 }
 
@@ -96,18 +110,6 @@ void smbcli_sock_dead(struct smbcli_socket *sock)
        }
 }
 
-/****************************************************************************
- reduce socket reference count - if it becomes zero then close
-****************************************************************************/
-void smbcli_sock_close(struct smbcli_socket *sock)
-{
-       sock->reference_count--;
-       if (sock->reference_count <= 0) {
-               smbcli_sock_dead(sock);
-               talloc_free(sock);
-       }
-}
-
 /****************************************************************************
  Set socket options on a open connection.
 ****************************************************************************/
index d70ceceab3aba2ff3d2d00997a5d085a1a267654..eb1d3631ee390e93f5df88f24c9b4d70a17f02c1 100644 (file)
@@ -41,6 +41,21 @@ static void smbcli_transport_event_handler(struct event_context *ev, struct fd_e
        }
 }
 
+/*
+  destroy a transport
+ */
+static int transport_destructor(void *ptr)
+{
+       struct smbcli_transport *transport = ptr;
+
+       smbcli_transport_dead(transport);
+       event_remove_fd(transport->event.ctx, transport->event.fde);
+       event_remove_timed(transport->event.ctx, transport->event.te);
+       event_context_destroy(transport->event.ctx);
+       talloc_free(transport->socket);
+       return 0;
+}
+
 /*
   create a transport structure based on an established socket
 */
@@ -67,8 +82,6 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock)
        
        smbcli_init_signing(transport);
 
-       transport->socket->reference_count++;
-
        ZERO_STRUCT(transport->called);
 
        fde.fd = sock->fd;
@@ -79,22 +92,9 @@ struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock)
 
        transport->event.fde = event_add_fd(transport->event.ctx, &fde);
 
-       return transport;
-}
+       talloc_set_destructor(transport, transport_destructor);
 
-/*
-  decrease reference count on a transport, and destroy if it becomes
-  zero
-*/
-void smbcli_transport_close(struct smbcli_transport *transport)
-{
-       transport->reference_count--;
-       if (transport->reference_count <= 0) {
-               event_remove_fd(transport->event.ctx, transport->event.fde);
-               event_remove_timed(transport->event.ctx, transport->event.te);
-               event_context_destroy(transport->event.ctx);
-               smbcli_sock_close(transport->socket);
-       }
+       return transport;
 }
 
 /*
index e3a1a6d34195ae696b8315ed4016423e3255fc88..e0072a31b1ece0f63b4dbc7ec241ef2b2b24572d 100644 (file)
        if (!req) return NULL; \
 } while (0)
 
+/*
+  destroy a smbcli_tree
+*/
+static int tree_destructor(void *ptr)
+{
+       struct smbcli_tree *tree = ptr;
+       talloc_free(tree->session);
+       return 0;
+}
 
 /****************************************************************************
  Initialize the tree context
@@ -41,24 +50,11 @@ struct smbcli_tree *smbcli_tree_init(struct smbcli_session *session)
 
        ZERO_STRUCTP(tree);
        tree->session = session;
-       tree->session->reference_count++;
+       talloc_set_destructor(tree, tree_destructor);
 
        return tree;
 }
 
-/****************************************************************************
-reduce reference count on a tree and destroy if <= 0
-****************************************************************************/
-void smbcli_tree_close(struct smbcli_tree *tree)
-{
-       if (!tree) return;
-       tree->reference_count--;
-       if (tree->reference_count <= 0) {
-               smbcli_session_close(tree->session);
-       }
-}
-
-
 /****************************************************************************
  Send a tconX (async send)
 ****************************************************************************/
@@ -202,7 +198,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree,
 
        transport = smbcli_transport_init(sock);
        if (!transport) {
-               smbcli_sock_close(sock);
+               talloc_free(sock);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -211,7 +207,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree,
        choose_called_name(&called,  dest_host, 0x20);
 
        if (!smbcli_transport_connect(transport, &calling, &called)) {
-               smbcli_transport_close(transport);
+               talloc_free(transport);
                return NT_STATUS_UNSUCCESSFUL;
        }
 
@@ -219,13 +215,13 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree,
        /* negotiate protocol options with the server */
        status = smb_raw_negotiate(transport);
        if (!NT_STATUS_IS_OK(status)) {
-               smbcli_transport_close(transport);
+               talloc_free(transport);
                return status;
        }
 
        session = smbcli_session_init(transport);
        if (!session) {
-               smbcli_transport_close(transport);
+               talloc_free(transport);
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -251,7 +247,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree,
 
        status = smb_raw_session_setup(session, mem_ctx, &setup);
        if (!NT_STATUS_IS_OK(status)) {
-               smbcli_session_close(session);
+               talloc_free(session);
                talloc_free(mem_ctx);
                return status;
        }
@@ -260,7 +256,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree,
 
        tree = smbcli_tree_init(session);
        if (!tree) {
-               smbcli_session_close(session);
+               talloc_free(session);
                talloc_free(mem_ctx);
                return NT_STATUS_NO_MEMORY;
        }
@@ -284,7 +280,7 @@ NTSTATUS smbcli_tree_full_connection(struct smbcli_tree **ret_tree,
        SAFE_FREE(in_path);
 
        if (!NT_STATUS_IS_OK(status)) {
-               smbcli_tree_close(tree);
+               talloc_free(tree);
                talloc_free(mem_ctx);
                return status;
        }
index dac95f5aec23262c6407d4187938651d8ba4c96d..09c5f3772ce58c144d371033001815fe157a8d99 100644 (file)
@@ -334,7 +334,7 @@ static NTSTATUS smb_shutdown_pipe(struct dcerpc_pipe *p)
        c.close.in.fnum = smb->fnum;
        c.close.in.write_time = 0;
        smb_raw_close(smb->tree, &c);
-       smbcli_tree_close(smb->tree);
+       talloc_free(smb->tree);
 
        return NT_STATUS_OK;
 }
@@ -443,7 +443,7 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe **p,
        smb->tree = tree;
 
        (*p)->transport.private = smb;
-       tree->reference_count++;
+       talloc_increase_ref_count(tree);
 
         return NT_STATUS_OK;
 }
index 43cced0543d4afec3bce08fdbf4e581ba4e3600b..be83d6bed1c72d798488657ce96f51b8aab43071 100644 (file)
@@ -486,7 +486,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **p,
        
        /* this ensures that the reference count is decremented so
           a pipe close will really close the link */
-       smbcli_tree_close(cli->tree);
+       talloc_free(cli->tree);
        
        (*p)->flags = binding->flags;
 
index 2ae41a674c93140aac71ff839587dea678e14ab1..3931792ee8a52ab785af8310d335d453e805a736 100644 (file)
@@ -162,7 +162,7 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon, int depth)
        struct cvfs_private *private = tcon->ntvfs_private_list[depth];
 
        smb_tree_disconnect(private->tree);
-       smbcli_tree_close(private->tree);
+       talloc_free(private->tree);
 
        return NT_STATUS_OK;
 }
@@ -517,11 +517,29 @@ static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io)
 }
 
 /*
-  exit - closing files?
+  exit - closing files open by the pid
 */
 static NTSTATUS cvfs_exit(struct smbsrv_request *req)
 {
-       return NT_STATUS_NOT_SUPPORTED;
+       NTVFS_GET_PRIVATE(cvfs_private, private, req);
+       struct smbcli_request *c_req;
+
+       if (!req->async.send_fn) {
+               return smb_raw_exit(private->tree->session);
+       }
+
+       c_req = smb_raw_exit_send(private->tree->session);
+
+       SIMPLE_ASYNC_TAIL;
+}
+
+/*
+  logoff - closing files open by the user
+*/
+static NTSTATUS cvfs_logoff(struct smbsrv_request *req)
+{
+       /* we can't do this right in the cifs backend .... */
+       return NT_STATUS_OK;
 }
 
 /*
@@ -699,6 +717,7 @@ NTSTATUS ntvfs_cifs_init(void)
        ops.search_next = cvfs_search_next;
        ops.search_close = cvfs_search_close;
        ops.trans = cvfs_trans;
+       ops.logoff = cvfs_logoff;
 
        if (lp_parm_bool(-1, "cifs", "maptrans2", False)) {
            ops.trans2 = cvfs_trans2;
index ce6629739a0524375deb8d445c8975b036a441b3..33e1287d215c8df35f15fee4586b052a3f347cae 100644 (file)
@@ -43,6 +43,13 @@ struct ipc_private {
                uint16_t fnum;
                struct dcesrv_connection *dce_conn;
                uint16_t ipc_state;
+               /* we need to remember the session it was opened on,
+                  as it is illegal to operate on someone elses fnum */
+               struct smbsrv_session *session;
+
+               /* we need to remember the client pid that 
+                  opened the file so SMBexit works */
+               uint16_t smbpid;
        } *pipe_list;
 
 };
@@ -262,6 +269,9 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname,
 
        DLIST_ADD(private->pipe_list, p);
 
+       p->smbpid = req->smbpid;
+       p->session = req->session;
+
        *ps = p;
 
        return NT_STATUS_OK;
@@ -514,11 +524,39 @@ static NTSTATUS ipc_close(struct smbsrv_request *req, union smb_close *io)
 }
 
 /*
-  exit - closing files?
+  exit - closing files
 */
 static NTSTATUS ipc_exit(struct smbsrv_request *req)
 {
-       return NT_STATUS_ACCESS_DENIED;
+       NTVFS_GET_PRIVATE(ipc_private, private, req);
+       struct pipe_state *p, *next;
+       
+       for (p=private->pipe_list; p; p=next) {
+               next = p->next;
+               if (p->smbpid == req->smbpid) {
+                       pipe_shutdown(private, p);
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
+/*
+  logoff - closing files open by the user
+*/
+static NTSTATUS ipc_logoff(struct smbsrv_request *req)
+{
+       NTVFS_GET_PRIVATE(ipc_private, private, req);
+       struct pipe_state *p, *next;
+       
+       for (p=private->pipe_list; p; p=next) {
+               next = p->next;
+               if (p->session == req->session) {
+                       pipe_shutdown(private, p);
+               }
+       }
+
+       return NT_STATUS_OK;
 }
 
 /*
@@ -733,6 +771,7 @@ NTSTATUS ntvfs_ipc_init(void)
        ops.search_next = ipc_search_next;
        ops.search_close = ipc_search_close;
        ops.trans = ipc_trans;
+       ops.logoff = ipc_logoff;
 
        /* register ourselves with the NTVFS subsystem. */
        ret = register_backend("ntvfs", &ops);
index eebf6f1dde5254ee40f819c5036fdd3a5ca6c26d..90b5d43bd6759a716b818c676f03d6015753da03 100644 (file)
@@ -475,6 +475,19 @@ static NTSTATUS nbench_exit(struct smbsrv_request *req)
        return status;
 }
 
+/*
+  logoff - closing files
+*/
+static NTSTATUS nbench_logoff(struct smbsrv_request *req)
+{
+       NTVFS_GET_PRIVATE(nbench_private, private, req);
+       NTSTATUS status;
+
+       PASS_THRU_REQ(req, logoff, (req));
+
+       return status;
+}
+
 /*
   lock a byte range
 */
@@ -672,6 +685,7 @@ NTSTATUS ntvfs_nbench_init(void)
        ops.search_next = nbench_search_next;
        ops.search_close = nbench_search_close;
        ops.trans = nbench_trans;
+       ops.logoff = nbench_logoff;
 
        /* we don't register a trans2 handler as we want to be able to
           log individual trans2 requests */
index c9cf6de1e013c70a4419c79e562f0d22c65afa78..96434f44e24ff1b48786e2046fb8c59d5dde6a41 100644 (file)
@@ -74,6 +74,9 @@ struct ntvfs_ops {
 
        /* trans interface - used by IPC backend for pipes and RAP calls */
        NTSTATUS (*trans)(struct smbsrv_request *req, struct smb_trans2 *trans);
+
+       /* logoff - called when a vuid is closed */
+       NTSTATUS (*logoff)(struct smbsrv_request *req);
 };
 
 
index a1c6dcdcfe5d678c7e31fdc9f69850c3aa33672a..f3bec4085ea16bae8e2bc829d4e58dd7fc67fad0 100644 (file)
 /*
   find open file handle given fnum
 */
-struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum)
+struct pvfs_file *pvfs_find_fd(struct smbsrv_request *req, uint16_t fnum)
 {
+       NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
        struct pvfs_file *f;
        for (f=pvfs->open_files;f;f=f->next) {
                if (f->fnum == fnum) {
+                       if (req->session != f->session) {
+                               DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n", fnum));
+                               return NULL;
+                       }
                        return f;
                }
        }
@@ -146,6 +151,8 @@ do_open:
        f->fnum = fd;
        f->fd = fd;
        f->name = talloc_steal(f, name);
+       f->session = req->session;
+       f->smbpid = req->smbpid;
 
        /* setup a destructor to avoid file descriptor leaks on
           abnormal termination */
@@ -183,7 +190,7 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io)
                return NT_STATUS_INVALID_LEVEL;
        }
 
-       f = pvfs_find_fd(pvfs, io->close.in.fnum);
+       f = pvfs_find_fd(req, io->close.in.fnum);
        if (!f) {
                return NT_STATUS_INVALID_HANDLE;
        }
@@ -202,3 +209,45 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io)
        return status;
 }
 
+
+/*
+  logoff - close all file descriptors open by a vuid
+*/
+NTSTATUS pvfs_logoff(struct smbsrv_request *req)
+{
+       NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
+       struct pvfs_file *f, *next;
+
+       for (f=pvfs->open_files;f;f=next) {
+               next = f->next;
+               if (f->session == req->session) {
+                       talloc_set_destructor(f, NULL);
+                       DLIST_REMOVE(pvfs->open_files, f);
+                       talloc_free(f);
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
+
+/*
+  exit - close files for the current pid
+*/
+NTSTATUS pvfs_exit(struct smbsrv_request *req)
+{
+       NTVFS_GET_PRIVATE(pvfs_state, pvfs, req);
+       struct pvfs_file *f, *next;
+
+       for (f=pvfs->open_files;f;f=next) {
+               next = f->next;
+               if (f->smbpid == req->smbpid) {
+                       talloc_set_destructor(f, NULL);
+                       DLIST_REMOVE(pvfs->open_files, f);
+                       talloc_free(f);
+               }
+       }
+
+       return NT_STATUS_OK;
+}
+
index 649036b09a6d9657dc6d30886637027c5b21795a..81706bcfe89fe45377e5ad6fd14d15e948a3cb81 100644 (file)
@@ -114,7 +114,7 @@ NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info)
                return ntvfs_map_qfileinfo(req, info, pvfs->ops);
        }
 
-       f = pvfs_find_fd(pvfs, info->generic.in.fnum);
+       f = pvfs_find_fd(req, info->generic.in.fnum);
        if (!f) {
                return NT_STATUS_INVALID_HANDLE;
        }
index cbb031763883813039004f88a4e72b987303ac7a..72ac00a32d367a66bcc18d63cf829fc86ef09472 100644 (file)
@@ -36,7 +36,8 @@ NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd)
                return NT_STATUS_NOT_SUPPORTED;
        }
 
-       f = pvfs_find_fd(pvfs, rd->readx.in.fnum);
+
+       f = pvfs_find_fd(req, rd->readx.in.fnum);
        if (!f) {
                return NT_STATUS_INVALID_HANDLE;
        }
index c2c58415be76299d6070592b1349f2e3162a5002..2ea2fdaf8edb89695a1d92b8f83b8d54fc26986c 100644 (file)
@@ -33,7 +33,7 @@ NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req,
        struct utimbuf unix_times;
        struct pvfs_file *f;
 
-       f = pvfs_find_fd(pvfs, info->generic.file.fnum);
+       f = pvfs_find_fd(req, info->generic.file.fnum);
        if (!f) {
                return NT_STATUS_INVALID_HANDLE;
        }
index ac9d23b88fb68bceb20c04d9d2460169b646005e..02ba1b8228ac92679f47ed50913eca95109b9863 100644 (file)
@@ -35,7 +35,7 @@ NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr)
 
        switch (wr->generic.level) {
        case RAW_WRITE_WRITEX:
-               f = pvfs_find_fd(pvfs, wr->writex.in.fnum);
+               f = pvfs_find_fd(req, wr->writex.in.fnum);
                if (!f) {
                        return NT_STATUS_INVALID_HANDLE;
                }
@@ -53,7 +53,7 @@ NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr)
                return NT_STATUS_OK;
 
        case RAW_WRITE_WRITE:
-               f = pvfs_find_fd(pvfs, wr->write.in.fnum);
+               f = pvfs_find_fd(req, wr->write.in.fnum);
                if (!f) {
                        return NT_STATUS_INVALID_HANDLE;
                }
index 8705317b2a4338a20f8d2385facbf0dba51a3ebc..7ae7c6759a1f299b4328a817febf8d9f062c3fac 100644 (file)
@@ -160,15 +160,6 @@ static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io)
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-/*
-  exit - closing files?
-*/
-static NTSTATUS pvfs_exit(struct smbsrv_request *req)
-{
-       DEBUG(0,("pvfs_exit not implemented\n"));
-       return NT_STATUS_NOT_SUPPORTED;
-}
-
 /*
   lock a byte range
 */
@@ -241,6 +232,7 @@ NTSTATUS ntvfs_posix_init(void)
        ops.search_next = pvfs_search_next;
        ops.search_close = pvfs_search_close;
        ops.trans = pvfs_trans;
+       ops.logoff = pvfs_logoff;
 
        /* register ourselves with the NTVFS subsystem. We register
           under the name 'default' as we wish to be the default
index bfb1fbf7ca0f15dbd3dccd1d605100818cf803d2..96ab7f85b2f54aadc597f20260601c9c6d351f99 100644 (file)
@@ -107,6 +107,14 @@ struct pvfs_file {
        int fd;
        uint16_t fnum;
        struct pvfs_filename *name;
+
+       /* we need to remember the session it was opened on,
+          as it is illegal to operate on someone elses fnum */
+       struct smbsrv_session *session;
+
+       /* we need to remember the client pid that 
+          opened the file so SMBexit works */
+       uint16_t smbpid;
 };
 
 
index 5b2fe9df56fe45f001b02f5a775977277dcb77f6..f60646ed77db62d5fcfcc8ba02cbb12735029cd4 100644 (file)
@@ -589,13 +589,21 @@ static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io)
 }
 
 /*
-  exit - closing files?
+  exit - closing files
 */
 static NTSTATUS svfs_exit(struct smbsrv_request *req)
 {
        return NT_STATUS_NOT_SUPPORTED;
 }
 
+/*
+  logoff - closing files
+*/
+static NTSTATUS svfs_logoff(struct smbsrv_request *req)
+{
+       return NT_STATUS_NOT_SUPPORTED;
+}
+
 /*
   lock a byte range
 */
@@ -962,6 +970,7 @@ NTSTATUS ntvfs_simple_init(void)
        ops.search_next = svfs_search_next;
        ops.search_close = svfs_search_close;
        ops.trans = svfs_trans;
+       ops.logoff = svfs_logoff;
 
        /* register ourselves with the NTVFS subsystem. We register
           under names 'simple'
index 17e629d81e573f8715c2c38c733dad9f86944ac2..46029ce8dc564076d984f3818cd3a6345a0f2159 100644 (file)
@@ -350,10 +350,6 @@ void dcesrv_endpoint_disconnect(struct dcesrv_connection *p)
                gensec_end(&p->auth_state.gensec_security);
        }
 
-       if (p->auth_state.session_info) {
-               free_session_info(&p->auth_state.session_info);
-       }
-
        talloc_free(p);
 }
 
index 72c7c20a1119d57ff822e7ab40d349ba979fcf86..94317bfc39830bffd46963ab3feb9a32207c396f 100644 (file)
@@ -1149,23 +1149,26 @@ void reply_flush(struct smbsrv_request *req)
 
 
 /****************************************************************************
- Reply to a exit.
+ Reply to a exit. This closes all files open by a smbpid
 ****************************************************************************/
 void reply_exit(struct smbsrv_request *req)
 {
+       NTSTATUS status;
+       struct smbsrv_tcon *tcon;
        REQ_CHECK_WCT(req, 0);
 
-       req->async.send_fn = reply_simple_send;
-
-       if (!req->tcon) {
-               req_reply_error(req, NT_STATUS_INVALID_HANDLE);
-               return;
+       for (tcon=req->smb_conn->tree.tcons;tcon;tcon=tcon->next) {
+               req->tcon = tcon;
+               status = tcon->ntvfs_ops->exit(req);
+               req->tcon = NULL;
+               if (!NT_STATUS_IS_OK(status)) {
+                       req_reply_error(req, status);
+                       return;
+               }
        }
 
-       /* call backend */
-       req->async.status = req->tcon->ntvfs_ops->exit(req);
-       
-       REQ_ASYNC_TAIL;
+       req_setup_reply(req, 0, 0);
+       req_send_reply(req);
 }
 
 
@@ -2097,20 +2100,29 @@ void reply_sesssetup(struct smbsrv_request *req)
        req_reply_error(req, NT_STATUS_FOOBAR);
 }
 
-
 /****************************************************************************
  Reply to a SMBulogoffX.
 ****************************************************************************/
 void reply_ulogoffX(struct smbsrv_request *req)
 {
+       struct smbsrv_tcon *tcon;
        uint16_t vuid;
+       NTSTATUS status;
 
        vuid = SVAL(req->in.hdr, HDR_UID);
-       
+
        /* in user level security we are supposed to close any files
-          open by this user */
+          open by this user on all open tree connects */
        if ((vuid != 0) && (lp_security() != SEC_SHARE)) {
-               DEBUG(0,("REWRITE: not closing user files\n"));
+               for (tcon=req->smb_conn->tree.tcons;tcon;tcon=tcon->next) {
+                       req->tcon = tcon;
+                       status = tcon->ntvfs_ops->logoff(req);
+                       req->tcon = NULL;
+                       if (!NT_STATUS_IS_OK(status)) {
+                               req_reply_error(req, status);
+                               return;
+                       }
+               }
        }
 
        smbsrv_invalidate_vuid(req->smb_conn, vuid);
index 80bc799df03ce7b71e00948b7a57edf18d64f206..54fa3ecee666f0d091d6a7ab05f25c46b5cbf4d3 100644 (file)
@@ -43,7 +43,7 @@ static BOOL try_failed_login(struct smbcli_state *cli)
                return False;
        }
 
-       smbcli_session_close(session);
+       talloc_free(session);
        talloc_free(mem_ctx);
 
        return True;
index 7bc75a662721b217db8fd6417d22688a9fc1ba4e..194d2de93ba14c2aa59243cbfebeaee361ba8c0d 100644 (file)
@@ -81,6 +81,8 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        printf("create a second security context on the same transport\n");
        session = smbcli_session_init(cli->transport);
+       talloc_increase_ref_count(cli->transport);
+
        setup.generic.level = RAW_SESSSETUP_GENERIC;
        setup.generic.in.sesskey = cli->transport->negotiate.sesskey;
        setup.generic.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */
@@ -95,6 +97,8 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        printf("create a third security context on the same transport, with vuid set\n");
        session2 = smbcli_session_init(cli->transport);
+       talloc_increase_ref_count(cli->transport);
+
        session2->vuid = session->vuid;
        setup.generic.level = RAW_SESSSETUP_GENERIC;
        setup.generic.in.sesskey = cli->transport->negotiate.sesskey;
@@ -110,10 +114,13 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        printf("vuid1=%d vuid2=%d vuid3=%d\n", cli->session->vuid, session->vuid, session2->vuid);
        
        CHECK_NOT_VALUE(session->vuid, session2->vuid);
+       talloc_free(session2);
 
        if (cli->transport->negotiate.capabilities & CAP_EXTENDED_SECURITY) {
                printf("create a fourth security context on the same transport, without extended security\n");
                session3 = smbcli_session_init(cli->transport);
+               talloc_increase_ref_count(cli->transport);
+
                session3->vuid = session->vuid;
                setup.generic.level = RAW_SESSSETUP_GENERIC;
                setup.generic.in.sesskey = cli->transport->negotiate.sesskey;
@@ -124,12 +131,14 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
                status = smb_raw_session_setup(session3, mem_ctx, &setup);
                CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+
+               talloc_free(session3);
        }
                
        printf("use the same tree as the existing connection\n");
        tree = smbcli_tree_init(session);
+       talloc_increase_ref_count(session);
        tree->tid = cli->tree->tid;
-       cli->tree->reference_count++;
 
        printf("create a file using the new vuid\n");
        io.generic.level = RAW_OPEN_NTCREATEX;
@@ -168,6 +177,7 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        printf("logoff the new vuid\n");
        status = smb_raw_ulogoff(session);
        CHECK_STATUS(status, NT_STATUS_OK);
+       talloc_free(session);
 
        printf("the new vuid should not now be accessible\n");
        status = smb_raw_write(tree, &wr);
@@ -182,7 +192,7 @@ static BOOL test_session(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* close down the new tree, which will also close the session
           as the reference count will be 0 */
-       smbcli_tree_close(tree);
+       talloc_free(tree);
        
 done:
        return ret;
@@ -215,9 +225,10 @@ static BOOL test_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        }
 
        share = lp_parm_string(-1, "torture", "share");
-
+       
        printf("create a second tree context on the same session\n");
        tree = smbcli_tree_init(cli->session);
+       talloc_increase_ref_count(cli->session);
 
        tcon.generic.level = RAW_TCON_TCONX;
        tcon.tconx.in.flags = 0;
@@ -286,7 +297,7 @@ static BOOL test_tree(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE);
 
        /* close down the new tree */
-       smbcli_tree_close(tree);
+       talloc_free(tree);
        
 done:
        return ret;
@@ -425,5 +436,6 @@ BOOL torture_raw_context(int dummy)
 
        torture_close_connection(cli);
        talloc_destroy(mem_ctx);
+
        return ret;
 }