From ef2e26c91b80556af033d3335e55f5dfa6fff31d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 01:53:07 +0000 Subject: first public release of samba4 code (This used to be commit b0510b5428b3461aeb9bbe3cc95f62fc73e2b97f) --- source4/ntvfs/README | 26 ++ source4/ntvfs/cifs/README | 5 + source4/ntvfs/cifs/vfs_cifs.c | 723 +++++++++++++++++++++++++++++++ source4/ntvfs/ipc/README | 5 + source4/ntvfs/ipc/vfs_ipc.c | 295 +++++++++++++ source4/ntvfs/ntvfs_base.c | 145 +++++++ source4/ntvfs/ntvfs_dfs.c | 117 +++++ source4/ntvfs/ntvfs_generic.c | 544 ++++++++++++++++++++++++ source4/ntvfs/ntvfs_util.c | 26 ++ source4/ntvfs/posix/vfs_posix.c | 151 +++++++ source4/ntvfs/print/README | 3 + source4/ntvfs/print/vfs_print.c | 104 +++++ source4/ntvfs/reference/ref.h | 36 ++ source4/ntvfs/reference/ref_util.c | 142 +++++++ source4/ntvfs/reference/vfs_ref.c | 843 ++++++++++++++++++++++++++++++++++++ source4/ntvfs/simple/svfs.h | 28 ++ source4/ntvfs/simple/svfs_util.c | 162 +++++++ source4/ntvfs/simple/vfs_simple.c | 848 +++++++++++++++++++++++++++++++++++++ 18 files changed, 4203 insertions(+) create mode 100644 source4/ntvfs/README create mode 100644 source4/ntvfs/cifs/README create mode 100644 source4/ntvfs/cifs/vfs_cifs.c create mode 100644 source4/ntvfs/ipc/README create mode 100644 source4/ntvfs/ipc/vfs_ipc.c create mode 100644 source4/ntvfs/ntvfs_base.c create mode 100644 source4/ntvfs/ntvfs_dfs.c create mode 100644 source4/ntvfs/ntvfs_generic.c create mode 100644 source4/ntvfs/ntvfs_util.c create mode 100644 source4/ntvfs/posix/vfs_posix.c create mode 100644 source4/ntvfs/print/README create mode 100644 source4/ntvfs/print/vfs_print.c create mode 100644 source4/ntvfs/reference/ref.h create mode 100644 source4/ntvfs/reference/ref_util.c create mode 100644 source4/ntvfs/reference/vfs_ref.c create mode 100644 source4/ntvfs/simple/svfs.h create mode 100644 source4/ntvfs/simple/svfs_util.c create mode 100644 source4/ntvfs/simple/vfs_simple.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/README b/source4/ntvfs/README new file mode 100644 index 0000000000..c86c9a0050 --- /dev/null +++ b/source4/ntvfs/README @@ -0,0 +1,26 @@ +This is the base of the new NTVFS subsystem for Samba. The model for +NTVFS backends is quite different than for the older style VFS +backends, in particular: + +- the NTVFS backends receive windows style file names, although they + are in the unix charset (usually UTF8). This means the backend is + responsible for mapping windows filename conventions to unix + filename conventions if necessary + +- the NTVFS backends are responsible for changing effective UID before + calling any OS local filesystem operations (if needed). The + become_*() functions are provided to make this easier. + +- the NTVFS backends are responsible for resolving DFS paths + +- each NTVFS backend handles either disk, printer or IPC$ shares, + rather than one backend handling all types + +- the entry points of the NTVFS backends correspond closely with basic + SMB operations, wheres the old VFS was modelled directly on the + POSIX filesystem interface. + +- the NTVFS backends are responsible for all semantic mappings, such + as mapping dos file attributes, ACLs, file ownership and file times + + diff --git a/source4/ntvfs/cifs/README b/source4/ntvfs/cifs/README new file mode 100644 index 0000000000..a43ad09bdf --- /dev/null +++ b/source4/ntvfs/cifs/README @@ -0,0 +1,5 @@ +This is the 'CIFS on CIFS' backend for Samba. It provides a NTVFS +backend that talks to a remote CIFS server. The primary aim of this +backend is for debugging and development, although some poeple may +find it useful as a CIFS gateway. + diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c new file mode 100644 index 0000000000..9a17336519 --- /dev/null +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -0,0 +1,723 @@ +/* + Unix SMB/CIFS implementation. + + CIFS-on-CIFS NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements a CIFS->CIFS NTVFS filesystem backend. + +*/ + +#include "includes.h" + +/* this is stored in ntvfs_private */ +struct cvfs_private { + struct cli_tree *tree; + struct cli_transport *transport; + struct tcon_context *conn; + const char *map_calls; +}; + + +/* a structure used to pass information to an async handler */ +struct async_info { + struct request_context *req; + void *parms; +}; + +/* + an idle function to cope with messages from the smbd client while + waiting for a reply from the server + this function won't be needed once all of the cifs backend + and the core of smbd is converted to use async calls +*/ +static void idle_func(struct cli_transport *transport, void *p_private) +{ + struct cvfs_private *private = p_private; + if (socket_pending(private->conn->smb->socket.fd)) { + smbd_process_async(private->conn->smb); + } +} + +/* + a handler for oplock break events from the server - these need to be passed + along to the client + */ +static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 fnum, uint8 level, void *p_private) +{ + struct cvfs_private *private = p_private; + + DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); + return req_send_oplock_break(private->conn, fnum, level); +} + +/* + a handler for read events on a connection to a backend server +*/ +static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags) +{ + struct tcon_context *conn = fde->private; + struct cvfs_private *private = conn->ntvfs_private; + + DEBUG(5,("cifs_socket_handler event on fd %d\n", fde->fd)); + + if (!cli_request_receive_next(private->transport)) { + /* the connection to our server is dead */ + close_cnum(conn); + } +} + +/* + connect to a share - used when a tree_connect operation comes in. +*/ +static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) +{ + struct tcon_context *conn = req->conn; + NTSTATUS status; + struct cvfs_private *private; + char *map_calls; + struct fd_event fde; + const char *host, *user, *pass, *domain, *remote_share; + + /* Here we need to determine which server to connect to. + * For now we use parametric options, type cifs. + * Later we will use security=server and auth_server.c. + */ + host = lp_parm_string(req->conn->service, "cifs", "server"); + user = lp_parm_string(req->conn->service, "cifs", "user"); + pass = lp_parm_string(req->conn->service, "cifs", "password"); + domain = lp_parm_string(req->conn->service, "cifs", "domain"); + remote_share = lp_parm_string(req->conn->service, "cifs", "share"); + if (!remote_share) { + remote_share = sharename; + } + + if (!host || !user || !pass || !domain) { + DEBUG(1,("CIFS backend: You must supply server, user, password and domain\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + private = talloc(req->conn->mem_ctx, sizeof(struct cvfs_private)); + if (!private) { + return NT_STATUS_NO_MEMORY; + } + ZERO_STRUCTP(private); + + req->conn->ntvfs_private = (void *)private; + + status = cli_tree_full_connection(&private->tree, + "vfs_cifs", + host, + 0, + remote_share, "?????", + user, domain, + pass); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + private->transport = private->tree->session->transport; + private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); + private->conn = req->conn; + + conn->fs_type = talloc_strdup(conn->mem_ctx, "NTFS"); + conn->dev_type = talloc_strdup(conn->mem_ctx, "A:"); + + map_calls = lp_parm_string(req->conn->service, "cifs", "map calls"); + if (map_calls) { + private->map_calls = talloc_strdup(conn->mem_ctx, map_calls); + } + + /* if we are mapping trans2, then we need to not give a trans2 + pointer in the operations structure */ + if (private->map_calls && in_list("trans2", private->map_calls, True)) { + conn->ntvfs_ops->trans2 = NULL; + } + + /* we need to tell the event loop that we wish to receive read events + on our SMB connection to the server */ + fde.fd = private->transport->socket->fd; + fde.flags = EVENT_FD_READ; + fde.private = req->conn; + fde.handler = cifs_socket_handler; + + event_add_fd(conn->smb->events, &fde); + + /* we need to receive oplock break requests from the server */ + cli_oplock_handler(private->transport, oplock_handler, private); + cli_transport_idle_handler(private->transport, idle_func, 100, private); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS cvfs_disconnect(struct tcon_context *conn) +{ + struct cvfs_private *private = conn->ntvfs_private; + + event_remove_fd_all(conn->smb->events, private->transport->socket->fd); + smb_tree_disconnect(private->tree); + cli_tree_close(private->tree); + + return NT_STATUS_OK; +} + +/* + a handler for simple async replies + this handler can only be used for functions that don't return any + parameters (those that just return a status code) + */ +static void async_simple(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = cli_request_simple_recv(c_req); + req->async.send_fn(req); +} + + +/* save some typing for the simple functions */ +#define ASYNC_RECV_TAIL(io, async_fn) do { \ + if (!c_req) return NT_STATUS_UNSUCCESSFUL; \ + { \ + struct async_info *async = c_req->async.private; \ + async = talloc(req->mem_ctx, sizeof(*async)); \ + if (!async) return NT_STATUS_NO_MEMORY; \ + async->parms = io; \ + async->req = req; \ + c_req->async.private = async; \ + } \ + c_req->async.fn = async_fn; \ + req->control_flags |= REQ_CONTROL_ASYNC; \ + return NT_STATUS_OK; \ +} while (0) + +#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS cvfs_unlink(struct request_context *req, struct smb_unlink *unl) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + /* see if the front end will allow us to perform this + function asynchronously. */ + if (!req->async.send_fn) { + return smb_raw_unlink(private->tree, unl); + } + + c_req = smb_raw_unlink_send(private->tree, unl); + + SIMPLE_ASYNC_TAIL; +} + +/* + a handler for async ioctl replies + */ +static void async_ioctl(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_ioctl_recv(c_req, req->mem_ctx, async->parms); + req->async.send_fn(req); +} + +/* + ioctl interface +*/ +static NTSTATUS cvfs_ioctl(struct request_context *req, struct smb_ioctl *io) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + /* see if the front end will allow us to perform this + function asynchronously. */ + if (!req->async.send_fn) { + return smb_raw_ioctl(private->tree, req->mem_ctx, io); + } + + c_req = smb_raw_ioctl_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_ioctl); +} + +/* + check if a directory exists +*/ +static NTSTATUS cvfs_chkpath(struct request_context *req, struct smb_chkpath *cp) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_chkpath(private->tree, cp); + } + + c_req = smb_raw_chkpath_send(private->tree, cp); + + SIMPLE_ASYNC_TAIL; +} + +/* + a handler for async qpathinfo replies + */ +static void async_qpathinfo(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_pathinfo_recv(c_req, req->mem_ctx, async->parms); + req->async.send_fn(req); +} + +/* + return info on a pathname +*/ +static NTSTATUS cvfs_qpathinfo(struct request_context *req, union smb_fileinfo *info) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_pathinfo(private->tree, req->mem_ctx, info); + } + + c_req = smb_raw_pathinfo_send(private->tree, info); + + ASYNC_RECV_TAIL(info, async_qpathinfo); +} + +/* + a handler for async qfileinfo replies + */ +static void async_qfileinfo(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_fileinfo_recv(c_req, req->mem_ctx, async->parms); + req->async.send_fn(req); +} + +/* + query info on a open file +*/ +static NTSTATUS cvfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_fileinfo(private->tree, req->mem_ctx, info); + } + + c_req = smb_raw_fileinfo_send(private->tree, info); + + ASYNC_RECV_TAIL(info, async_qfileinfo); +} + + +/* + set info on a pathname +*/ +static NTSTATUS cvfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_setpathinfo(private->tree, st); + } + + c_req = smb_raw_setpathinfo_send(private->tree, st); + + SIMPLE_ASYNC_TAIL; +} + + +/* + a handler for async open replies + */ +static void async_open(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_open_recv(c_req, req->mem_ctx, async->parms); + req->async.send_fn(req); +} + +/* + open a file +*/ +static NTSTATUS cvfs_open(struct request_context *req, union smb_open *io) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (private->map_calls && in_list("open", private->map_calls, True) && + io->generic.level != RAW_OPEN_GENERIC) { + return ntvfs_map_open(req, io); + } + + if (!req->async.send_fn) { + return smb_raw_open(private->tree, req->mem_ctx, io); + } + + c_req = smb_raw_open_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_open); +} + +/* + create a directory +*/ +static NTSTATUS cvfs_mkdir(struct request_context *req, union smb_mkdir *md) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_mkdir(private->tree, md); + } + + c_req = smb_raw_mkdir_send(private->tree, md); + + SIMPLE_ASYNC_TAIL; +} + +/* + remove a directory +*/ +static NTSTATUS cvfs_rmdir(struct request_context *req, struct smb_rmdir *rd) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_rmdir(private->tree, rd); + } + c_req = smb_raw_rmdir_send(private->tree, rd); + + SIMPLE_ASYNC_TAIL; +} + +/* + rename a set of files +*/ +static NTSTATUS cvfs_rename(struct request_context *req, struct smb_rename *ren) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_rename(private->tree, ren); + } + + c_req = smb_raw_rename_send(private->tree, ren); + + SIMPLE_ASYNC_TAIL; +} + +/* + copy a set of files +*/ +static NTSTATUS cvfs_copy(struct request_context *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + a handler for async read replies + */ +static void async_read(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_read_recv(c_req, async->parms); + req->async.send_fn(req); +} + +/* + read from a file +*/ +static NTSTATUS cvfs_read(struct request_context *req, union smb_read *rd) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_read(private->tree, rd); + } + + c_req = smb_raw_read_send(private->tree, rd); + + ASYNC_RECV_TAIL(rd, async_read); +} + +/* + a handler for async write replies + */ +static void async_write(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_write_recv(c_req, async->parms); + req->async.send_fn(req); +} + +/* + write to a file +*/ +static NTSTATUS cvfs_write(struct request_context *req, union smb_write *wr) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_write(private->tree, wr); + } + + c_req = smb_raw_write_send(private->tree, wr); + + ASYNC_RECV_TAIL(wr, async_write); +} + +/* + seek in a file +*/ +static NTSTATUS cvfs_seek(struct request_context *req, struct smb_seek *io) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + flush a file +*/ +static NTSTATUS cvfs_flush(struct request_context *req, struct smb_flush *io) +{ + return NT_STATUS_OK; +} + +/* + close a file +*/ +static NTSTATUS cvfs_close(struct request_context *req, union smb_close *io) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_close(private->tree, io); + } + + c_req = smb_raw_close_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; +} + +/* + exit - closing files? +*/ +static NTSTATUS cvfs_exit(struct request_context *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + lock a byte range +*/ +static NTSTATUS cvfs_lock(struct request_context *req, union smb_lock *lck) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_lock(private->tree, lck); + } + + c_req = smb_raw_lock_send(private->tree, lck); + SIMPLE_ASYNC_TAIL; +} + +/* + set info on a open file +*/ +static NTSTATUS cvfs_setfileinfo(struct request_context *req, + union smb_setfileinfo *info) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_setfileinfo(private->tree, info); + } + c_req = smb_raw_setfileinfo_send(private->tree, info); + + SIMPLE_ASYNC_TAIL; +} + + +/* + a handler for async fsinfo replies + */ +static void async_fsinfo(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_fsinfo_recv(c_req, req->mem_ctx, async->parms); + req->async.send_fn(req); +} + +/* + return filesystem space info +*/ +static NTSTATUS cvfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_fsinfo(private->tree, req->mem_ctx, fs); + } + + c_req = smb_raw_fsinfo_send(private->tree, req->mem_ctx, fs); + + ASYNC_RECV_TAIL(fs, async_fsinfo); +} + +/* + return print queue info +*/ +static NTSTATUS cvfs_lpq(struct request_context *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS cvfs_search_first(struct request_context *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + + return smb_raw_search_first(private->tree, req->mem_ctx, io, search_private, callback); +} + +/* continue a search */ +static NTSTATUS cvfs_search_next(struct request_context *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + + return smb_raw_search_next(private->tree, req->mem_ctx, io, search_private, callback); +} + +/* close a search */ +static NTSTATUS cvfs_search_close(struct request_context *req, union smb_search_close *io) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + + return smb_raw_search_close(private->tree, io); +} + +/* + a handler for async trans2 replies + */ +static void async_trans2(struct cli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct request_context *req = async->req; + req->async.status = smb_raw_trans2_recv(c_req, req->mem_ctx, async->parms); + req->async.send_fn(req); +} + +/* raw trans2 */ +static NTSTATUS cvfs_trans2(struct request_context *req, struct smb_trans2 *trans2) +{ + struct cvfs_private *private = req->conn->ntvfs_private; + struct cli_request *c_req; + + if (!req->async.send_fn) { + return smb_raw_trans2(private->tree, req->mem_ctx, trans2); + } + + c_req = smb_raw_trans2_send(private->tree, trans2); + + ASYNC_RECV_TAIL(trans2, async_trans2); +} + +/* + initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem + */ +BOOL cifs_vfs_init(void) +{ + BOOL ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = cvfs_connect; + ops.disconnect = cvfs_disconnect; + ops.unlink = cvfs_unlink; + ops.chkpath = cvfs_chkpath; + ops.qpathinfo = cvfs_qpathinfo; + ops.setpathinfo = cvfs_setpathinfo; + ops.open = cvfs_open; + ops.mkdir = cvfs_mkdir; + ops.rmdir = cvfs_rmdir; + ops.rename = cvfs_rename; + ops.copy = cvfs_copy; + ops.ioctl = cvfs_ioctl; + ops.read = cvfs_read; + ops.write = cvfs_write; + ops.seek = cvfs_seek; + ops.flush = cvfs_flush; + ops.close = cvfs_close; + ops.exit = cvfs_exit; + ops.lock = cvfs_lock; + ops.setfileinfo = cvfs_setfileinfo; + ops.qfileinfo = cvfs_qfileinfo; + ops.fsinfo = cvfs_fsinfo; + ops.lpq = cvfs_lpq; + ops.search_first = cvfs_search_first; + ops.search_next = cvfs_search_next; + ops.search_close = cvfs_search_close; + + /* only define this one for trans2 testing */ + ops.trans2 = cvfs_trans2; + + /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ + + ret = ntvfs_register("cifs", NTVFS_DISK, &ops); + + if (!ret) { + DEBUG(0,("Failed to register CIFS backend!\n")); + return False; + } + + return True; +} diff --git a/source4/ntvfs/ipc/README b/source4/ntvfs/ipc/README new file mode 100644 index 0000000000..059a7146e5 --- /dev/null +++ b/source4/ntvfs/ipc/README @@ -0,0 +1,5 @@ +This is the IPC$ backend for Samba. NTVFS operations that are made on +IPC$ shares are directed here by default. Most file operations +are not supported on IPC$ shares. + + diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c new file mode 100644 index 0000000000..fe310d104e --- /dev/null +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -0,0 +1,295 @@ +/* + Unix SMB/CIFS implementation. + default IPC$ NTVFS backend + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements the IPC$ backend, called by the NTVFS subsystem to + handle requests on IPC$ shares +*/ + + +#include "includes.h" + +/* + connect to a share - always works +*/ +static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) +{ + struct tcon_context *conn = req->conn; + + conn->fs_type = talloc_strdup(conn->mem_ctx, "IPC"); + conn->dev_type = talloc_strdup(conn->mem_ctx, "IPC"); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS ipc_disconnect(struct tcon_context *tcon) +{ + return NT_STATUS_OK; +} + +/* + delete a file +*/ +static NTSTATUS ipc_unlink(struct request_context *req, struct smb_unlink *unl) +{ + return NT_STATUS_ACCESS_DENIED; +} + + +/* + ioctl interface - we don't do any +*/ +static NTSTATUS ipc_ioctl(struct request_context *req, struct smb_ioctl *io) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + check if a directory exists +*/ +static NTSTATUS ipc_chkpath(struct request_context *req, struct smb_chkpath *cp) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + return info on a pathname +*/ +static NTSTATUS ipc_qpathinfo(struct request_context *req, union smb_fileinfo *info) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + set info on a pathname +*/ +static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + open a file +*/ +static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + create a directory +*/ +static NTSTATUS ipc_mkdir(struct request_context *req, union smb_mkdir *md) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + remove a directory +*/ +static NTSTATUS ipc_rmdir(struct request_context *req, struct smb_rmdir *rd) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + rename a set of files +*/ +static NTSTATUS ipc_rename(struct request_context *req, struct smb_rename *ren) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + copy a set of files +*/ +static NTSTATUS ipc_copy(struct request_context *req, struct smb_copy *cp) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + read from a file +*/ +static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + write to a file +*/ +static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + seek in a file +*/ +static NTSTATUS ipc_seek(struct request_context *req, struct smb_seek *io) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + flush a file +*/ +static NTSTATUS ipc_flush(struct request_context *req, struct smb_flush *io) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + close a file +*/ +static NTSTATUS ipc_close(struct request_context *req, union smb_close *io) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + exit - closing files? +*/ +static NTSTATUS ipc_exit(struct request_context *req) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + lock a byte range +*/ +static NTSTATUS ipc_lock(struct request_context *req, union smb_lock *lck) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + set info on a open file +*/ +static NTSTATUS ipc_setfileinfo(struct request_context *req, union smb_setfileinfo *info) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + query info on a open file +*/ +static NTSTATUS ipc_qfileinfo(struct request_context *req, union smb_fileinfo *info) +{ + return NT_STATUS_ACCESS_DENIED; +} + + +/* + return filesystem info +*/ +static NTSTATUS ipc_fsinfo(struct request_context *req, union smb_fsinfo *fs) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + return print queue info +*/ +static NTSTATUS ipc_lpq(struct request_context *req, union smb_lpq *lpq) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +NTSTATUS ipc_search_first(struct request_context *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + continue listing files in a directory +*/ +NTSTATUS ipc_search_next(struct request_context *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + end listing files in a directory +*/ +NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *io) +{ + return NT_STATUS_ACCESS_DENIED; +} + + +/* + initialialise the IPC backend, registering ourselves with the ntvfs subsystem + */ +BOOL ipc_vfs_init(void) +{ + BOOL ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = ipc_connect; + ops.disconnect = ipc_disconnect; + ops.unlink = ipc_unlink; + ops.chkpath = ipc_chkpath; + ops.qpathinfo = ipc_qpathinfo; + ops.setpathinfo = ipc_setpathinfo; + ops.open = ipc_open; + ops.mkdir = ipc_mkdir; + ops.rmdir = ipc_rmdir; + ops.rename = ipc_rename; + ops.copy = ipc_copy; + ops.ioctl = ipc_ioctl; + ops.read = ipc_read; + ops.write = ipc_write; + ops.seek = ipc_seek; + ops.flush = ipc_flush; + ops.close = ipc_close; + ops.exit = ipc_exit; + ops.lock = ipc_lock; + ops.setfileinfo = ipc_setfileinfo; + ops.qfileinfo = ipc_qfileinfo; + ops.fsinfo = ipc_fsinfo; + ops.lpq = ipc_lpq; + ops.search_first = ipc_search_first; + ops.search_next = ipc_search_next; + ops.search_close = ipc_search_close; + + /* register ourselves with the NTVFS subsystem. */ + ret = ntvfs_register("ipc", NTVFS_IPC, &ops); + + if (!ret) { + DEBUG(0,("Failed to register IPC backend!\n")); + return False; + } + + return True; +} diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c new file mode 100644 index 0000000000..57cdb97e9f --- /dev/null +++ b/source4/ntvfs/ntvfs_base.c @@ -0,0 +1,145 @@ +/* + Unix SMB/CIFS implementation. + NTVFS base code + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements the core code for all NTVFS modules. Backends register themselves here. +*/ + +#include "includes.h" + + +/* the list of currently registered NTVFS backends, note that there + * can be more than one backend with the same name, as long as they + * have different typesx */ +static struct { + const char *name; + enum ntvfs_type type; + struct ntvfs_ops *ops; +} *backends = NULL; +static int num_backends; + +/* + register a NTVFS backend. + + The 'name' can be later used by other backends to find the operations + structure for this backend. + + The 'type' is used to specify whether this is for a disk, printer or IPC$ share +*/ +BOOL ntvfs_register(const char *name, enum ntvfs_type type, struct ntvfs_ops *ops) +{ + if (ntvfs_backend_byname(name, type) != NULL) { + /* its already registered! */ + DEBUG(2,("NTVFS backend '%s' for type %d already registered\n", + name, (int)type)); + return False; + } + + backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); + if (!backends) { + smb_panic("out of memory in ntvfs_register"); + } + + backends[num_backends].name = smb_xstrdup(name); + backends[num_backends].type = type; + backends[num_backends].ops = smb_xmemdup(ops, sizeof(*ops)); + + num_backends++; + + return True; +} + + +/* + return the operations structure for a named backend of the specified type +*/ +struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) +{ + int i; + + for (i=0;isizeof_ntvfs_ops = sizeof(struct ntvfs_ops); + sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T); + sizes->sizeof_tcon_context = sizeof(struct tcon_context); + sizes->sizeof_request_context = sizeof(struct request_context); + + return NTVFS_INTERFACE_VERSION; +} + + +/* + initialise the NTVFS subsystem +*/ +BOOL ntvfs_init(void) +{ + /* initialise our 3 basic backends. These are assumed to be + * present and are always built in */ + if (!posix_vfs_init() || + !ipc_vfs_init() || + !print_vfs_init()) { + return False; + } + /* initialize optional backends, e.g. CIFS. We allow failures here. */ + cifs_vfs_init(); + +#if WITH_NTVFS_STFS + tank_vfs_init(); +#endif + + DEBUG(3,("NTVFS version %d initialised\n", NTVFS_INTERFACE_VERSION)); + return True; +} + + +/* + initialise a connection structure to point at a NTVFS backend +*/ +NTSTATUS ntvfs_init_connection(struct request_context *req) +{ + const char *handler = lp_ntvfs_handler(req->conn->service); + + if (strequal(handler, "default")) + handler = "ipc"; + + req->conn->ntvfs_ops = ntvfs_backend_byname(handler, req->conn->type); + + if (!req->conn->ntvfs_ops) { + DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handler, req->conn->type)); + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/ntvfs_dfs.c b/source4/ntvfs/ntvfs_dfs.c new file mode 100644 index 0000000000..7acd1f7cbb --- /dev/null +++ b/source4/ntvfs/ntvfs_dfs.c @@ -0,0 +1,117 @@ +/* + Unix SMB/CIFS implementation. + NTVFS base code + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements the core code for all NTVFS modules. Backends register themselves here. +*/ + +#include "includes.h" + + +/* the list of currently registered NTVFS backends, note that there + * can be more than one backend with the same name, as long as they + * have different typesx */ +static struct { + const char *name; + enum ntvfs_type type; + struct ntvfs_ops *ops; +} *backends = NULL; +static int num_backends; + +/* + register a NTVFS backend. + + The 'name' can be later used by other backends to find the operations + structure for this backend. + + The 'type' is used to specify whether this is for a disk, printer or IPC$ share +*/ +BOOL ntvfs_register(const char *name, enum ntvfs_type type, struct ntvfs_ops *ops) +{ + if (ntvfs_backend_byname(name, type) != NULL) { + /* its already registered! */ + DEBUG(2,("NTVFS backend '%s' for type %d already registered\n", + name, (int)type)); + return False; + } + + backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); + if (!backends) { + smb_panic("out of memory in ntvfs_register"); + } + + backends[num_backends].name = smb_xstrdup(name); + backends[num_backends].type = type; + backends[num_backends].ops = smb_xmemdup(ops, sizeof(*ops)); + + num_backends++; + + return True; +} + + +/* + return the operations structure for a named backend of the specified type +*/ +struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) +{ + int i; + + for (i=0;isizeof_ntvfs_ops = sizeof(struct ntvfs_ops); + sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T); + sizes->sizeof_tcon_context = sizeof(struct tcon_context); + + return NTVFS_INTERFACE_VERSION; +} + + +/* + initialise the NTVFS subsystem +*/ +BOOL ntvfs_init(void) +{ + /* initialise our 3 basic backends. These are assumed to be + * present and are always built in */ + if (!posix_vfs_init() || + !ipc_vfs_init() || + !print_vfs_init()) { + return False; + } + + DEBUG(3,("NTVFS version %d initialised\n", NTVFS_INTERFACE_VERSION)); + return True; +} diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c new file mode 100644 index 0000000000..def448a671 --- /dev/null +++ b/source4/ntvfs/ntvfs_generic.c @@ -0,0 +1,544 @@ +/* + Unix SMB/CIFS implementation. + + NTVFS generic level mapping code + + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements mappings between info levels for NTVFS backend calls + + the idea is that each of these functions implements one of the NTVFS + backend calls in terms of the 'generic' call. All backends that use + these functions must supply the generic call, but can if it wants to + also implement other levels if the need arises + + this allows backend writers to only implement one varient of each + call unless they need fine grained control of the calls. +*/ + +#include "includes.h" + +/* + see if a filename ends in EXE COM DLL or SYM. This is needed for the DENY_DOS mapping for OpenX +*/ +static BOOL is_exe_file(const char *fname) +{ + char *p; + p = strrchr(fname, '.'); + if (!p) { + return False; + } + p++; + if (strcasecmp(p, "EXE") == 0 || + strcasecmp(p, "COM") == 0 || + strcasecmp(p, "DLL") == 0 || + strcasecmp(p, "SYM") == 0) { + return True; + } + return False; +} + + +/* + NTVFS open generic to any mapper +*/ +NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) +{ + NTSTATUS status; + union smb_open io2; + + if (io->generic.level == RAW_OPEN_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + + switch (io->generic.level) { + case RAW_OPEN_OPENX: + ZERO_STRUCT(io2.generic.in); + io2.generic.level = RAW_OPEN_GENERIC; + if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) { + io2.generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; + } + if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { + io2.generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + } + + switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { + case OPENX_MODE_ACCESS_READ: + io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + break; + case OPENX_MODE_ACCESS_WRITE: + io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + break; + case OPENX_MODE_ACCESS_RDWR: + case OPENX_MODE_ACCESS_FCB: + io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS; + break; + } + + switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { + case OPENX_MODE_DENY_READ: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_WRITE: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + break; + case OPENX_MODE_DENY_ALL: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + case OPENX_MODE_DENY_NONE: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_DOS: + /* DENY_DOS is quite strange - it depends on the filename! */ + if (is_exe_file(io->openx.in.fname)) { + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + } else { + if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == + OPENX_MODE_ACCESS_READ) { + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + } else { + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + } + } + break; + case OPENX_MODE_DENY_FCB: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + } + + switch (io->openx.in.open_func) { + case (OPENX_OPEN_FUNC_FAIL): + io2.generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + case (OPENX_OPEN_FUNC_OPEN): + io2.generic.in.open_disposition = NTCREATEX_DISP_OPEN; + break; + case (OPENX_OPEN_FUNC_TRUNC): + io2.generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; + break; + case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): + io2.generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): + io2.generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + break; + case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): + io2.generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; + break; + } + io2.generic.in.alloc_size = io->openx.in.size; + io2.generic.in.file_attr = io->openx.in.file_attrs; + io2.generic.in.fname = io->openx.in.fname; + + status = req->conn->ntvfs_ops->open(req, &io2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ZERO_STRUCT(io->openx.out); + io->openx.out.fnum = io2.generic.out.fnum; + io->openx.out.attrib = io2.generic.out.attrib; + io->openx.out.write_time = nt_time_to_unix(&io2.generic.out.write_time); + io->openx.out.size = io2.generic.out.size; + + return NT_STATUS_OK; + + + case RAW_OPEN_OPEN: + ZERO_STRUCT(io2.generic.in); + io2.generic.level = RAW_OPEN_GENERIC; + io2.generic.in.file_attr = io->open.in.search_attrs; + io2.generic.in.fname = io->open.in.fname; + io2.generic.in.open_disposition = NTCREATEX_DISP_OPEN; + DEBUG(9,("ntvfs_map_open(OPEN): mapping flags=0x%x\n", + io->open.in.flags)); + switch (io->open.in.flags & OPEN_FLAGS_MODE_MASK) { + case OPEN_FLAGS_OPEN_READ: + io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io->open.out.rmode = DOS_OPEN_RDONLY; + break; + case OPEN_FLAGS_OPEN_WRITE: + io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io->open.out.rmode = DOS_OPEN_WRONLY; + break; + case OPEN_FLAGS_OPEN_RDWR: + case 0xf: /* FCB mode */ + io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS; + io->open.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ + break; + default: + DEBUG(2,("ntvfs_map_open(OPEN): invalid mode 0x%x\n", + io->open.in.flags & OPEN_FLAGS_MODE_MASK)); + return NT_STATUS_INVALID_PARAMETER; + } + + switch(io->open.in.flags & OPEN_FLAGS_DENY_MASK) { + case OPEN_FLAGS_DENY_DOS: + /* DENY_DOS is quite strange - it depends on the filename! */ + /* REWRITE: is this necessary for OPEN? */ + if (is_exe_file(io->open.in.fname)) { + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + } else { + if ((io->open.in.flags & OPEN_FLAGS_MODE_MASK) == + OPEN_FLAGS_OPEN_READ) { + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + } else { + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + } + } + break; + case OPEN_FLAGS_DENY_ALL: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + case OPEN_FLAGS_DENY_WRITE: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + break; + case OPEN_FLAGS_DENY_READ: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPEN_FLAGS_DENY_NONE: + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE; + break; + case 0x70: /* FCB mode */ + io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + default: + DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", + io->open.in.flags & OPEN_FLAGS_DENY_MASK)); + return NT_STATUS_INVALID_PARAMETER; + } + DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", + io->open.in.flags, io2.generic.in.access_mask, io2.generic.in.share_access)); + + status = req->conn->ntvfs_ops->open(req, &io2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ZERO_STRUCT(io->openx.out); + io->open.out.fnum = io2.generic.out.fnum; + io->open.out.attrib = io2.generic.out.attrib; + io->open.out.write_time = nt_time_to_unix(&io2.generic.out.write_time); + io->open.out.size = io2.generic.out.size; + io->open.out.rmode = DOS_OPEN_RDWR; + + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; +} + + +/* + NTVFS fsinfo generic to any mapper +*/ +NTSTATUS ntvfs_map_fsinfo(struct request_context *req, union smb_fsinfo *fs) +{ + NTSTATUS status; + union smb_fsinfo fs2; + + if (fs->generic.level == RAW_QFS_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + + /* ask the backend for the generic info */ + fs2.generic.level = RAW_QFS_GENERIC; + + status = req->conn->ntvfs_ops->fsinfo(req, &fs2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* and convert it to the required level */ + switch (fs->generic.level) { + case RAW_QFS_GENERIC: + return NT_STATUS_INVALID_LEVEL; + + case RAW_QFS_DSKATTR: { + /* map from generic to DSKATTR */ + unsigned bpunit = 64; + + /* we need to scale the sizes to fit */ + for (bpunit=64; bpunit<0x10000; bpunit *= 2) { + if (fs2.generic.out.blocks_total * (double)fs2.generic.out.block_size < bpunit * 512 * 65535.0) { + break; + } + } + + fs->dskattr.out.blocks_per_unit = bpunit; + fs->dskattr.out.block_size = 512; + fs->dskattr.out.units_total = + (fs2.generic.out.blocks_total * (double)fs2.generic.out.block_size) / (bpunit * 512); + fs->dskattr.out.units_free = + (fs2.generic.out.blocks_free * (double)fs2.generic.out.block_size) / (bpunit * 512); + + /* we must return a maximum of 2G to old DOS systems, or they get very confused */ + if (bpunit > 64 && req->smb->negotiate.protocol <= PROTOCOL_LANMAN2) { + fs->dskattr.out.blocks_per_unit = 64; + fs->dskattr.out.units_total = 0xFFFF; + fs->dskattr.out.units_free = 0xFFFF; + } + return NT_STATUS_OK; + } + + case RAW_QFS_ALLOCATION: + fs->allocation.out.fs_id = fs2.generic.out.fs_id; + fs->allocation.out.total_alloc_units = fs2.generic.out.blocks_total; + fs->allocation.out.avail_alloc_units = fs2.generic.out.blocks_free; + fs->allocation.out.sectors_per_unit = 1; + fs->allocation.out.bytes_per_sector = fs2.generic.out.block_size; + return NT_STATUS_OK; + + case RAW_QFS_VOLUME: + fs->volume.out.serial_number = fs2.generic.out.serial_number; + fs->volume.out.volume_name.s = fs2.generic.out.volume_name; + return NT_STATUS_OK; + + case RAW_QFS_VOLUME_INFO: + case RAW_QFS_VOLUME_INFORMATION: + fs->volume_info.out.create_time = fs2.generic.out.create_time; + fs->volume_info.out.serial_number = fs2.generic.out.serial_number; + fs->volume_info.out.volume_name.s = fs2.generic.out.volume_name; + return NT_STATUS_OK; + + case RAW_QFS_SIZE_INFO: + case RAW_QFS_SIZE_INFORMATION: + fs->size_info.out.total_alloc_units = fs2.generic.out.blocks_total; + fs->size_info.out.avail_alloc_units = fs2.generic.out.blocks_free; + fs->size_info.out.sectors_per_unit = 1; + fs->size_info.out.bytes_per_sector = fs2.generic.out.block_size; + return NT_STATUS_OK; + + case RAW_QFS_DEVICE_INFO: + case RAW_QFS_DEVICE_INFORMATION: + fs->device_info.out.device_type = fs2.generic.out.device_type; + fs->device_info.out.characteristics = fs2.generic.out.device_characteristics; + return NT_STATUS_OK; + + case RAW_QFS_ATTRIBUTE_INFO: + case RAW_QFS_ATTRIBUTE_INFORMATION: + fs->attribute_info.out.fs_attr = fs2.generic.out.fs_attr; + fs->attribute_info.out.max_file_component_length = fs2.generic.out.max_file_component_length; + fs->attribute_info.out.fs_type.s = fs2.generic.out.fs_type; + return NT_STATUS_OK; + + case RAW_QFS_QUOTA_INFORMATION: + ZERO_STRUCT(fs->quota_information.out.unknown); + fs->quota_information.out.quota_soft = fs2.generic.out.quota_soft; + fs->quota_information.out.quota_hard = fs2.generic.out.quota_hard; + fs->quota_information.out.quota_flags = fs2.generic.out.quota_flags; + return NT_STATUS_OK; + + case RAW_QFS_FULL_SIZE_INFORMATION: + fs->full_size_information.out.total_alloc_units = fs2.generic.out.blocks_total; + fs->full_size_information.out.call_avail_alloc_units = fs2.generic.out.blocks_free; + fs->full_size_information.out.actual_avail_alloc_units = fs2.generic.out.blocks_free; + fs->full_size_information.out.sectors_per_unit = 1; + fs->full_size_information.out.bytes_per_sector = fs2.generic.out.block_size; + return NT_STATUS_OK; + + case RAW_QFS_OBJECTID_INFORMATION: + fs->objectid_information.out.guid = fs2.generic.out.guid; + ZERO_STRUCT(fs->objectid_information.out.unknown); + return NT_STATUS_OK; + } + + + return NT_STATUS_INVALID_LEVEL; +} + + +/* + NTVFS fileinfo generic to any mapper +*/ +NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *info, union smb_fileinfo *info2) +{ + /* and convert it to the required level using results in info2 */ + switch (info->generic.level) { + case RAW_FILEINFO_GENERIC: + return NT_STATUS_INVALID_LEVEL; + case RAW_FILEINFO_GETATTR: + info->getattr.out.attrib = info2->generic.out.attrib & 0x3f; + info->getattr.out.size = info2->generic.out.size; + info->getattr.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); + return NT_STATUS_OK; + + case RAW_FILEINFO_GETATTRE: + info->getattre.out.attrib = info2->generic.out.attrib; + info->getattre.out.size = info2->generic.out.size; + info->getattre.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); + info->getattre.out.create_time = nt_time_to_unix(&info2->generic.out.create_time); + info->getattre.out.access_time = nt_time_to_unix(&info2->generic.out.access_time); + info->getattre.out.alloc_size = info2->generic.out.alloc_size; + return NT_STATUS_OK; + + case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: + info->network_open_information.out.create_time = info2->generic.out.create_time; + info->network_open_information.out.access_time = info2->generic.out.access_time; + info->network_open_information.out.write_time = info2->generic.out.write_time; + info->network_open_information.out.change_time = info2->generic.out.change_time; + info->network_open_information.out.alloc_size = info2->generic.out.alloc_size; + info->network_open_information.out.size = info2->generic.out.size; + info->network_open_information.out.attrib = info2->generic.out.attrib; + return NT_STATUS_OK; + + case RAW_FILEINFO_ALL_INFO: + case RAW_FILEINFO_ALL_INFORMATION: + info->all_info.out.create_time = info2->generic.out.create_time; + info->all_info.out.access_time = info2->generic.out.access_time; + info->all_info.out.write_time = info2->generic.out.write_time; + info->all_info.out.change_time = info2->generic.out.change_time; + info->all_info.out.attrib = info2->generic.out.attrib; + info->all_info.out.alloc_size = info2->generic.out.alloc_size; + info->all_info.out.size = info2->generic.out.size; + info->all_info.out.nlink = info2->generic.out.nlink; + info->all_info.out.delete_pending = info2->generic.out.delete_pending; + info->all_info.out.directory = info2->generic.out.directory; + info->all_info.out.ea_size = info2->generic.out.ea_size; + info->all_info.out.fname.s = info2->generic.out.fname.s; + info->all_info.out.fname.private_length = info2->generic.out.fname.private_length; + return NT_STATUS_OK; + + case RAW_FILEINFO_BASIC_INFO: + case RAW_FILEINFO_BASIC_INFORMATION: + info->basic_info.out.create_time = info2->generic.out.create_time; + info->basic_info.out.access_time = info2->generic.out.access_time; + info->basic_info.out.write_time = info2->generic.out.write_time; + info->basic_info.out.change_time = info2->generic.out.change_time; + info->basic_info.out.attrib = info2->generic.out.attrib; + return NT_STATUS_OK; + + case RAW_FILEINFO_STANDARD: + info->standard.out.create_time = nt_time_to_unix(&info2->generic.out.create_time); + info->standard.out.access_time = nt_time_to_unix(&info2->generic.out.access_time); + info->standard.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); + info->standard.out.size = info2->generic.out.size; + info->standard.out.alloc_size = info2->generic.out.alloc_size; + info->standard.out.attrib = info2->generic.out.attrib; + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_SIZE: + info->ea_size.out.create_time = nt_time_to_unix(&info2->generic.out.create_time); + info->ea_size.out.access_time = nt_time_to_unix(&info2->generic.out.access_time); + info->ea_size.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); + info->ea_size.out.size = info2->generic.out.size; + info->ea_size.out.alloc_size = info2->generic.out.alloc_size; + info->ea_size.out.attrib = info2->generic.out.attrib; + info->ea_size.out.ea_size = info2->generic.out.ea_size; + return NT_STATUS_OK; + + case RAW_FILEINFO_STANDARD_INFO: + case RAW_FILEINFO_STANDARD_INFORMATION: + info->standard_info.out.alloc_size = info2->generic.out.alloc_size; + info->standard_info.out.size = info2->generic.out.size; + info->standard_info.out.nlink = info2->generic.out.nlink; + info->standard_info.out.delete_pending = info2->generic.out.delete_pending; + info->standard_info.out.directory = info2->generic.out.directory; + return NT_STATUS_OK; + + case RAW_FILEINFO_INTERNAL_INFORMATION: + info->internal_information.out.device = info2->generic.out.device; + info->internal_information.out.inode = info2->generic.out.inode; + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_INFO: + case RAW_FILEINFO_EA_INFORMATION: + info->ea_info.out.ea_size = info2->generic.out.ea_size; + return NT_STATUS_OK; + + case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: + info->attribute_tag_information.out.attrib = info2->generic.out.attrib; + info->attribute_tag_information.out.reparse_tag = info2->generic.out.reparse_tag; + return NT_STATUS_OK; + + case RAW_FILEINFO_STREAM_INFO: + case RAW_FILEINFO_STREAM_INFORMATION: + /* setup a single data stream */ + info->stream_info.out.num_streams = info2->generic.out.num_streams; + info->stream_info.out.streams = talloc(req->mem_ctx, sizeof(info2->stream_info.out.streams[0])); + if (!info->stream_info.out.streams) { + return NT_STATUS_NO_MEMORY; + } + info->stream_info.out.streams[0].size = info2->generic.out.streams[0].size; + info->stream_info.out.streams[0].alloc_size = info2->generic.out.streams[0].alloc_size; + info->stream_info.out.streams[0].stream_name.s = info2->generic.out.streams[0].stream_name.s; + info->stream_info.out.streams[0].stream_name.private_length = info->generic.out.streams[0].stream_name.private_length; + return NT_STATUS_OK; + + case RAW_FILEINFO_NAME_INFO: + case RAW_FILEINFO_NAME_INFORMATION: + info->name_info.out.fname.s = info2->generic.out.fname.s; + info->name_info.out.fname.private_length = info2->generic.out.fname.private_length; + return NT_STATUS_OK; + + case RAW_FILEINFO_ALT_NAME_INFO: + case RAW_FILEINFO_ALT_NAME_INFORMATION: + info->alt_name_info.out.fname.s = info2->generic.out.alt_fname.s; + info->alt_name_info.out.fname.private_length = info2->generic.out.alt_fname.private_length; + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; +} + +/* + NTVFS fileinfo generic to any mapper +*/ +NTSTATUS ntvfs_map_qfileinfo(struct request_context *req, union smb_fileinfo *info) +{ + NTSTATUS status; + union smb_fileinfo info2; + + if (info->generic.level == RAW_FILEINFO_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + + /* ask the backend for the generic info */ + info2.generic.level = RAW_FILEINFO_GENERIC; + info2.generic.in.fnum = info->generic.in.fnum; + + status = req->conn->ntvfs_ops->qfileinfo(req, &info2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + return ntvfs_map_fileinfo(req, info, &info2); +} + +/* + NTVFS pathinfo generic to any mapper +*/ +NTSTATUS ntvfs_map_qpathinfo(struct request_context *req, union smb_fileinfo *info) +{ + NTSTATUS status; + union smb_fileinfo info2; + + if (info->generic.level == RAW_FILEINFO_GENERIC) { + return NT_STATUS_INVALID_LEVEL; + } + + /* ask the backend for the generic info */ + info2.generic.level = RAW_FILEINFO_GENERIC; + info2.generic.in.fname = info->generic.in.fname; + + status = req->conn->ntvfs_ops->qpathinfo(req, &info2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + return ntvfs_map_fileinfo(req, info, &info2); +} diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c new file mode 100644 index 0000000000..4036fb0935 --- /dev/null +++ b/source4/ntvfs/ntvfs_util.c @@ -0,0 +1,26 @@ +/* + Unix SMB/CIFS implementation. + NTVFS utility code + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements common utility functions that many NTVFS backends may wish to use +*/ + +#include "includes.h" + + diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c new file mode 100644 index 0000000000..b27e7493a0 --- /dev/null +++ b/source4/ntvfs/posix/vfs_posix.c @@ -0,0 +1,151 @@ +/* + Unix SMB/CIFS implementation. + POSIX NTVFS backend + Copyright (C) Andrew Tridgell 1992-2003 + Copyright (C) Andrew Bartlett 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements most of the POSIX NTVFS backend + This is the default backend +*/ + +#include "includes.h" + +/* + connect to a share - used when a tree_connect operation comes + in. For a disk based backend we needs to ensure that the base + directory exists (tho it doesn't need to be accessible by the user, + that comes later) +*/ +static NTSTATUS pvfs_connect(struct ntvfs_context *ctx, const char *sharename) +{ + struct stat st; + struct connection_struct *conn = ctx->conn; + NTSTATUS status; + + /* the directory must exist */ + if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { + DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", + conn->connectpath, lp_servicename(SNUM(conn)))); + return NT_STATUS_BAD_NETWORK_NAME; + } + + /* Initialise old VFS function pointers */ + if (!smbd_vfs_init(conn)) { + DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn)))); + return NT_STATUS_BAD_NETWORK_NAME; + } + + /* become the user for the rest */ + status = ntvfs_change_to_user(ctx); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* the posix backend can do preexec */ + status = ntvfs_connect_preexec(ctx); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* Invoke the old POSIX VFS make connection hook */ + if (conn->vfs_ops.connect && + conn->vfs_ops.connect(conn, lp_servicename(snum), user) < 0) { + DEBUG(0,("make_connection: POSIX VFS make connection failed!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + } + + + /* + * Print out the 'connected as' stuff here as we need + * to know the effective uid and gid we will be using + * (at least initially). + */ + if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) { + dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address ); + dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) ); + dbgtext( "initially as user %s ", user ); + dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() ); + dbgtext( "(pid %d)\n", (int)sys_getpid() ); + } + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS pvfs_disconnect(struct ntvfs_context *ctx) +{ + return NT_STATUS_OK; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS pvfs_unlink(struct ntvfs_context *ctx, const char *name, uint16 dirtype) +{ + NTSTATUS status; + + if (ntvfs_dfs_redirect(ctx, name)) { + return NT_STATUS_PATH_NOT_COVERED; + } + + status = unlink_internals(ctx->conn, dirtype, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ntvfs_run_change_notify_queue(); + + return NT_STATUS_OK; +} + + + + + + + +/* + initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem + */ +BOOL posix_vfs_init(void) +{ + BOOL ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = pvfs_connect; + ops.disconnect = pvfs_disconnect; + ops.unlink = pvfs_unlink; + + /* register ourselves with the NTVFS subsystem. We register under the name 'default' + as we wish to be the default backend */ + ret = ntvfs_register("default", NTVFS_DISK, &ops); + + if (!ret) { + DEBUG(0,("Failed to register POSIX backend!\n")); + return False; + } + + return True; +} diff --git a/source4/ntvfs/print/README b/source4/ntvfs/print/README new file mode 100644 index 0000000000..441c82dddd --- /dev/null +++ b/source4/ntvfs/print/README @@ -0,0 +1,3 @@ +This is the print NTVFS backend for Samba. NTVFS operations that are +made on print shares are directed here by default. Most directory +operations and many file operations are not supported on print shares. diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c new file mode 100644 index 0000000000..2563f0ad9c --- /dev/null +++ b/source4/ntvfs/print/vfs_print.c @@ -0,0 +1,104 @@ +/* + Unix SMB/CIFS implementation. + default print NTVFS backend + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements the print backend, called by the NTVFS subsystem to + handle requests on printing shares +*/ + +#include "includes.h" + +/* + connect to a share - used when a tree_connect operation comes + in. For printing shares this should check that the spool directory + is available +*/ +static NTSTATUS print_connect(struct request_context *req, const char *sharename) +{ + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS print_disconnect(struct tcon_context *conn) +{ + return NT_STATUS_OK; +} + +/* + lots of operations are not allowed on printing shares - mostly return NT_STATUS_ACCESS_DENIED +*/ +static NTSTATUS print_unlink(struct request_context *req, struct smb_unlink *unl) +{ + return NT_STATUS_ACCESS_DENIED; +} + + +/* + ioctl - used for job query +*/ +static NTSTATUS print_ioctl(struct request_context *req, struct smb_ioctl *io) +{ + char *p; + + if (io->in.request == IOCTL_QUERY_JOB_INFO) { + /* a request for the print job id of an open print job */ + io->out.blob = data_blob_talloc(req->mem_ctx, NULL, 32); + + memset(io->out.blob.data, 0, io->out.blob.length); + + p = io->out.blob.data; + SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); + push_string(NULL, p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); + push_string(NULL, p+18, lp_servicename(req->conn->service), 13, STR_TERMINATE|STR_ASCII); + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_PARAMETER; +} + + +/* + initialialise the print backend, registering ourselves with the ntvfs subsystem + */ +BOOL print_vfs_init(void) +{ + BOOL ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = print_connect; + ops.disconnect = print_disconnect; + ops.unlink = print_unlink; + ops.ioctl = print_ioctl; + + /* register ourselves with the NTVFS subsystem. We register under the name 'default' + as we wish to be the default backend */ + ret = ntvfs_register("default", NTVFS_PRINT, &ops); + + if (!ret) { + DEBUG(0,("Failed to register PRINT backend!\n")); + return False; + } + + return True; +} diff --git a/source4/ntvfs/reference/ref.h b/source4/ntvfs/reference/ref.h new file mode 100644 index 0000000000..00eab76094 --- /dev/null +++ b/source4/ntvfs/reference/ref.h @@ -0,0 +1,36 @@ + +struct rvfs_private { + /* the meta-data database */ + TDB_CONTEXT *tdb; + + /* the base directory */ + char *connectpath; + + /* a linked list of open searches */ + struct search_state *search; + + /* next available search handle */ + uint16 next_search_handle; +}; + +struct rvfs_dir { + uint_t count; + char *unix_dir; + struct { + char *name; + } *files; +}; + +struct search_state { + struct search_state *next, *prev; + TALLOC_CTX *mem_ctx; + uint16 handle; + uint_t current_index; + struct rvfs_dir *dir; +}; + + +struct ref_struct { + NTTIME mtime, ctime, atime, wtime; + char *; +}; diff --git a/source4/ntvfs/reference/ref_util.c b/source4/ntvfs/reference/ref_util.c new file mode 100644 index 0000000000..8234944ebd --- /dev/null +++ b/source4/ntvfs/reference/ref_util.c @@ -0,0 +1,142 @@ +/* + Unix SMB/CIFS implementation. + + simple NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + utility functions for simple backend +*/ + +#include "includes.h" +#include "svfs.h" + +/* + convert a windows path to a unix path - don't do any manging or case sensitive handling +*/ +char *svfs_unix_path(struct request_context *req, const char *name) +{ + struct svfs_private *private = req->conn->ntvfs_private; + char *ret; + + if (*name != '\\') { + ret = talloc_asprintf(req->mem_ctx, "%s/%s", private->connectpath, name); + } else { + ret = talloc_asprintf(req->mem_ctx, "%s%s", private->connectpath, name); + } + all_string_sub(ret, "\\", "/", 0); + + strlower(ret); + + return ret; +} + + +/* + read a directory and find all matching file names and stat info + returned names are separate unix and DOS names. The returned names + are relative to the directory +*/ +struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, const char *pattern) +{ + char *unix_path; + char *p, *mask; + struct svfs_dir *dir; + DIR *odir; + struct dirent *dent; + uint_t allocated = 0; + char *low_mask; + + unix_path = svfs_unix_path(req, pattern); + if (!unix_path) { return NULL; } + + dir = talloc(mem_ctx, sizeof(struct svfs_dir)); + if (!dir) { return NULL; } + + dir->count = 0; + dir->files = 0; + + /* find the base directory */ + p = strrchr(unix_path, '/'); + if (!p) { return NULL; } + + dir->unix_dir = talloc_strndup(mem_ctx, unix_path, PTR_DIFF(p, unix_path)); + if (!dir->unix_dir) { return NULL; } + + /* the wildcard pattern is the last part */ + mask = p+1; + + low_mask = talloc_strdup(mem_ctx, mask); + if (!low_mask) { return NULL; } + strlower(low_mask); + + odir = opendir(dir->unix_dir); + if (!odir) { return NULL; } + + while ((dent = readdir(odir))) { + uint_t i = dir->count; + char *full_name; + char *low_name; + + low_name = talloc_strdup(mem_ctx, dent->d_name); + if (!low_name) { continue; } + strlower(low_name); + + /* check it matches the wildcard pattern */ + if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) { + continue; + } + + if (dir->count >= allocated) { + allocated = (allocated + 100) * 1.2; + dir->files = talloc_realloc(mem_ctx, dir->files, allocated * sizeof(dir->files[0])); + if (!dir->files) { + closedir(odir); + return NULL; + } + } + + dir->files[i].name = low_name; + if (!dir->files[i].name) { continue; } + + asprintf(&full_name, "%s/%s", dir->unix_dir, dir->files[i].name); + if (!full_name) { continue; } + + if (stat(full_name, &dir->files[i].st) == 0) { + dir->count++; + } + + free(full_name); + } + + closedir(odir); + + return dir; +} + + +/* + convert a unix stat struct to a dos attrib +*/ +uint32 svfs_file_attrib(struct stat *st) +{ + if (S_ISDIR(st->st_mode)) { + return FILE_ATTRIBUTE_DIRECTORY; + } + return 0; +} diff --git a/source4/ntvfs/reference/vfs_ref.c b/source4/ntvfs/reference/vfs_ref.c new file mode 100644 index 0000000000..b4fa2e61ff --- /dev/null +++ b/source4/ntvfs/reference/vfs_ref.c @@ -0,0 +1,843 @@ +/* + Unix SMB/CIFS implementation. + + simple NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements a very simple NTVFS filesystem backend. + + this backend largely ignores the POSIX -> CIFS mappings, just doing absolutely + minimal work to give a working backend. +*/ + +#include "includes.h" +#include "svfs.h" + +/* + connect to a share - used when a tree_connect operation comes + in. For a disk based backend we needs to ensure that the base + directory exists (tho it doesn't need to be accessible by the user, + that comes later) +*/ +static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) +{ + struct stat st; + struct tcon_context *conn = req->conn; + struct svfs_private *private; + + conn->ntvfs_private = talloc(conn->mem_ctx, sizeof(struct svfs_private)); + + private = conn->ntvfs_private; + + private->connectpath = talloc_strdup(conn->mem_ctx, lp_pathname(conn->service)); + + /* the directory must exist */ + if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { + DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", + private->connectpath, sharename)); + return NT_STATUS_BAD_NETWORK_NAME; + } + + conn->fs_type = talloc_strdup(conn->mem_ctx, "NTFS"); + conn->dev_type = talloc_strdup(conn->mem_ctx, "A:"); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS svfs_disconnect(struct request_context *req) +{ + return NT_STATUS_OK; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) +{ + char *unix_path; + + unix_path = svfs_unix_path(req, unl->in.pattern); + + /* ignoring wildcards ... */ + if (unlink(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + + +/* + ioctl interface - we don't do any +*/ +static NTSTATUS svfs_ioctl(struct request_context *req, struct smb_ioctl *io) +{ + return NT_STATUS_INVALID_PARAMETER; +} + +/* + check if a directory exists +*/ +static NTSTATUS svfs_chkpath(struct request_context *req, struct smb_chkpath *cp) +{ + char *unix_path; + struct stat st; + + unix_path = svfs_unix_path(req, cp->in.path); + + if (stat(unix_path, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + if (!S_ISDIR(st.st_mode)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + return NT_STATUS_OK; +} + +/* + approximately map a struct stat to a fileinfo struct +*/ +static NTSTATUS map_fileinfo(struct request_context *req, union smb_fileinfo *info, struct stat *st) +{ + switch (info->generic.level) { + case SMB_FILEINFO_NETWORK_OPEN_INFORMATION: + unix_to_nt_time(&info->netopen.out.create_time, st->st_ctime); + unix_to_nt_time(&info->netopen.out.access_time, st->st_atime); + unix_to_nt_time(&info->netopen.out.write_time, st->st_mtime); + unix_to_nt_time(&info->netopen.out.change_time, st->st_mtime); + info->netopen.out.alloc_size = st->st_size; + info->netopen.out.size = st->st_size; + info->netopen.out.attrib = svfs_file_attrib(st); + info->netopen.out.unknown = 0; + return NT_STATUS_OK; + + case SMB_FILEINFO_ALL_INFO: + unix_to_nt_time(&info->all_info.out.create_time, st->st_ctime); + unix_to_nt_time(&info->all_info.out.access_time, st->st_atime); + unix_to_nt_time(&info->all_info.out.write_time, st->st_mtime); + unix_to_nt_time(&info->all_info.out.change_time, st->st_mtime); + info->all_info.out.attrib = svfs_file_attrib(st); + info->all_info.out.alloc_size = st->st_size; + info->all_info.out.size = st->st_size; + info->all_info.out.nlink = st->st_nlink; + info->all_info.out.delete_pending = 0; + info->all_info.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; + info->all_info.out.index_number = st->st_ino; + info->all_info.out.ea_size = 0; + info->all_info.out.access_flags = 0xd01BF; /* what is this!? */ + info->all_info.out.current_offset = 0; + info->all_info.out.open_mode = 0; /* what do do put here!? */ + info->all_info.out.alignment_requirement = 0; /* what do do put here!? */ + info->all_info.out.fname = talloc_strdup(req->mem_ctx, "TODO - STORE FILENAME"); + return NT_STATUS_OK; + + case SMB_FILEINFO_BASIC: + unix_to_nt_time(&info->basic.out.create_time, st->st_ctime); + unix_to_nt_time(&info->basic.out.access_time, st->st_atime); + unix_to_nt_time(&info->basic.out.write_time, st->st_mtime); + unix_to_nt_time(&info->basic.out.change_time, st->st_mtime); + info->basic.out.attrib = svfs_file_attrib(st); + return NT_STATUS_OK; + + case SMB_FILEINFO_INFO_STANDARD: + info->info_standard.out.create_time = st->st_ctime; + info->info_standard.out.access_time = st->st_atime; + info->info_standard.out.write_time = st->st_mtime; + info->info_standard.out.size = st->st_size; + info->info_standard.out.alloc_size = st->st_size; + info->info_standard.out.attrib = svfs_file_attrib(st); + return NT_STATUS_OK; + + case SMB_FILEINFO_INFO_STANDARD_EA: + info->info_standard_ea.out.create_time = st->st_ctime; + info->info_standard_ea.out.access_time = st->st_atime; + info->info_standard_ea.out.write_time = st->st_mtime; + info->info_standard_ea.out.size = st->st_size; + info->info_standard_ea.out.alloc_size = st->st_size; + info->info_standard_ea.out.attrib = svfs_file_attrib(st); + info->info_standard_ea.out.ea_size = 0; + return NT_STATUS_OK; + + case SMB_FILEINFO_STANDARD_INFO: + info->standard_info.out.alloc_size = st->st_size; + info->standard_info.out.size = st->st_size; + info->standard_info.out.nlink = st->st_nlink; + info->standard_info.out.delete_pending = 0; + info->standard_info.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; + info->standard_info.out.unknown = 0; + return NT_STATUS_OK; + + case SMB_FILEINFO_INTERNAL: + info->internal.out.device = st->st_dev; + info->internal.out.device = st->st_ino; + return NT_STATUS_OK; + + case SMB_FILEINFO_EA: + info->ea.out.unknown = 0; + return NT_STATUS_OK; + + case SMB_FILEINFO_ATTRIB_TAGINFO: + info->tag.out.attrib = svfs_file_attrib(st); + info->tag.out.reparse_tag = 0; + return NT_STATUS_OK; + + case SMB_FILEINFO_STREAM: + /* setup a single data stream */ + info->stream.out.num_streams = 1; + info->stream.out.streams = talloc(req->mem_ctx, sizeof(info->stream.out.streams[0])); + if (!info->stream.out.streams) { + return NT_STATUS_NO_MEMORY; + } + info->stream.out.streams[0].size = st->st_size; + info->stream.out.streams[0].alloc_size = st->st_size; + info->stream.out.streams[0].stream_name = talloc_strdup(req->mem_ctx,"::$DATA"); + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; +} + +/* + return info on a pathname +*/ +static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo *info) +{ + char *unix_path; + struct stat st; + + unix_path = svfs_unix_path(req, info->basic.in.fname); + + if (stat(unix_path, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + return map_fileinfo(req, info, &st); +} + +/* + query info on a open file +*/ +static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) +{ + struct stat st; + + if (fstat(info->generic.in.fnum, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + return map_fileinfo(req, info, &st); +} + + +/* + set info on a pathname +*/ +static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + open a file +*/ +static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) +{ + char *unix_path; + struct stat st; + int fd, flags; + + if (io->generic.level != SMB_OPEN_GENERIC) { + return ntvfs_map_open(req, io); + } + + unix_path = svfs_unix_path(req, io->ntcreatex.in.fname); + + switch (io->generic.in.open_disposition) { + case FILE_SUPERSEDE: + flags = O_RDWR | O_CREAT | O_TRUNC; + break; + case FILE_OPEN: + flags = O_RDWR; + break; + case FILE_CREATE: + flags = O_RDWR | O_CREAT | O_EXCL; + break; + case FILE_OPEN_IF: + flags = O_RDWR | O_CREAT; + break; + case FILE_OVERWRITE: + flags = O_RDWR; + break; + case FILE_OVERWRITE_IF: + flags = O_RDWR | O_CREAT | O_TRUNC; + break; + default: + flags = O_RDWR; + break; + } + + if (io->generic.in.create_options & FILE_DIRECTORY_FILE) { + flags = O_RDONLY | O_DIRECTORY; + switch (io->generic.in.open_disposition) { + case FILE_CREATE: + if (mkdir(unix_path, 0755) == -1) { + return map_nt_error_from_unix(errno); + } + break; + case FILE_OPEN_IF: + if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { + return map_nt_error_from_unix(errno); + } + break; + } + } + + fd = open(unix_path, flags, 0644); + if (fd == -1) { + return map_nt_error_from_unix(errno); + } + + if (fstat(fd, &st) == -1) { + close(fd); + return map_nt_error_from_unix(errno); + } + + ZERO_STRUCT(io->generic.out); + + unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); + unix_to_nt_time(&io->generic.out.access_time, st.st_atime); + unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); + unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); + io->generic.out.fnum = fd; + io->generic.out.alloc_size = st.st_size; + io->generic.out.size = st.st_size; + io->generic.out.file_attr = svfs_file_attrib(&st); + io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; + + return NT_STATUS_OK; +} + +/* + create a directory +*/ +static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md) +{ + char *unix_path; + + if (md->generic.level != RAW_MKDIR_MKDIR) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path = svfs_unix_path(req, md->mkdir.in.path); + + if (mkdir(unix_path, 0777) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + remove a directory +*/ +static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) +{ + char *unix_path; + + unix_path = svfs_unix_path(req, rd->in.path); + + if (rmdir(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + rename a set of files +*/ +static NTSTATUS svfs_rename(struct request_context *req, struct smb_rename *ren) +{ + char *unix_path1, *unix_path2; + + unix_path1 = svfs_unix_path(req, ren->in.pattern1); + unix_path2 = svfs_unix_path(req, ren->in.pattern2); + + if (rename(unix_path1, unix_path2) != 0) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + copy a set of files +*/ +static NTSTATUS svfs_copy(struct request_context *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + read from a file +*/ +static NTSTATUS svfs_read(struct request_context *req, union smb_read *rd) +{ + ssize_t ret; + + if (rd->generic.level != SMB_READ_READX) { + return NT_STATUS_NOT_SUPPORTED; + } + + ret = pread(rd->readx.in.fnum, + rd->readx.out.data, + rd->readx.in.maxcnt, + rd->readx.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + rd->readx.out.nread = ret; + rd->readx.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; +} + +/* + write to a file +*/ +static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr) +{ + ssize_t ret; + + switch (wr->generic.level) { + case SMB_WRITE_WRITEX: + ret = pwrite(wr->writex.in.fnum, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; + + case SMB_WRITE_WRITE: + if (wr->write.in.count == 0) { + /* a truncate! */ + ret = ftruncate(wr->write.in.fnum, wr->write.in.offset); + } else { + ret = pwrite(wr->write.in.fnum, + wr->write.in.data, + wr->write.in.count, + wr->write.in.offset); + } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->write.out.nwritten = ret; + + return NT_STATUS_OK; + } + + return NT_STATUS_NOT_SUPPORTED; +} + +/* + seek in a file +*/ +static NTSTATUS svfs_seek(struct request_context *req, struct smb_seek *io) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + flush a file +*/ +static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) +{ + fsync(io->in.fnum); + return NT_STATUS_OK; +} + +/* + close a file +*/ +static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) +{ + if (io->generic.level != SMB_CLOSE_CLOSE) { + /* we need a mapping function */ + return NT_STATUS_INVALID_LEVEL; + } + + if (close(io->close.in.fnum) != 0) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + exit - closing files? +*/ +static NTSTATUS svfs_exit(struct request_context *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + lock a byte range +*/ +static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck) +{ + DEBUG(0,("REWRITE: not doing byte range locking!\n")); + return NT_STATUS_OK; +} + +/* + set info on a open file +*/ +static NTSTATUS svfs_setfileinfo(struct request_context *req, + union smb_setfileinfo *info) +{ + DEBUG(0,("REWRITE: svfs_setfileinfo: not doing setfileinfo level %d\n", + info->generic.level)); + switch (info->generic.level) { + case SMB_SETFILEINFO_BASIC: + info->basic.out.ea_error_offset = 0; + break; + case SMB_SETFILEINFO_END_OF_FILE: + if (ftruncate(info->eof.in.fnum, info->eof.in.size) != 0) { + return map_nt_error_from_unix(errno); + } + info->eof.out.ea_error_offset = 0; + break; + case SMB_SETFILEINFO_ALLOCATION: + info->eof.out.ea_error_offset = 0; + break; + } + return NT_STATUS_OK; +} + + +/* + return filesystem space info +*/ +static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) +{ + struct svfs_private *private = req->conn->ntvfs_private; + + if (fs->generic.level != SMB_FSINFO_GENERIC) { + return ntvfs_map_fsinfo(req, fs); + } + + if (sys_fsusage(private->connectpath, + &fs->generic.out.blocks_free, + &fs->generic.out.blocks_total) == -1) { + return map_nt_error_from_unix(errno); + } + + fs->generic.out.block_size = 512; + + return NT_STATUS_OK; +} + +/* + return filesystem attribute info +*/ +static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) +{ + struct stat st; + struct svfs_private *private = req->conn->ntvfs_private; + + if (fs->generic.level != SMB_FSATTR_GENERIC) { + return ntvfs_map_fsattr(req, fs); + } + + if (stat(private->connectpath, &st) != 0) { + return map_nt_error_from_unix(errno); + } + + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.fs_attr = + FILE_CASE_PRESERVED_NAMES | + FILE_CASE_SENSITIVE_SEARCH | + FILE_PERSISTENT_ACLS; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.serial_number = 1; + fs->generic.out.fs_type = talloc_strdup(req->mem_ctx, "NTFS"); + fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, + lp_servicename(req->conn->service)); + + return NT_STATUS_OK; +} + +/* + return print queue info +*/ +static NTSTATUS svfs_lpq(struct request_context *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +NTSTATUS svfs_search_first(struct request_context *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = req->conn->ntvfs_private; + struct search_state *search; + union smb_search_data file; + TALLOC_CTX *mem_ctx; + uint_t max_count; + + if (io->generic.level != SMB_SEARCH_T2FFIRST_BOTH) { + return NT_STATUS_NOT_SUPPORTED; + } + + mem_ctx = talloc_init("svfs_search"); + + search = talloc_zero(mem_ctx, sizeof(struct search_state)); + if (!search) { + return NT_STATUS_NO_MEMORY; + } + + max_count = io->t2ffirst.in.max_count; + + dir = svfs_list(mem_ctx, req, io->t2ffirst.in.pattern); + if (!dir) { + talloc_destroy_pool(mem_ctx); + return NT_STATUS_FOOBAR; + } + + search->mem_ctx = mem_ctx; + search->handle = private->next_search_handle; + search->dir = dir; + + if (dir->count < max_count) { + max_count = dir->count; + } + + for (i=0; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both.change_time, dir->files[i].st.st_mtime); + file.both.name = dir->files[i].name; + file.both.short_name = dir->files[i].name; + file.both.size = dir->files[i].st.st_size; + file.both.ex_attrib = svfs_file_attrib(&dir->files[i].st); + + if (!callback(search_private, &file)) { + break; + } + } + + search->current_index = i; + + io->t2ffirst.out.count = i; + io->t2ffirst.out.handle = search->handle; + io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; + + /* work out if we are going to keep the search state */ + if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + talloc_destroy(search->mem_ctx); + } else { + private->next_search_handle++; + DLIST_ADD(private->search, search); + } + + return NT_STATUS_OK; +} + +/* continue a search */ +NTSTATUS svfs_search_next(struct request_context *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = req->conn->ntvfs_private; + struct search_state *search; + union smb_search_data file; + uint_t max_count; + + if (io->generic.level != SMB_SEARCH_T2FFIRST_BOTH) { + return NT_STATUS_NOT_SUPPORTED; + } + + for (search=private->search; search; search = search->next) { + if (search->handle == io->t2fnext.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + dir = search->dir; + + /* the client might be asking for something other than just continuing + with the search */ + if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && + (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && + io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { + /* look backwards first */ + for (i=search->current_index; i > 0; i--) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + + /* then look forwards */ + for (i=search->current_index+1; i <= dir->count; i++) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + } + +found: + max_count = search->current_index + io->t2fnext.in.max_count; + + if (max_count > dir->count) { + max_count = dir->count; + } + + for (i = search->current_index; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both.change_time, dir->files[i].st.st_mtime); + file.both.name = dir->files[i].name; + file.both.short_name = dir->files[i].name; + file.both.size = dir->files[i].st.st_size; + file.both.ex_attrib = svfs_file_attrib(&dir->files[i].st); + + if (!callback(search_private, &file)) { + break; + } + } + + io->t2fnext.out.count = i - search->current_index; + io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; + + search->current_index = i; + + /* work out if we are going to keep the search state */ + if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + DLIST_REMOVE(private->search, search); + talloc_destroy(search->mem_ctx); + } + + return NT_STATUS_OK; +} + +/* close a search */ +NTSTATUS svfs_search_close(struct request_context *req, union smb_search_close *io) +{ + struct svfs_private *private = req->conn->ntvfs_private; + struct search_state *search; + + for (search=private->search; search; search = search->next) { + if (search->handle == io->findclose.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + DLIST_REMOVE(private->search, search); + talloc_destroy(search->mem_ctx); + + return NT_STATUS_OK; +} + + +/* + initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem + */ +BOOL posix_vfs_init(void) +{ + BOOL ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = svfs_connect; + ops.disconnect = svfs_disconnect; + ops.unlink = svfs_unlink; + ops.chkpath = svfs_chkpath; + ops.qpathinfo = svfs_qpathinfo; + ops.setpathinfo = svfs_setpathinfo; + ops.open = svfs_open; + ops.mkdir = svfs_mkdir; + ops.rmdir = svfs_rmdir; + ops.rename = svfs_rename; + ops.copy = svfs_copy; + ops.ioctl = svfs_ioctl; + ops.read = svfs_read; + ops.write = svfs_write; + ops.seek = svfs_seek; + ops.flush = svfs_flush; + ops.close = svfs_close; + ops.exit = svfs_exit; + ops.lock = svfs_lock; + ops.setfileinfo = svfs_setfileinfo; + ops.qfileinfo = svfs_qfileinfo; + ops.fsinfo = svfs_fsinfo; + ops.fsattr = svfs_fsattr; + ops.lpq = svfs_lpq; + ops.search_first = svfs_search_first; + ops.search_next = svfs_search_next; + ops.search_close = svfs_search_close; + + /* register ourselves with the NTVFS subsystem. We register under the name 'default' + as we wish to be the default backend */ + ret = ntvfs_register("simple", NTVFS_DISK, &ops); + + if (!ret) { + DEBUG(0,("Failed to register POSIX backend!\n")); + return False; + } + + return True; +} diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h new file mode 100644 index 0000000000..e74fd07fce --- /dev/null +++ b/source4/ntvfs/simple/svfs.h @@ -0,0 +1,28 @@ + +struct svfs_private { + /* the base directory */ + char *connectpath; + + /* a linked list of open searches */ + struct search_state *search; + + /* next available search handle */ + uint16 next_search_handle; +}; + +struct svfs_dir { + uint_t count; + char *unix_dir; + struct { + char *name; + struct stat st; + } *files; +}; + +struct search_state { + struct search_state *next, *prev; + TALLOC_CTX *mem_ctx; + uint16 handle; + uint_t current_index; + struct svfs_dir *dir; +}; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c new file mode 100644 index 0000000000..a8a88cfad0 --- /dev/null +++ b/source4/ntvfs/simple/svfs_util.c @@ -0,0 +1,162 @@ +/* + Unix SMB/CIFS implementation. + + simple NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + utility functions for simple backend +*/ + +#include "includes.h" +#include "svfs.h" + +/* + convert a windows path to a unix path - don't do any manging or case sensitive handling +*/ +char *svfs_unix_path(struct request_context *req, const char *name) +{ + struct svfs_private *private = req->conn->ntvfs_private; + char *ret; + + if (*name != '\\') { + ret = talloc_asprintf(req->mem_ctx, "%s/%s", private->connectpath, name); + } else { + ret = talloc_asprintf(req->mem_ctx, "%s%s", private->connectpath, name); + } + all_string_sub(ret, "\\", "/", 0); + + strlower(ret); + + return ret; +} + + +/* + read a directory and find all matching file names and stat info + returned names are separate unix and DOS names. The returned names + are relative to the directory +*/ +struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, const char *pattern) +{ + char *unix_path; + char *p, *mask; + struct svfs_dir *dir; + DIR *odir; + struct dirent *dent; + uint_t allocated = 0; + char *low_mask; + + unix_path = svfs_unix_path(req, pattern); + if (!unix_path) { return NULL; } + + dir = talloc(mem_ctx, sizeof(struct svfs_dir)); + if (!dir) { return NULL; } + + dir->count = 0; + dir->files = 0; + + /* find the base directory */ + p = strrchr(unix_path, '/'); + if (!p) { return NULL; } + + dir->unix_dir = talloc_strndup(mem_ctx, unix_path, PTR_DIFF(p, unix_path)); + if (!dir->unix_dir) { return NULL; } + + /* the wildcard pattern is the last part */ + mask = p+1; + + low_mask = talloc_strdup(mem_ctx, mask); + if (!low_mask) { return NULL; } + strlower(low_mask); + + odir = opendir(dir->unix_dir); + if (!odir) { return NULL; } + + while ((dent = readdir(odir))) { + uint_t i = dir->count; + char *full_name; + char *low_name; + + low_name = talloc_strdup(mem_ctx, dent->d_name); + if (!low_name) { continue; } + strlower(low_name); + + /* check it matches the wildcard pattern */ + if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) { + continue; + } + + if (dir->count >= allocated) { + allocated = (allocated + 100) * 1.2; + dir->files = talloc_realloc(mem_ctx, dir->files, allocated * sizeof(dir->files[0])); + if (!dir->files) { + closedir(odir); + return NULL; + } + } + + dir->files[i].name = low_name; + if (!dir->files[i].name) { continue; } + + asprintf(&full_name, "%s/%s", dir->unix_dir, dir->files[i].name); + if (!full_name) { continue; } + + if (stat(full_name, &dir->files[i].st) == 0) { + dir->count++; + } + + free(full_name); + } + + closedir(odir); + + return dir; +} + + +/******************************************************************* +set the time on a file via file descriptor +*******************************************************************/ +int svfs_file_utime(int fd, struct utimbuf *times) +{ + char *fd_path = NULL; + int ret; + + asprintf(&fd_path, "/proc/self/%d", fd); + if (!fd_path) { + errno = ENOMEM; + return -1; + } + + ret = utime(fd_path, times); + free(fd_path); + return ret; +} + + +/* + map a unix file attrib to a DOS attribute +*/ +uint16 svfs_unix_to_dos_attrib(mode_t mode) +{ + uint16 ret = 0; + if (S_ISDIR(mode)) ret |= FILE_ATTRIBUTE_DIRECTORY; + if (!(mode & S_IWUSR)) ret |= FILE_ATTRIBUTE_READONLY; + return ret; +} diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c new file mode 100644 index 0000000000..caf7732ac7 --- /dev/null +++ b/source4/ntvfs/simple/vfs_simple.c @@ -0,0 +1,848 @@ +/* + Unix SMB/CIFS implementation. + + simple NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements a very simple NTVFS filesystem backend. + + this backend largely ignores the POSIX -> CIFS mappings, just doing absolutely + minimal work to give a working backend. +*/ + +#include "includes.h" +#include "svfs.h" + +/* + connect to a share - used when a tree_connect operation comes + in. For a disk based backend we needs to ensure that the base + directory exists (tho it doesn't need to be accessible by the user, + that comes later) +*/ +static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) +{ + struct stat st; + struct tcon_context *conn = req->conn; + struct svfs_private *private; + + conn->ntvfs_private = talloc(conn->mem_ctx, sizeof(struct svfs_private)); + + private = conn->ntvfs_private; + + private->next_search_handle = 0; + private->connectpath = talloc_strdup(conn->mem_ctx, lp_pathname(conn->service)); + + /* the directory must exist */ + if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { + DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", + private->connectpath, sharename)); + return NT_STATUS_BAD_NETWORK_NAME; + } + + conn->fs_type = talloc_strdup(conn->mem_ctx, "NTFS"); + conn->dev_type = talloc_strdup(conn->mem_ctx, "A:"); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS svfs_disconnect(struct tcon_context *req) +{ + return NT_STATUS_OK; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) +{ + char *unix_path; + + unix_path = svfs_unix_path(req, unl->in.pattern); + + /* ignoring wildcards ... */ + if (unlink(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + + +/* + ioctl interface - we don't do any +*/ +static NTSTATUS svfs_ioctl(struct request_context *req, struct smb_ioctl *io) +{ + return NT_STATUS_INVALID_PARAMETER; +} + +/* + check if a directory exists +*/ +static NTSTATUS svfs_chkpath(struct request_context *req, struct smb_chkpath *cp) +{ + char *unix_path; + struct stat st; + + unix_path = svfs_unix_path(req, cp->in.path); + + if (stat(unix_path, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + if (!S_ISDIR(st.st_mode)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + return NT_STATUS_OK; +} + +/* + approximately map a struct stat to a generic fileinfo struct +*/ +static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinfo *info, struct stat *st) +{ + unix_to_nt_time(&info->generic.out.create_time, st->st_ctime); + unix_to_nt_time(&info->generic.out.access_time, st->st_atime); + unix_to_nt_time(&info->generic.out.write_time, st->st_mtime); + unix_to_nt_time(&info->generic.out.change_time, st->st_mtime); + info->generic.out.alloc_size = st->st_size; + info->generic.out.size = st->st_size; + info->generic.out.attrib = svfs_unix_to_dos_attrib(st->st_mode); + info->generic.out.alloc_size = st->st_blksize * st->st_blocks; + info->generic.out.nlink = st->st_nlink; + info->generic.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; + info->generic.out.device = st->st_dev; + info->generic.out.inode = st->st_ino; + /* REWRITE: TODO stuff in here */ + info->generic.out.delete_pending = 0; + info->generic.out.ea_size = 0; + info->generic.out.num_eas = 0; + info->generic.out.fname.s = talloc_strdup(req->mem_ctx, "TODO - STORE FILENAME"); + info->generic.out.alt_fname.s = talloc_strdup(req->mem_ctx, "TODO - STORE ALT_FN"); + info->generic.out.ex_attrib = 0; + info->generic.out.compressed_size = 0; + info->generic.out.format = 0; + info->generic.out.unit_shift = 0; + info->generic.out.chunk_shift = 0; + info->generic.out.cluster_shift = 0; + + info->generic.out.access_flags = 0; + info->generic.out.position = 0; + info->generic.out.mode = 0; + info->generic.out.alignment_requirement = 0; + info->generic.out.reparse_tag = 0; + info->generic.out.num_streams = 0; + /* setup a single data stream */ + info->generic.out.num_streams = 1; + info->generic.out.streams = talloc(req->mem_ctx, sizeof(info->stream_info.out.streams[0])); + if (!info->generic.out.streams) { + return NT_STATUS_NO_MEMORY; + } + info->generic.out.streams[0].size = st->st_size; + info->generic.out.streams[0].alloc_size = st->st_size; + info->generic.out.streams[0].stream_name.s = talloc_strdup(req->mem_ctx,"::$DATA"); + /* REWRITE: end */ + + return NT_STATUS_OK; +} + +/* + return info on a pathname +*/ +static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo *info) +{ + char *unix_path; + struct stat st; + + DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level)); + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qpathinfo(req, info); + } + + unix_path = svfs_unix_path(req, info->generic.in.fname); + DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); + if (stat(unix_path, &st) == -1) { + DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); + if (errno == 0) + errno = ENOENT; + return map_nt_error_from_unix(errno); + } + DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); + return svfs_map_fileinfo(req, info, &st); +} + +/* + query info on a open file +*/ +static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) +{ + struct stat st; + + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qfileinfo(req, info); + } + + if (fstat(info->generic.in.fnum, &st) == -1) { + if (errno == 0) + errno = ENOENT; + return map_nt_error_from_unix(errno); + } + + return svfs_map_fileinfo(req, info, &st); +} + + +/* + open a file +*/ +static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) +{ + char *unix_path; + struct stat st; + int fd, flags; + + if (io->generic.level != RAW_OPEN_GENERIC) { + return ntvfs_map_open(req, io); + } + + unix_path = svfs_unix_path(req, io->ntcreatex.in.fname); + + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_SUPERSEDE: + flags = O_RDWR | O_CREAT | O_TRUNC; + break; + case NTCREATEX_DISP_OPEN: + flags = O_RDWR; + break; + case NTCREATEX_DISP_CREATE: + flags = O_RDWR | O_CREAT | O_EXCL; + break; + case NTCREATEX_DISP_OPEN_IF: + flags = O_RDWR | O_CREAT; + break; + case NTCREATEX_DISP_OVERWRITE: + flags = O_RDWR; + break; + case NTCREATEX_DISP_OVERWRITE_IF: + flags = O_RDWR | O_CREAT | O_TRUNC; + break; + default: + flags = O_RDWR; + break; + } + + if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { + flags = O_RDONLY | O_DIRECTORY; + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_CREATE: + if (mkdir(unix_path, 0755) == -1) { + DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + break; + case NTCREATEX_DISP_OPEN_IF: + if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { + DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + break; + } + } + DEBUG(9,("svfs_open: file %s flags=0x%x\n", unix_path, flags)); + fd = open(unix_path, flags, 0644); + DEBUG(9,("svfs_open: fd=%d errno=%d\n", fd, errno)); + if (fd == -1) { + if (errno == 0) + errno = ENOENT; + return map_nt_error_from_unix(errno); + } + + if (fstat(fd, &st) == -1) { + DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); + if (errno == 0) + errno = ENOENT; + close(fd); + return map_nt_error_from_unix(errno); + } + + ZERO_STRUCT(io->generic.out); + + unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); + unix_to_nt_time(&io->generic.out.access_time, st.st_atime); + unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); + unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); + io->generic.out.fnum = fd; + io->generic.out.alloc_size = st.st_size; + io->generic.out.size = st.st_size; + io->generic.out.attrib = svfs_unix_to_dos_attrib(st.st_mode); + io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; + + return NT_STATUS_OK; +} + +/* + create a directory +*/ +static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md) +{ + char *unix_path; + + if (md->generic.level != RAW_MKDIR_MKDIR) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path = svfs_unix_path(req, md->mkdir.in.path); + + if (mkdir(unix_path, 0777) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + remove a directory +*/ +static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) +{ + char *unix_path; + + unix_path = svfs_unix_path(req, rd->in.path); + + if (rmdir(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + rename a set of files +*/ +static NTSTATUS svfs_rename(struct request_context *req, struct smb_rename *ren) +{ + char *unix_path1, *unix_path2; + + unix_path1 = svfs_unix_path(req, ren->in.pattern1); + unix_path2 = svfs_unix_path(req, ren->in.pattern2); + + if (rename(unix_path1, unix_path2) != 0) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + copy a set of files +*/ +static NTSTATUS svfs_copy(struct request_context *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + read from a file +*/ +static NTSTATUS svfs_read(struct request_context *req, union smb_read *rd) +{ + ssize_t ret; + + if (rd->generic.level != RAW_READ_READX) { + return NT_STATUS_NOT_SUPPORTED; + } + + ret = pread(rd->readx.in.fnum, + rd->readx.out.data, + rd->readx.in.maxcnt, + rd->readx.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + rd->readx.out.nread = ret; + rd->readx.out.remaining = 0; /* should fill this in? */ + rd->readx.out.compaction_mode = 0; + + return NT_STATUS_OK; +} + +/* + write to a file +*/ +static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr) +{ + ssize_t ret; + + switch (wr->generic.level) { + case RAW_WRITE_WRITEX: + ret = pwrite(wr->writex.in.fnum, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; + + case RAW_WRITE_WRITE: + if (wr->write.in.count == 0) { + /* a truncate! */ + ret = ftruncate(wr->write.in.fnum, wr->write.in.offset); + } else { + ret = pwrite(wr->write.in.fnum, + wr->write.in.data, + wr->write.in.count, + wr->write.in.offset); + } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->write.out.nwritten = ret; + + return NT_STATUS_OK; + } + + return NT_STATUS_NOT_SUPPORTED; +} + +/* + seek in a file +*/ +static NTSTATUS svfs_seek(struct request_context *req, struct smb_seek *io) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + flush a file +*/ +static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) +{ + fsync(io->in.fnum); + return NT_STATUS_OK; +} + +/* + close a file +*/ +static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) +{ + if (io->generic.level != RAW_CLOSE_CLOSE) { + /* we need a mapping function */ + return NT_STATUS_INVALID_LEVEL; + } + + if (close(io->close.in.fnum) != 0) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + exit - closing files? +*/ +static NTSTATUS svfs_exit(struct request_context *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + lock a byte range +*/ +static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck) +{ + DEBUG(0,("REWRITE: not doing byte range locking!\n")); + return NT_STATUS_OK; +} + +/* + set info on a pathname +*/ +static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + set info on a open file +*/ +static NTSTATUS svfs_setfileinfo(struct request_context *req, + union smb_setfileinfo *info) +{ + struct utimbuf unix_times; + int fd; + + switch (info->generic.level) { + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + if (ftruncate(info->end_of_file_info.file.fnum, + info->end_of_file_info.in.size) != 0) { + return map_nt_error_from_unix(errno); + } + break; + case RAW_SFILEINFO_SETATTRE: + unix_times.actime = info->setattre.in.access_time; + unix_times.modtime = info->setattre.in.write_time; + fd = info->setattre.file.fnum; + + if (unix_times.actime == 0 && unix_times.modtime == 0) { + break; + } + + /* set modify time = to access time if modify time was 0 */ + if (unix_times.actime != 0 && unix_times.modtime == 0) { + unix_times.modtime = unix_times.actime; + } + + /* Set the date on this file */ + if (svfs_file_utime(fd, &unix_times) != 0) { + return NT_STATUS_ACCESS_DENIED; + } + break; + } + return NT_STATUS_OK; +} + + +/* + return filesystem space info +*/ +static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) +{ + struct svfs_private *private = req->conn->ntvfs_private; + struct stat st; + + if (fs->generic.level != RAW_QFS_GENERIC) { + return ntvfs_map_fsinfo(req, fs); + } + + if (sys_fsusage(private->connectpath, + &fs->generic.out.blocks_free, + &fs->generic.out.blocks_total) == -1) { + return map_nt_error_from_unix(errno); + } + + fs->generic.out.block_size = 512; + + if (stat(private->connectpath, &st) != 0) { + return NT_STATUS_DISK_CORRUPT_ERROR; + } + + fs->generic.out.fs_id = st.st_ino; + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.serial_number = st.st_ino; + fs->generic.out.fs_attr = 0; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.device_type = 0; + fs->generic.out.device_characteristics = 0; + fs->generic.out.quota_soft = 0; + fs->generic.out.quota_hard = 0; + fs->generic.out.quota_flags = 0; + fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, lp_servicename(req->conn->service)); + fs->generic.out.fs_type = req->conn->fs_type; + + return NT_STATUS_OK; +} + +#if 0 +/* + return filesystem attribute info +*/ +static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) +{ + struct stat st; + struct svfs_private *private = req->conn->ntvfs_private; + + if (fs->generic.level != RAW_FSATTR_GENERIC) { + return ntvfs_map_fsattr(req, fs); + } + + if (stat(private->connectpath, &st) != 0) { + return map_nt_error_from_unix(errno); + } + + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.fs_attr = + FILE_CASE_PRESERVED_NAMES | + FILE_CASE_SENSITIVE_SEARCH | + FILE_PERSISTENT_ACLS; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.serial_number = 1; + fs->generic.out.fs_type = talloc_strdup(req->mem_ctx, "NTFS"); + fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, + lp_servicename(req->conn->service)); + + return NT_STATUS_OK; +} +#endif + +/* + return print queue info +*/ +static NTSTATUS svfs_lpq(struct request_context *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS svfs_search_first(struct request_context *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = req->conn->ntvfs_private; + struct search_state *search; + union smb_search_data file; + TALLOC_CTX *mem_ctx; + uint_t max_count; + + if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { + return NT_STATUS_NOT_SUPPORTED; + } + + mem_ctx = talloc_init("svfs_search"); + + search = talloc_zero(mem_ctx, sizeof(struct search_state)); + if (!search) { + return NT_STATUS_NO_MEMORY; + } + + max_count = io->t2ffirst.in.max_count; + + dir = svfs_list(mem_ctx, req, io->t2ffirst.in.pattern); + if (!dir) { + talloc_destroy_pool(mem_ctx); + return NT_STATUS_FOOBAR; + } + + search->mem_ctx = mem_ctx; + search->handle = private->next_search_handle; + search->dir = dir; + + if (dir->count < max_count) { + max_count = dir->count; + } + + for (i=0; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); + file.both_directory_info.name.s = dir->files[i].name; + file.both_directory_info.short_name.s = dir->files[i].name; + file.both_directory_info.size = dir->files[i].st.st_size; + file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + + if (!callback(search_private, &file)) { + break; + } + } + + search->current_index = i; + + io->t2ffirst.out.count = i; + io->t2ffirst.out.handle = search->handle; + io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; + + /* work out if we are going to keep the search state */ + if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + talloc_destroy(search->mem_ctx); + } else { + private->next_search_handle++; + DLIST_ADD(private->search, search); + } + + return NT_STATUS_OK; +} + +/* continue a search */ +static NTSTATUS svfs_search_next(struct request_context *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = req->conn->ntvfs_private; + struct search_state *search; + union smb_search_data file; + uint_t max_count; + + if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { + return NT_STATUS_NOT_SUPPORTED; + } + + for (search=private->search; search; search = search->next) { + if (search->handle == io->t2fnext.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + dir = search->dir; + + /* the client might be asking for something other than just continuing + with the search */ + if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && + (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && + io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { + /* look backwards first */ + for (i=search->current_index; i > 0; i--) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + + /* then look forwards */ + for (i=search->current_index+1; i <= dir->count; i++) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + } + +found: + max_count = search->current_index + io->t2fnext.in.max_count; + + if (max_count > dir->count) { + max_count = dir->count; + } + + for (i = search->current_index; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); + file.both_directory_info.name.s = dir->files[i].name; + file.both_directory_info.short_name.s = dir->files[i].name; + file.both_directory_info.size = dir->files[i].st.st_size; + file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + + if (!callback(search_private, &file)) { + break; + } + } + + io->t2fnext.out.count = i - search->current_index; + io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; + + search->current_index = i; + + /* work out if we are going to keep the search state */ + if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + DLIST_REMOVE(private->search, search); + talloc_destroy(search->mem_ctx); + } + + return NT_STATUS_OK; +} + +/* close a search */ +static NTSTATUS svfs_search_close(struct request_context *req, union smb_search_close *io) +{ + struct svfs_private *private = req->conn->ntvfs_private; + struct search_state *search; + + for (search=private->search; search; search = search->next) { + if (search->handle == io->findclose.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + DLIST_REMOVE(private->search, search); + talloc_destroy(search->mem_ctx); + + return NT_STATUS_OK; +} + + +/* + initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem + */ +BOOL posix_vfs_init(void) +{ + BOOL ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = svfs_connect; + ops.disconnect = svfs_disconnect; + ops.unlink = svfs_unlink; + ops.chkpath = svfs_chkpath; + ops.qpathinfo = svfs_qpathinfo; + ops.setpathinfo = svfs_setpathinfo; + ops.open = svfs_open; + ops.mkdir = svfs_mkdir; + ops.rmdir = svfs_rmdir; + ops.rename = svfs_rename; + ops.copy = svfs_copy; + ops.ioctl = svfs_ioctl; + ops.read = svfs_read; + ops.write = svfs_write; + ops.seek = svfs_seek; + ops.flush = svfs_flush; + ops.close = svfs_close; + ops.exit = svfs_exit; + ops.lock = svfs_lock; + ops.setfileinfo = svfs_setfileinfo; + ops.qfileinfo = svfs_qfileinfo; + ops.fsinfo = svfs_fsinfo; + ops.lpq = svfs_lpq; + ops.search_first = svfs_search_first; + ops.search_next = svfs_search_next; + ops.search_close = svfs_search_close; + + /* register ourselves with the NTVFS subsystem. We register under the name 'default' + as we wish to be the default backend */ + ret = ntvfs_register("simple", NTVFS_DISK, &ops); + + if (!ret) { + DEBUG(0,("Failed to register POSIX backend!\n")); + return False; + } + + return True; +} -- cgit From 75c0125fb71b0562e7bdd85c391764796b5f12f6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Aug 2003 16:04:21 +0000 Subject: - added SMBntrename test suite - allow username of form DOMAIN\username or DOMAIN/username - added ntrename to gentest (This used to be commit 2b464472c17b791eb5b117f89d5aaea2bf60f6ad) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/reference/vfs_ref.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 10 +++++++--- 4 files changed, 10 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9a17336519..1afdb66a1c 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -424,7 +424,7 @@ static NTSTATUS cvfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS cvfs_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS cvfs_rename(struct request_context *req, union smb_rename *ren) { struct cvfs_private *private = req->conn->ntvfs_private; struct cli_request *c_req; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index fe310d104e..b13c358dd5 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -114,7 +114,7 @@ static NTSTATUS ipc_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS ipc_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS ipc_rename(struct request_context *req, union smb_rename *ren) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/reference/vfs_ref.c b/source4/ntvfs/reference/vfs_ref.c index b4fa2e61ff..13b4eb5fbc 100644 --- a/source4/ntvfs/reference/vfs_ref.c +++ b/source4/ntvfs/reference/vfs_ref.c @@ -378,7 +378,7 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS svfs_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) { char *unix_path1, *unix_path2; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index caf7732ac7..52e772af74 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -340,12 +340,16 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS svfs_rename(struct request_context *req, struct smb_rename *ren) +static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) { char *unix_path1, *unix_path2; - unix_path1 = svfs_unix_path(req, ren->in.pattern1); - unix_path2 = svfs_unix_path(req, ren->in.pattern2); + if (ren->generic.level != RAW_RENAME_RENAME) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path1 = svfs_unix_path(req, ren->rename.in.pattern1); + unix_path2 = svfs_unix_path(req, ren->rename.in.pattern2); if (rename(unix_path1, unix_path2) != 0) { return map_nt_error_from_unix(errno); -- cgit From e2c1250076060faca37b5b3d76902d6c24c2f3fd Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 17:14:20 +0000 Subject: fix IRIX build (This used to be commit 85c504a837960bf74dc05391a4d0bb924f2f9a3a) --- source4/ntvfs/simple/vfs_simple.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 52e772af74..11763c93b5 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -29,6 +29,10 @@ #include "includes.h" #include "svfs.h" +#ifndef O_DIRECTORY +#define O_DIRECTORY 0 +#endif + /* connect to a share - used when a tree_connect operation comes in. For a disk based backend we needs to ensure that the base -- cgit From 0becf4d68329ca599f3e34ee97ca3f72d0e9425f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Sep 2003 04:37:33 +0000 Subject: thanks to ntfsd and some google searches I worked out what the unknown fields in level 261 and level 262 of directory search are, plus the names of the levels the unknown fields are a 64bit unique file id, and match the 64 bit number from the internal_information qfileinfo level (This used to be commit b69f54eb028a24144a2e813f059b08644118ab09) --- source4/ntvfs/ntvfs_generic.c | 3 +-- source4/ntvfs/simple/svfs_util.c | 11 +++++++++++ source4/ntvfs/simple/vfs_simple.c | 3 +-- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index def448a671..08c8b88d30 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -453,8 +453,7 @@ NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *inf return NT_STATUS_OK; case RAW_FILEINFO_INTERNAL_INFORMATION: - info->internal_information.out.device = info2->generic.out.device; - info->internal_information.out.inode = info2->generic.out.inode; + info->internal_information.out.file_id = info2->generic.out.file_id; return NT_STATUS_OK; case RAW_FILEINFO_EA_INFO: diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index a8a88cfad0..baa6f86d94 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -160,3 +160,14 @@ uint16 svfs_unix_to_dos_attrib(mode_t mode) if (!(mode & S_IWUSR)) ret |= FILE_ATTRIBUTE_READONLY; return ret; } + +/* + build a file_id from a stat struct +*/ +large_t svfs_file_id(struct stat *st) +{ + large_t ret = st->st_ino; + ret <<= 32; + ret |= st->st_dev; + return ret; +} diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 11763c93b5..c08b36fb39 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -136,8 +136,7 @@ static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinf info->generic.out.alloc_size = st->st_blksize * st->st_blocks; info->generic.out.nlink = st->st_nlink; info->generic.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; - info->generic.out.device = st->st_dev; - info->generic.out.inode = st->st_ino; + info->generic.out.file_id = svfs_file_id(st); /* REWRITE: TODO stuff in here */ info->generic.out.delete_pending = 0; info->generic.out.ea_size = 0; -- cgit From a846e592058726b670e40505493a4668bd856186 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Nov 2003 03:15:26 +0000 Subject: CVS: ---------------------------------------------------------------------- CVS: Enter Log. Lines beginning with `CVS:' are removed automatically CVS: CVS: Committing in . CVS: CVS: Modified Files: CVS: Makefile.in configure.in include/includes.h include/ntvfs.h CVS: include/smb.h lib/iconv.c lib/module.c ntvfs/ntvfs_base.c CVS: ntvfs/cifs/vfs_cifs.c ntvfs/ipc/vfs_ipc.c CVS: ntvfs/posix/vfs_posix.c ntvfs/print/vfs_print.c CVS: ntvfs/reference/vfs_ref.c ntvfs/simple/vfs_simple.c CVS: passdb/pdb_interface.c CVS: Added Files: CVS: include/module.h CVS: ---------------------------------------------------------------------- Update to the modules system. Fixed: - get rid of smb_probe_module - merge older updates from 3.0 - introduced register_subsystem() and register_backend() functions - adapt ntvfs and charset to use new register functions - made smb_load_modules() work recursively (e.g. 'preload modules = /usr/lib/samba') - got rid of some old remains Things that still need work: - Did I break tankFS? I don't think so, but I can't test it here :-( - Add 'postload modules = ' (for modules that need to be loaded after fork() in smbd, if applicable) - Convert RPC, auth, passdb, etc to use new register_{subsystem,backend}() functions - Accept wildcards in 'preload modules' option, instead of loading recursively (This used to be commit 7512b9ab1a8b3103f7a6c13f736353c46a26b668) --- source4/ntvfs/cifs/vfs_cifs.c | 14 ++++++++------ source4/ntvfs/ipc/vfs_ipc.c | 14 ++++++++------ source4/ntvfs/ntvfs_base.c | 36 +++++++++++++----------------------- source4/ntvfs/posix/vfs_posix.c | 16 +++++++++------- source4/ntvfs/print/vfs_print.c | 14 ++++++++------ source4/ntvfs/simple/vfs_simple.c | 14 ++++++++------ 6 files changed, 54 insertions(+), 54 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 1afdb66a1c..3903203505 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -672,12 +672,15 @@ static NTSTATUS cvfs_trans2(struct request_context *req, struct smb_trans2 *tran /* initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem */ -BOOL cifs_vfs_init(void) +NTSTATUS ntvfs_cifs_init(void) { - BOOL ret; + NTSTATUS ret; struct ntvfs_ops ops; ZERO_STRUCT(ops); + + ops.name = "cifs"; + ops.type = NTVFS_DISK; /* fill in all the operations */ ops.connect = cvfs_connect; @@ -712,12 +715,11 @@ BOOL cifs_vfs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ - ret = ntvfs_register("cifs", NTVFS_DISK, &ops); + ret = register_backend("ntvfs", &ops); - if (!ret) { + if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register CIFS backend!\n")); - return False; } - return True; + return ret; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b13c358dd5..da5c42507a 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -248,14 +248,16 @@ NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *i /* initialialise the IPC backend, registering ourselves with the ntvfs subsystem */ -BOOL ipc_vfs_init(void) +NTSTATUS ntvfs_ipc_init(void) { - BOOL ret; + NTSTATUS ret; struct ntvfs_ops ops; ZERO_STRUCT(ops); /* fill in all the operations */ + ops.name = "ipc"; + ops.type = NTVFS_IPC; ops.connect = ipc_connect; ops.disconnect = ipc_disconnect; ops.unlink = ipc_unlink; @@ -284,12 +286,12 @@ BOOL ipc_vfs_init(void) ops.search_close = ipc_search_close; /* register ourselves with the NTVFS subsystem. */ - ret = ntvfs_register("ipc", NTVFS_IPC, &ops); + ret = register_backend("ntvfs", &ops); - if (!ret) { + if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register IPC backend!\n")); - return False; + return ret; } - return True; + return ret; } diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 57cdb97e9f..11f39c5d59 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -28,8 +28,6 @@ * can be more than one backend with the same name, as long as they * have different typesx */ static struct { - const char *name; - enum ntvfs_type type; struct ntvfs_ops *ops; } *backends = NULL; static int num_backends; @@ -42,13 +40,15 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -BOOL ntvfs_register(const char *name, enum ntvfs_type type, struct ntvfs_ops *ops) +static NTSTATUS ntvfs_register(void *_ops) { - if (ntvfs_backend_byname(name, type) != NULL) { + struct ntvfs_ops *ops = _ops; + + if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { /* its already registered! */ DEBUG(2,("NTVFS backend '%s' for type %d already registered\n", - name, (int)type)); - return False; + ops->name, (int)ops->type)); + return NT_STATUS_OBJECT_NAME_COLLISION; } backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); @@ -56,13 +56,12 @@ BOOL ntvfs_register(const char *name, enum ntvfs_type type, struct ntvfs_ops *op smb_panic("out of memory in ntvfs_register"); } - backends[num_backends].name = smb_xstrdup(name); - backends[num_backends].type = type; backends[num_backends].ops = smb_xmemdup(ops, sizeof(*ops)); + backends[num_backends].ops->name = smb_xstrdup(ops->name); num_backends++; - return True; + return NT_STATUS_OK; } @@ -74,8 +73,8 @@ struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) int i; for (i=0;itype == type && + strcmp(backends[i].ops->name, name) == 0) { return backends[i].ops; } } @@ -105,19 +104,10 @@ int ntvfs_interface_version(struct ntvfs_critical_sizes *sizes) */ BOOL ntvfs_init(void) { - /* initialise our 3 basic backends. These are assumed to be - * present and are always built in */ - if (!posix_vfs_init() || - !ipc_vfs_init() || - !print_vfs_init()) { - return False; - } - /* initialize optional backends, e.g. CIFS. We allow failures here. */ - cifs_vfs_init(); + register_subsystem("ntvfs", ntvfs_register); -#if WITH_NTVFS_STFS - tank_vfs_init(); -#endif + /* FIXME: Perhaps panic if a basic backend, such as IPC, fails to initialise? */ + static_init_ntvfs; DEBUG(3,("NTVFS version %d initialised\n", NTVFS_INTERFACE_VERSION)); return True; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index b27e7493a0..9a35f19322 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -23,7 +23,7 @@ This is the default backend */ -#include "includes.h" +#include "include/includes.h" /* connect to a share - used when a tree_connect operation comes @@ -126,12 +126,15 @@ static NTSTATUS pvfs_unlink(struct ntvfs_context *ctx, const char *name, uint16 /* initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem */ -BOOL posix_vfs_init(void) +NTSTATUS ntvfs_posix_init(void) { - BOOL ret; + NTSTATUS ret; struct ntvfs_ops ops; ZERO_STRUCT(ops); + + ops.name = "default"; + ops.type = NTVFS_DISK; /* fill in all the operations */ ops.connect = pvfs_connect; @@ -140,12 +143,11 @@ BOOL posix_vfs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ - ret = ntvfs_register("default", NTVFS_DISK, &ops); + ret = register_backend("ntvfs", &ops); - if (!ret) { + if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend!\n")); - return False; } - return True; + return ret; } diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 2563f0ad9c..82829d759a 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -78,13 +78,16 @@ static NTSTATUS print_ioctl(struct request_context *req, struct smb_ioctl *io) /* initialialise the print backend, registering ourselves with the ntvfs subsystem */ -BOOL print_vfs_init(void) +NTSTATUS ntvfs_print_init(void) { - BOOL ret; + NTSTATUS ret; struct ntvfs_ops ops; ZERO_STRUCT(ops); + ops.name = "default"; + ops.type = NTVFS_PRINT; + /* fill in all the operations */ ops.connect = print_connect; ops.disconnect = print_disconnect; @@ -93,12 +96,11 @@ BOOL print_vfs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ - ret = ntvfs_register("default", NTVFS_PRINT, &ops); + ret = register_backend("ntvfs", &ops); - if (!ret) { + if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register PRINT backend!\n")); - return False; } - return True; + return ret; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index c08b36fb39..f7ba41522c 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -807,13 +807,16 @@ static NTSTATUS svfs_search_close(struct request_context *req, union smb_search_ /* initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem */ -BOOL posix_vfs_init(void) +NTSTATUS ntvfs_simple_init(void) { - BOOL ret; + NTSTATUS ret; struct ntvfs_ops ops; ZERO_STRUCT(ops); + ops.name = "simple"; + ops.type = NTVFS_DISK; + /* fill in all the operations */ ops.connect = svfs_connect; ops.disconnect = svfs_disconnect; @@ -844,12 +847,11 @@ BOOL posix_vfs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ - ret = ntvfs_register("simple", NTVFS_DISK, &ops); + ret = register_backend("ntvfs", &ops); - if (!ret) { + if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend!\n")); - return False; } - return True; + return ret; } -- cgit From c290906b3f238ba0246624525046b6cdda214d27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 2003 09:16:53 +0000 Subject: make sure we can expand the critical versions structure without causing crashes in old modules. Thanks to metze for pointing this out! (This used to be commit 2ee5540629e7922cd76d87ed53b70bf37b83e100) --- source4/ntvfs/ntvfs_base.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 11f39c5d59..ad1b3ae671 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -88,14 +88,17 @@ struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) This can be used by backends to either detect compilation errors, or provide multiple implementations for different smbd compilation options in one module */ -int ntvfs_interface_version(struct ntvfs_critical_sizes *sizes) +const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { - sizes->sizeof_ntvfs_ops = sizeof(struct ntvfs_ops); - sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T); - sizes->sizeof_tcon_context = sizeof(struct tcon_context); - sizes->sizeof_request_context = sizeof(struct request_context); - - return NTVFS_INTERFACE_VERSION; + static const struct ntvfs_critical_sizes critical_sizes = { + NTVFS_INTERFACE_VERSION, + sizeof(struct ntvfs_ops), + sizeof(SMB_OFF_T), + sizeof(struct tcon_context), + sizeof(struct request_context), + }; + + return &critical_sizes; } -- cgit From 47702c85524afceba520cc3c2d2bc0d9a4e02e40 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 2 Dec 2003 11:10:56 +0000 Subject: Initial step at cleaning and splitting up configure.in. (This used to be commit 369a9c1ac1ff94a1d3f51eac20a39577f9cf2155) --- source4/ntvfs/config.m4 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 source4/ntvfs/config.m4 (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 new file mode 100644 index 0000000000..22ab6dadfa --- /dev/null +++ b/source4/ntvfs/config.m4 @@ -0,0 +1,18 @@ +default_static_modules="$default_static_modules ntvfs_ipc ntvfs_simple ntvfs_print ntvfs_cifs" + +SMB_MODULE(ntvfs_cifs, \$(NTVFS_CIFS_OBJ), "bin/cifs.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_simple, \$(NTVFS_SIMPLE_OBJ), "bin/ntvfs_simple.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_print, \$(NTVFS_PRINT_OBJ), "bin/ntvfs_print.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_ipc, \$(NTVFS_IPC_OBJ), "bin/ntvfs_ipc.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_posix, \$(NTVFS_POSIX_OBJ), "bin/ntvfs_posix.$SHLIBEXT$", NTVFS) + +# Tank FS +SMB_MODULE(ntvfs_csm, \$(NTVFS_CSM_OBJ), "bin/ntvfs_csm.$SHLIBEXT$", NTVFS) +STFS_ENABLED="#" +if test "$MODULE_ntvfs_csm"; then + SMBD_EXTRA_LIBS="$SMBD_EXTRA_LIBS \$\(STFS_LIBS\)" + STFS_ENABLED= +fi +AC_SUBST(STFS_ENABLED) + +SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o) -- cgit From 926240428c0646aabb13539745940b61a7cf44a9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Dec 2003 02:03:06 +0000 Subject: * patch based on work by Jim Myers to unify the ioctl handling to be more like the other major SMB functions * added SMBntrename code (This used to be commit f2d3dc9893fa0e089c407fa16ce9ff13587e70cd) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/print/vfs_print.c | 14 +++++++++----- source4/ntvfs/simple/vfs_simple.c | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 3903203505..c61749e2ad 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -247,7 +247,7 @@ static void async_ioctl(struct cli_request *c_req) /* ioctl interface */ -static NTSTATUS cvfs_ioctl(struct request_context *req, struct smb_ioctl *io) +static NTSTATUS cvfs_ioctl(struct request_context *req, union smb_ioctl *io) { struct cvfs_private *private = req->conn->ntvfs_private; struct cli_request *c_req; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index da5c42507a..7ada031bd5 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -58,7 +58,7 @@ static NTSTATUS ipc_unlink(struct request_context *req, struct smb_unlink *unl) /* ioctl interface - we don't do any */ -static NTSTATUS ipc_ioctl(struct request_context *req, struct smb_ioctl *io) +static NTSTATUS ipc_ioctl(struct request_context *req, union smb_ioctl *io) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 82829d759a..a9484d4329 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -54,17 +54,21 @@ static NTSTATUS print_unlink(struct request_context *req, struct smb_unlink *unl /* ioctl - used for job query */ -static NTSTATUS print_ioctl(struct request_context *req, struct smb_ioctl *io) +static NTSTATUS print_ioctl(struct request_context *req, union smb_ioctl *io) { char *p; - if (io->in.request == IOCTL_QUERY_JOB_INFO) { + if (io->generic.level != RAW_IOCTL_IOCTL) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + if (io->ioctl.in.request == IOCTL_QUERY_JOB_INFO) { /* a request for the print job id of an open print job */ - io->out.blob = data_blob_talloc(req->mem_ctx, NULL, 32); + io->ioctl.out.blob = data_blob_talloc(req->mem_ctx, NULL, 32); - memset(io->out.blob.data, 0, io->out.blob.length); + data_blob_clear(&io->ioctl.out.blob); - p = io->out.blob.data; + p = io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); push_string(NULL, p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); push_string(NULL, p+18, lp_servicename(req->conn->service), 13, STR_TERMINATE|STR_ASCII); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index f7ba41522c..261ce4a19a 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -95,7 +95,7 @@ static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) /* ioctl interface - we don't do any */ -static NTSTATUS svfs_ioctl(struct request_context *req, struct smb_ioctl *io) +static NTSTATUS svfs_ioctl(struct request_context *req, union smb_ioctl *io) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From 42c6a2548a658a198f128cdce36b9fcf869c33c8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Dec 2003 11:01:58 +0000 Subject: merged more updates from Jim Myers (This used to be commit 03bf30659640d684073f92d64da6e911edb65a73) --- source4/ntvfs/ntvfs_generic.c | 115 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 103 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 08c8b88d30..ea62f8c9a6 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -178,7 +178,8 @@ NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) break; case OPEN_FLAGS_OPEN_RDWR: case 0xf: /* FCB mode */ - io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS; + io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | + GENERIC_RIGHTS_FILE_WRITE; io->open.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ break; default: @@ -369,12 +370,13 @@ NTSTATUS ntvfs_map_fsinfo(struct request_context *req, union smb_fsinfo *fs) */ NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *info, union smb_fileinfo *info2) { + int i; /* and convert it to the required level using results in info2 */ switch (info->generic.level) { case RAW_FILEINFO_GENERIC: return NT_STATUS_INVALID_LEVEL; case RAW_FILEINFO_GETATTR: - info->getattr.out.attrib = info2->generic.out.attrib & 0x3f; + info->getattr.out.attrib = info2->generic.out.attrib & 0xff; info->getattr.out.size = info2->generic.out.size; info->getattr.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); return NT_STATUS_OK; @@ -468,29 +470,118 @@ NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *inf case RAW_FILEINFO_STREAM_INFO: case RAW_FILEINFO_STREAM_INFORMATION: - /* setup a single data stream */ info->stream_info.out.num_streams = info2->generic.out.num_streams; - info->stream_info.out.streams = talloc(req->mem_ctx, sizeof(info2->stream_info.out.streams[0])); - if (!info->stream_info.out.streams) { - return NT_STATUS_NO_MEMORY; + if (info->stream_info.out.num_streams > 0) { + info->stream_info.out.streams = talloc(req->mem_ctx, + info->stream_info.out.num_streams * sizeof(struct stream_struct)); + if (!info->stream_info.out.streams) { + DEBUG(2,("ntvfs_map_fileinfo: no memory for %d streams\n", + info->stream_info.out.num_streams)); + return NT_STATUS_NO_MEMORY; + } + for (i=0; i < info->stream_info.out.num_streams; i++) { + info->stream_info.out.streams[i] = info2->generic.out.streams[i]; + info->stream_info.out.streams[i].stream_name.s = + talloc_strdup(req->mem_ctx, info2->generic.out.streams[i].stream_name.s); + if (!info->stream_info.out.streams[i].stream_name.s) { + DEBUG(2,("ntvfs_map_fileinfo: no memory for stream_name\n")); + return NT_STATUS_NO_MEMORY; + } + } } - info->stream_info.out.streams[0].size = info2->generic.out.streams[0].size; - info->stream_info.out.streams[0].alloc_size = info2->generic.out.streams[0].alloc_size; - info->stream_info.out.streams[0].stream_name.s = info2->generic.out.streams[0].stream_name.s; - info->stream_info.out.streams[0].stream_name.private_length = info->generic.out.streams[0].stream_name.private_length; return NT_STATUS_OK; case RAW_FILEINFO_NAME_INFO: case RAW_FILEINFO_NAME_INFORMATION: - info->name_info.out.fname.s = info2->generic.out.fname.s; + info->name_info.out.fname.s = talloc_strdup(req->mem_ctx, info2->generic.out.fname.s); info->name_info.out.fname.private_length = info2->generic.out.fname.private_length; return NT_STATUS_OK; case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: - info->alt_name_info.out.fname.s = info2->generic.out.alt_fname.s; + info->alt_name_info.out.fname.s = talloc_strdup(req->mem_ctx, info2->generic.out.alt_fname.s); info->alt_name_info.out.fname.private_length = info2->generic.out.alt_fname.private_length; return NT_STATUS_OK; + + case RAW_FILEINFO_POSITION_INFORMATION: + info->position_information.out.position = info2->generic.out.position; + return NT_STATUS_OK; + + case RAW_FILEINFO_ALL_EAS: + info->all_eas.out.num_eas = info2->generic.out.num_eas; + if (info->all_eas.out.num_eas > 0) { + info->all_eas.out.eas = talloc(req->mem_ctx, + info->all_eas.out.num_eas * sizeof(struct ea_struct)); + if (!info->all_eas.out.eas) { + DEBUG(2,("ntvfs_map_fileinfo: no memory for %d eas\n", + info->all_eas.out.num_eas)); + return NT_STATUS_NO_MEMORY; + } + for (i = 0; i < info->all_eas.out.num_eas; i++) { + info->all_eas.out.eas[i] = info2->generic.out.eas[i]; + info->all_eas.out.eas[i].name.s = + talloc_strdup(req->mem_ctx, info2->generic.out.eas[i].name.s); + if (!info->all_eas.out.eas[i].name.s) { + DEBUG(2,("ntvfs_map_fileinfo: no memory for stream_name\n")); + return NT_STATUS_NO_MEMORY; + } + info->all_eas.out.eas[i].value.data = + talloc_memdup(req->mem_ctx, + info2->generic.out.eas[i].value.data, + info2->generic.out.eas[i].value.length); + if (!info->all_eas.out.eas[i].value.data) { + DEBUG(2,("ntvfs_map_fileinfo: no memory for stream_name\n")); + return NT_STATUS_NO_MEMORY; + } + } + } + return NT_STATUS_OK; + + case RAW_FILEINFO_IS_NAME_VALID: + return NT_STATUS_OK; + + case RAW_FILEINFO_COMPRESSION_INFO: + case RAW_FILEINFO_COMPRESSION_INFORMATION: + info->compression_info.out.compressed_size = info2->generic.out.compressed_size; + info->compression_info.out.format = info2->generic.out.format; + info->compression_info.out.unit_shift = info2->generic.out.unit_shift; + info->compression_info.out.chunk_shift = info2->generic.out.chunk_shift; + info->compression_info.out.cluster_shift = info2->generic.out.cluster_shift; + return NT_STATUS_OK; + + case RAW_FILEINFO_ACCESS_INFORMATION: + info->access_information.out.access_flags = info2->generic.out.access_flags; + return NT_STATUS_OK; + + case RAW_FILEINFO_MODE_INFORMATION: + info->mode_information.out.mode = info2->generic.out.mode; + return NT_STATUS_OK; + + case RAW_FILEINFO_ALIGNMENT_INFORMATION: + info->alignment_information.out.alignment_requirement = + info2->generic.out.alignment_requirement; + return NT_STATUS_OK; +#if 0 + case RAW_FILEINFO_UNIX_BASIC: + info->unix_basic_info.out.end_of_file = info2->generic.out.end_of_file; + info->unix_basic_info.out.num_bytes = info2->generic.out.size; + info->unix_basic_info.out.status_change_time = info2->generic.out.change_time; + info->unix_basic_info.out.access_time = info2->generic.out.access_time; + info->unix_basic_info.out.change_time = info2->generic.out.change_time; + info->unix_basic_info.out.uid = info2->generic.out.uid; + info->unix_basic_info.out.gid = info2->generic.out.gid; + info->unix_basic_info.out.file_type = info2->generic.out.file_type; + info->unix_basic_info.out.dev_major = info2->generic.out.device; + info->unix_basic_info.out.dev_minor = info2->generic.out.device; + info->unix_basic_info.out.unique_id = info2->generic.out.inode; + info->unix_basic_info.out.permissions = info2->generic.out.permissions; + info->unix_basic_info.out.nlink = info2->generic.out.nlink; + return NT_STATUS_OK; + + case RAW_FILEINFO_UNIX_LINK: + info->unix_link_info.out.link_dest = info2->generic.out.link_dest; + return NT_STATUS_OK; +#endif } return NT_STATUS_INVALID_LEVEL; -- cgit From 2bde98c0ee67b4c60c5906b3b2f297cf4922c67c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Dec 2003 22:24:33 +0000 Subject: the rest of the initial rpc server side infrastructure (This used to be commit 5fb01b0ec0321724c25669151ea7c20e6ec182d0) --- source4/ntvfs/ipc/vfs_ipc.c | 182 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 179 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7ada031bd5..7ad02bb8cb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -25,16 +25,102 @@ #include "includes.h" +/* this is the private structure used to keep the state of an open + ipc$ connection. It needs to keep information about all open + pipes */ +struct ipc_private { + + uint16 next_fnum; + uint16 num_open; + + /* a list of open pipes */ + struct pipe_state { + struct pipe_state *next, *prev; + TALLOC_CTX *mem_ctx; + const char *pipe_name; + uint16 fnum; + struct dcesrv_state *pipe_state; + } *pipe_list; + +}; + + +/* + find the next fnum available on this connection +*/ +static uint16 find_next_fnum(struct ipc_private *ipc) +{ + struct pipe_state *p; + uint32 ret; + + if (ipc->num_open == 0xFFFF) { + return 0; + } + +again: + ret = ipc->next_fnum++; + + for (p=ipc->pipe_list; p; p=p->next) { + if (p->fnum == ret) { + goto again; + } + } + + return ret; +} + + +/* + shutdown a single pipe. Called on a close or disconnect +*/ +static void pipe_shutdown(struct ipc_private *private, struct pipe_state *p) +{ + TALLOC_CTX *mem_ctx = private->pipe_list->mem_ctx; + dcesrv_endpoint_disconnect(private->pipe_list->pipe_state); + DLIST_REMOVE(private->pipe_list, private->pipe_list); + talloc_destroy(mem_ctx); +} + + +/* + find a open pipe give a file descriptor +*/ +static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16 fnum) +{ + struct pipe_state *p; + + for (p=private->pipe_list; p; p=p->next) { + if (p->fnum == fnum) { + return p; + } + } + + return NULL; +} + + /* connect to a share - always works */ static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) { struct tcon_context *conn = req->conn; + struct ipc_private *private; conn->fs_type = talloc_strdup(conn->mem_ctx, "IPC"); conn->dev_type = talloc_strdup(conn->mem_ctx, "IPC"); + /* prepare the private state for this connection */ + private = talloc(conn->mem_ctx, sizeof(struct ipc_private)); + if (!private) { + return NT_STATUS_NO_MEMORY; + } + conn->ntvfs_private = (void *)private; + + private->pipe_list = NULL; + private->next_fnum = 1; + private->num_open = 0; + return NT_STATUS_OK; } @@ -43,6 +129,13 @@ static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) */ static NTSTATUS ipc_disconnect(struct tcon_context *tcon) { + struct ipc_private *private = tcon->ntvfs_private; + + /* close any pipes that are open. Discard any unread data */ + while (private->pipe_list) { + pipe_shutdown(private, private->pipe_list); + } + return NT_STATUS_OK; } @@ -88,11 +181,79 @@ static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfilein } /* - open a file + open a file - used for MSRPC pipes */ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) { - return NT_STATUS_ACCESS_DENIED; + struct pipe_state *p; + TALLOC_CTX *mem_ctx; + NTSTATUS status; + struct dcesrv_endpoint endpoint; + struct ipc_private *private = req->conn->ntvfs_private; + + /* for now only handle NTcreateX style opens */ + if (oi->generic.level != RAW_OPEN_NTCREATEX) { + return NT_STATUS_ACCESS_DENIED; + } + + mem_ctx = talloc_init("ipc_open '%s'", oi->ntcreatex.in.fname); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + p = talloc(mem_ctx, sizeof(struct pipe_state)); + if (!p) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + p->mem_ctx = mem_ctx; + + p->pipe_name = talloc_strdup(mem_ctx, oi->ntcreatex.in.fname); + if (!p->pipe_name) { + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + p->fnum = find_next_fnum(private); + if (p->fnum == 0) { + talloc_destroy(mem_ctx); + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + + if (strncasecmp(p->pipe_name, "\\pipe\\", 6) != 0) { + talloc_destroy(mem_ctx); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + p->pipe_name += 6; + + /* + we're all set, now ask the dcerpc server subsystem to open the + endpoint. At this stage the pipe isn't bound, so we don't + know what interface the user actually wants, just that they want + one of the interfaces attached to this pipe endpoint. + + TODO: note that we aren't passing any credentials here. We + will need to do that once the credentials infrastructure is + finalised for Samba4 + */ + + endpoint.type = ENDPOINT_SMB; + endpoint.info.smb_pipe = p->pipe_name; + + status = dcesrv_endpoint_connect(req->smb, &endpoint, &p->pipe_state); + if (!NT_STATUS_IS_OK(status)) { + talloc_destroy(mem_ctx); + return status; + } + + private->num_open++; + + DLIST_ADD(private->pipe_list, p); + + ZERO_STRUCT(oi->ntcreatex.out); + oi->ntcreatex.out.fnum = p->fnum; + + return NT_STATUS_OK; } /* @@ -164,7 +325,22 @@ static NTSTATUS ipc_flush(struct request_context *req, struct smb_flush *io) */ static NTSTATUS ipc_close(struct request_context *req, union smb_close *io) { - return NT_STATUS_ACCESS_DENIED; + struct ipc_private *private = req->conn->ntvfs_private; + struct pipe_state *p; + + if (io->generic.level != RAW_CLOSE_CLOSE) { + return NT_STATUS_ACCESS_DENIED; + } + + p = pipe_state_find(private, io->close.in.fnum); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + + pipe_shutdown(private, p); + private->num_open--; + + return NT_STATUS_OK; } /* -- cgit From fcc4efd1ea637c810eed8444080b87d7f92c837a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Dec 2003 09:07:45 +0000 Subject: the next step in the dcerpc server code. Added the link between the IPC IO routines and the dcerpc endpoint servers. (This used to be commit 4929c53bc8dddda8a763fdfbcf81a79776d01113) --- source4/ntvfs/cifs/vfs_cifs.c | 8 +++ source4/ntvfs/ipc/vfs_ipc.c | 146 ++++++++++++++++++++++++++++++++++++-- source4/ntvfs/simple/vfs_simple.c | 7 ++ 3 files changed, 155 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c61749e2ad..ba2d6e7d24 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -669,6 +669,13 @@ static NTSTATUS cvfs_trans2(struct request_context *req, struct smb_trans2 *tran ASYNC_RECV_TAIL(trans2, async_trans2); } + +/* SMBtrans - not used on file shares */ +static NTSTATUS cvfs_trans(struct request_context *req, struct smb_trans2 *trans2) +{ + return NT_STATUS_ACCESS_DENIED; +} + /* initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem */ @@ -709,6 +716,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.search_first = cvfs_search_first; ops.search_next = cvfs_search_next; ops.search_close = cvfs_search_close; + ops.trans = cvfs_trans; /* only define this one for trans2 testing */ ops.trans2 = cvfs_trans2; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7ad02bb8cb..5ab608c46b 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -220,11 +220,9 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) return NT_STATUS_TOO_MANY_OPENED_FILES; } - if (strncasecmp(p->pipe_name, "\\pipe\\", 6) != 0) { - talloc_destroy(mem_ctx); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + while (p->pipe_name[0] == '\\') { + p->pipe_name++; } - p->pipe_name += 6; /* we're all set, now ask the dcerpc server subsystem to open the @@ -293,7 +291,51 @@ static NTSTATUS ipc_copy(struct request_context *req, struct smb_copy *cp) */ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) { - return NT_STATUS_ACCESS_DENIED; + struct ipc_private *private = req->conn->ntvfs_private; + DATA_BLOB data; + uint16 fnum; + struct pipe_state *p; + NTSTATUS status; + + switch (rd->generic.level) { + case RAW_READ_READ: + fnum = rd->read.in.fnum; + data.length = rd->read.in.count; + data.data = rd->read.out.data; + break; + case RAW_READ_READX: + fnum = rd->readx.in.fnum; + data.length = rd->readx.in.maxcnt; + data.data = rd->readx.out.data; + break; + default: + return NT_STATUS_NOT_SUPPORTED; + } + + p = pipe_state_find(private, fnum); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + + status = dcesrv_output(p->pipe_state, &data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (rd->generic.level) { + case RAW_READ_READ: + rd->read.out.nread = data.length; + break; + case RAW_READ_READX: + rd->readx.out.remaining = 0; + rd->readx.out.compaction_mode = 0; + rd->readx.out.nread = data.length; + break; + default: + return NT_STATUS_NOT_SUPPORTED; + } + + return NT_STATUS_OK; } /* @@ -301,7 +343,52 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) */ static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr) { - return NT_STATUS_ACCESS_DENIED; + struct ipc_private *private = req->conn->ntvfs_private; + DATA_BLOB data; + uint16 fnum; + struct pipe_state *p; + NTSTATUS status; + + switch (wr->generic.level) { + case RAW_WRITE_WRITE: + fnum = wr->write.in.fnum; + data.data = wr->write.in.data; + data.length = wr->write.in.count; + break; + + case RAW_WRITE_WRITEX: + fnum = wr->writex.in.fnum; + data.data = wr->writex.in.data; + data.length = wr->writex.in.count; + break; + + default: + return NT_STATUS_NOT_SUPPORTED; + } + + p = pipe_state_find(private, fnum); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + + status = dcesrv_input(p->pipe_state, &data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (wr->generic.level) { + case RAW_WRITE_WRITE: + wr->write.out.nwritten = data.length; + break; + case RAW_WRITE_WRITEX: + wr->writex.out.nwritten = data.length; + wr->writex.out.remaining = 0; + break; + default: + return NT_STATUS_NOT_SUPPORTED; + } + + return NT_STATUS_OK; } /* @@ -421,6 +508,52 @@ NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *i } +/* SMBtrans - used to provide access to SMB pipes */ +static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans) +{ + struct pipe_state *p; + struct ipc_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + if (trans->in.setup_count != 2 || + trans->in.setup[0] != TRANSACT_DCERPCCMD) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* the fnum is in setup[1] */ + p = pipe_state_find(private, trans->in.setup[1]); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + + /* pass the data to the dcerpc server. Note that we don't + expect this to fail, and things like NDR faults are not + reported at this stage. Those sorts of errors happen in the + dcesrv_output stage */ + status = dcesrv_input(p->pipe_state, &trans->in.data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* + now ask the dcerpc system for some output. This doesn't yet handle + async calls. Again, we only expect NT_STATUS_OK. If the call fails then + the error is encoded at the dcerpc level + */ + status = dcesrv_output(p->pipe_state, &trans->out.data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + trans->out.setup_count = 0; + trans->out.setup = NULL; + trans->out.params = data_blob(NULL, 0); + + return NT_STATUS_OK; +} + + + /* initialialise the IPC backend, registering ourselves with the ntvfs subsystem */ @@ -460,6 +593,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.search_first = ipc_search_first; ops.search_next = ipc_search_next; ops.search_close = ipc_search_close; + ops.trans = ipc_trans; /* register ourselves with the NTVFS subsystem. */ ret = register_backend("ntvfs", &ops); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 261ce4a19a..7972a3565a 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -803,6 +803,12 @@ static NTSTATUS svfs_search_close(struct request_context *req, union smb_search_ return NT_STATUS_OK; } +/* SMBtrans - not used on file shares */ +static NTSTATUS svfs_trans(struct request_context *req, struct smb_trans2 *trans2) +{ + return NT_STATUS_ACCESS_DENIED; +} + /* initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem @@ -844,6 +850,7 @@ NTSTATUS ntvfs_simple_init(void) ops.search_first = svfs_search_first; ops.search_next = svfs_search_next; ops.search_close = svfs_search_close; + ops.trans = svfs_trans; /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ -- cgit From 16309de71d6c8de96e869aeaab0b879185991d87 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Dec 2003 03:59:09 +0000 Subject: * the RPC-ECHO pipe now works in smbd, as long as the data sizes don't cause fragmented pdus (I'll add fragments shortly) * change data_blob_talloc() to not zero memory when the 2nd argument is NULL. The zeroing just masks bugs, and can't even allow a DOS attack * modified pidl to ensure that [ref] arguments to the out side of functions are allocated when parsing the in side. This allows rpc backends to assume that [ref] variables are all setup. Doesn't work correctly for [ref] arrays yet * changed DLIST_ADD_END() to take the type instead of a tmp variable. This means you don't need to declare a silly tmp variable in the caller (This used to be commit 46e0a358198eeb9af1907ee2a29025d3ab23b6d1) --- source4/ntvfs/ipc/vfs_ipc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 5ab608c46b..b57e72f14a 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -526,6 +526,11 @@ static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans) return NT_STATUS_INVALID_HANDLE; } + trans->out.data = data_blob_talloc(req->mem_ctx, NULL, trans->in.max_data); + if (!trans->out.data.data) { + return NT_STATUS_NO_MEMORY; + } + /* pass the data to the dcerpc server. Note that we don't expect this to fail, and things like NDR faults are not reported at this stage. Those sorts of errors happen in the -- cgit From 8faa77f177833eeee245391840d06771f46e0136 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 04:46:50 +0000 Subject: rpcdump.exe now works fine against a Samba4 server for some reason the epm_Lookup replies can't be parsed by ethereal, although w2k parses then fine as does the Samba4 NDR code. (This used to be commit 097e7ca99d947932df5674c36e628ca6b8f31d3a) --- source4/ntvfs/ipc/vfs_ipc.c | 63 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b57e72f14a..04825ec632 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -40,6 +40,7 @@ struct ipc_private { const char *pipe_name; uint16 fnum; struct dcesrv_state *pipe_state; + uint16 ipc_state; } *pipe_list; }; @@ -223,6 +224,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) while (p->pipe_name[0] == '\\') { p->pipe_name++; } + p->ipc_state = 0x5ff; /* we're all set, now ask the dcerpc server subsystem to open the @@ -250,6 +252,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) ZERO_STRUCT(oi->ntcreatex.out); oi->ntcreatex.out.fnum = p->fnum; + oi->ntcreatex.out.ipc_state = p->ipc_state; return NT_STATUS_OK; } @@ -508,17 +511,12 @@ NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *i } -/* SMBtrans - used to provide access to SMB pipes */ -static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans) +/* SMBtrans - handle a DCERPC command */ +static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *trans) { struct pipe_state *p; struct ipc_private *private = req->conn->ntvfs_private; NTSTATUS status; - - if (trans->in.setup_count != 2 || - trans->in.setup[0] != TRANSACT_DCERPCCMD) { - return NT_STATUS_INVALID_PARAMETER; - } /* the fnum is in setup[1] */ p = pipe_state_find(private, trans->in.setup[1]); @@ -558,6 +556,57 @@ static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans) } +/* SMBtrans - set named pipe state */ +static NTSTATUS ipc_set_nm_pipe_state(struct request_context *req, struct smb_trans2 *trans) +{ + struct pipe_state *p; + struct ipc_private *private = req->conn->ntvfs_private; + + /* the fnum is in setup[1] */ + p = pipe_state_find(private, trans->in.setup[1]); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + + if (trans->in.params.length != 2) { + return NT_STATUS_INVALID_PARAMETER; + } + p->ipc_state = SVAL(trans->in.params.data, 0); + + trans->out.setup_count = 0; + trans->out.setup = NULL; + trans->out.params = data_blob(NULL, 0); + trans->out.data = data_blob(NULL, 0); + + return NT_STATUS_OK; +} + + +/* SMBtrans - used to provide access to SMB pipes */ +static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans) +{ + NTSTATUS status; + + if (trans->in.setup_count != 2) { + return NT_STATUS_INVALID_PARAMETER; + } + + switch (trans->in.setup[0]) { + case TRANSACT_SETNAMEDPIPEHANDLESTATE: + status = ipc_set_nm_pipe_state(req, trans); + break; + case TRANSACT_DCERPCCMD: + status = ipc_dcerpc_cmd(req, trans); + break; + default: + status = NT_STATUS_INVALID_PARAMETER; + break; + } + + return status; +} + + /* initialialise the IPC backend, registering ourselves with the ntvfs subsystem -- cgit From d4705378ce88d1bb2f787338c531998d37d078ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Dec 2003 10:58:48 +0000 Subject: dcerpc over tcp in the samba4 server now works to some extent. It needs quite a bit more work to get it finished. The biggest missing feature is the lack of NTLMSSP which is needed for basic authentication over tcp (This used to be commit 9fb0f0369356909c99389e2cbc525be27c08793c) --- source4/ntvfs/ipc/vfs_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 04825ec632..a3b3ab19b7 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -240,7 +240,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) endpoint.type = ENDPOINT_SMB; endpoint.info.smb_pipe = p->pipe_name; - status = dcesrv_endpoint_connect(req->smb, &endpoint, &p->pipe_state); + status = dcesrv_endpoint_connect(&req->smb->dcesrv, &endpoint, &p->pipe_state); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); return status; -- cgit From 24c22aef90d8534ee2d016b37b2b302f1367d106 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Dec 2003 09:02:58 +0000 Subject: a fairly large commit! This adds support for bigendian rpc in the client. I have installed SUN pcnetlink locally and am using it to test the samba4 rpc code. This allows us to easily find places where we have stuffed up the types (such as 2 uint16 versus a uint32), as testing both big-endian and little-endian easily shows which is correct. I have now used this to fix several bugs like that in the samba4 IDL. In order to make this work I also had to redefine a GUID as a true structure, not a blob. From the pcnetlink wire it is clear that it is indeed defined as a structure (the byte order changes). This required changing lots of Samba code to use a GUID as a structure. I also had to fix the if_version code in dcerpc syntax IDs, as it turns out they are a single uint32 not two uint16s. The big-endian support is a bit ugly at the moment, and breaks the layering in some places. More work is needed, especially on the server side. (This used to be commit bb1af644a5a7b188290ce36232f255da0e5d66d2) --- source4/ntvfs/ipc/vfs_ipc.c | 86 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 76 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index a3b3ab19b7..96f28895c9 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -181,10 +181,13 @@ static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfilein return NT_STATUS_ACCESS_DENIED; } + + /* - open a file - used for MSRPC pipes + open a file backend - used for MSRPC pipes */ -static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) +static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, + struct pipe_state **ps) { struct pipe_state *p; TALLOC_CTX *mem_ctx; @@ -192,12 +195,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) struct dcesrv_endpoint endpoint; struct ipc_private *private = req->conn->ntvfs_private; - /* for now only handle NTcreateX style opens */ - if (oi->generic.level != RAW_OPEN_NTCREATEX) { - return NT_STATUS_ACCESS_DENIED; - } - - mem_ctx = talloc_init("ipc_open '%s'", oi->ntcreatex.in.fname); + mem_ctx = talloc_init("ipc_open '%s'", fname); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } @@ -209,7 +207,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) } p->mem_ctx = mem_ctx; - p->pipe_name = talloc_strdup(mem_ctx, oi->ntcreatex.in.fname); + p->pipe_name = talloc_strdup(mem_ctx, fname); if (!p->pipe_name) { talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; @@ -250,11 +248,79 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) DLIST_ADD(private->pipe_list, p); + *ps = p; + + return NT_STATUS_OK; +} + +/* + open a file with ntcreatex - used for MSRPC pipes +*/ +static NTSTATUS ipc_open_ntcreatex(struct request_context *req, union smb_open *oi) +{ + struct pipe_state *p; + NTSTATUS status; + + status = ipc_open_generic(req, oi->ntcreatex.in.fname, &p); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + ZERO_STRUCT(oi->ntcreatex.out); oi->ntcreatex.out.fnum = p->fnum; oi->ntcreatex.out.ipc_state = p->ipc_state; - return NT_STATUS_OK; + return status; +} + +/* + open a file with openx - used for MSRPC pipes +*/ +static NTSTATUS ipc_open_openx(struct request_context *req, union smb_open *oi) +{ + struct pipe_state *p; + NTSTATUS status; + const char *fname = oi->openx.in.fname; + + if (strncasecmp(fname, "PIPE\\", 5) != 0) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + fname += 4; + + status = ipc_open_generic(req, fname, &p); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ZERO_STRUCT(oi->openx.out); + oi->openx.out.fnum = p->fnum; + oi->openx.out.ftype = 2; + oi->openx.out.devstate = p->ipc_state; + + return status; +} + +/* + open a file - used for MSRPC pipes +*/ +static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) +{ + NTSTATUS status; + + switch (oi->generic.level) { + case RAW_OPEN_NTCREATEX: + status = ipc_open_ntcreatex(req, oi); + break; + case RAW_OPEN_OPENX: + status = ipc_open_openx(req, oi); + break; + default: + status = NT_STATUS_NOT_SUPPORTED; + break; + } + + return status; } /* -- cgit From 8364fd2853ff4bb608157656878e05ca7984a2b9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Jan 2004 06:48:54 +0000 Subject: remove a useless assignment metze (This used to be commit 189ef6e73d04c3c02309b51a5b73e322abb82cdb) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index ba2d6e7d24..10fd56cb44 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -199,7 +199,7 @@ static void async_simple(struct cli_request *c_req) #define ASYNC_RECV_TAIL(io, async_fn) do { \ if (!c_req) return NT_STATUS_UNSUCCESSFUL; \ { \ - struct async_info *async = c_req->async.private; \ + struct async_info *async; \ async = talloc(req->mem_ctx, sizeof(*async)); \ if (!async) return NT_STATUS_NO_MEMORY; \ async->parms = io; \ -- cgit From 7e6cf43756b7643e2f0ee7ada5076f36f3a24bb7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Jan 2004 22:55:27 +0000 Subject: This patch adds a better dcerpc server infastructure. 1.) We now register endpoint servers add startup via register_backend() and later use the smb.conf 'dcerpc endpoint servers' parameter to setup the dcesrv_context 2.) each endpoint server can register at context creation time as much interfaces as it wants (multiple interfaces on one endpoint are supported!) (NOTE: there's a difference between 'endpoint server' and 'endpoint'! for details look at rpc_server/dcesrv_server.h) 3.) one endpoint can have a security descriptor registered to it self this will be checked in the future when a client wants to connect to an smb pipe endpoint. 4.) we now have a 'remote' endpoint server, which works like the ntvfs_cifs module it takes this options in the [globals] section: dcerpc remote:interfaces = srvsvc, winreg, w32time, epmapper dcerpc remote:binding = ... dcerpc remote:user = ... dcerpc remote:password = ... 5.) we currently have tree endpoint servers: epmapper, rpcecho and remote the default for the 'dcerpc endpiont servers = epmapper, rpcecho' for testing you can also do dcerpc endpoint servers = rpcecho, remote, epmapper dcerpc remote:interfaces = srvsvc, samr, netlogon 6,) please notice the the epmapper now only returns NO_ENTRIES (but I think we'll find a solution for this too:-) 7.) also there're some other stuff left, but step by step :-) This patch also includes updates for the register_subsystem() , ntvfs_init(), and some other funtions to check for duplicate subsystem registration metze (hmmm, my first large commit...I hope it works as supposed :-) (This used to be commit 917e45dafd5be4c2cd90ff425b8d6f8403122349) --- source4/ntvfs/ipc/vfs_ipc.c | 22 ++++++++++++---------- source4/ntvfs/ntvfs_base.c | 11 +++++++++-- 2 files changed, 21 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 96f28895c9..cd300b6589 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -1,7 +1,9 @@ /* Unix SMB/CIFS implementation. default IPC$ NTVFS backend + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan (metze) Metzmacher 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -39,7 +41,7 @@ struct ipc_private { TALLOC_CTX *mem_ctx; const char *pipe_name; uint16 fnum; - struct dcesrv_state *pipe_state; + struct dcesrv_connection *dce_conn; uint16 ipc_state; } *pipe_list; @@ -77,7 +79,7 @@ again: static void pipe_shutdown(struct ipc_private *private, struct pipe_state *p) { TALLOC_CTX *mem_ctx = private->pipe_list->mem_ctx; - dcesrv_endpoint_disconnect(private->pipe_list->pipe_state); + dcesrv_endpoint_disconnect(private->pipe_list->dce_conn); DLIST_REMOVE(private->pipe_list, private->pipe_list); talloc_destroy(mem_ctx); } @@ -192,7 +194,7 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, struct pipe_state *p; TALLOC_CTX *mem_ctx; NTSTATUS status; - struct dcesrv_endpoint endpoint; + struct dcesrv_ep_description ep_description; struct ipc_private *private = req->conn->ntvfs_private; mem_ctx = talloc_init("ipc_open '%s'", fname); @@ -235,10 +237,10 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, finalised for Samba4 */ - endpoint.type = ENDPOINT_SMB; - endpoint.info.smb_pipe = p->pipe_name; + ep_description.type = ENDPOINT_SMB; + ep_description.info.smb_pipe = p->pipe_name; - status = dcesrv_endpoint_connect(&req->smb->dcesrv, &endpoint, &p->pipe_state); + status = dcesrv_endpoint_search_connect(&req->smb->dcesrv, &ep_description, &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); return status; @@ -386,7 +388,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) return NT_STATUS_INVALID_HANDLE; } - status = dcesrv_output(p->pipe_state, &data); + status = dcesrv_output(p->dce_conn, &data); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -440,7 +442,7 @@ static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr) return NT_STATUS_INVALID_HANDLE; } - status = dcesrv_input(p->pipe_state, &data); + status = dcesrv_input(p->dce_conn, &data); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -599,7 +601,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t expect this to fail, and things like NDR faults are not reported at this stage. Those sorts of errors happen in the dcesrv_output stage */ - status = dcesrv_input(p->pipe_state, &trans->in.data); + status = dcesrv_input(p->dce_conn, &trans->in.data); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -609,7 +611,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t async calls. Again, we only expect NT_STATUS_OK. If the call fails then the error is encoded at the dcerpc level */ - status = dcesrv_output(p->pipe_state, &trans->out.data); + status = dcesrv_output(p->dce_conn, &trans->out.data); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index ad1b3ae671..e4009fd1f0 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -1,7 +1,9 @@ /* Unix SMB/CIFS implementation. NTVFS base code + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan (metze) Metzmacher 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -107,12 +109,17 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) */ BOOL ntvfs_init(void) { - register_subsystem("ntvfs", ntvfs_register); + NTSTATUS status; + + status = register_subsystem("ntvfs", ntvfs_register); + if (!NT_STATUS_IS_OK(status)) { + return False; + } /* FIXME: Perhaps panic if a basic backend, such as IPC, fails to initialise? */ static_init_ntvfs; - DEBUG(3,("NTVFS version %d initialised\n", NTVFS_INTERFACE_VERSION)); + DEBUG(3,("NTVFS subsystem version %d initialised\n", NTVFS_INTERFACE_VERSION)); return True; } -- cgit From 7a4da9654e30ea96b326448c3e9111c2a5604f58 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Jan 2004 05:54:17 +0000 Subject: dcerpc server output now copes with the client blocking part way through a read. This happens to also avoid a memcpy on output for dcerpc over tcp. (This used to be commit e7c53ad1856e299d82d84b5837189ae3191c32de) --- source4/ntvfs/ipc/vfs_ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index cd300b6589..c6d5a52960 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -388,7 +388,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) return NT_STATUS_INVALID_HANDLE; } - status = dcesrv_output(p->dce_conn, &data); + status = dcesrv_output_blob(p->dce_conn, &data); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -611,7 +611,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t async calls. Again, we only expect NT_STATUS_OK. If the call fails then the error is encoded at the dcerpc level */ - status = dcesrv_output(p->dce_conn, &trans->out.data); + status = dcesrv_output_blob(p->dce_conn, &trans->out.data); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 7de61be92413ce03bab20ab332e9b16dea56fc97 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Jan 2004 15:43:18 +0000 Subject: - remove all STFS related stuff (which were already removed in revision 1.37 and readded by mistake in revision 1.39) - change the SMB_MODULE() macro a bit Now we have: dnl Specify the default build method of this module dnl SMB_MODULE_DEFAULT(name,default_build) AC_DEFUN(SMB_MODULE_DEFAULT,... dnl Mark specified module as shared dnl SMB_MODULE(name,default_build,static_files,shared_files,subsystem,whatif-static,whatif-shared,whatif-not) this let us specify the default build method inside of the included config.m4 files metze (This used to be commit 92a3eb83d4bb07a7f1f87232e26831d05ab42915) --- source4/ntvfs/config.m4 | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index 22ab6dadfa..b9d79e61de 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -1,18 +1,9 @@ -default_static_modules="$default_static_modules ntvfs_ipc ntvfs_simple ntvfs_print ntvfs_cifs" +dnl # NTVFS Server subsystem -SMB_MODULE(ntvfs_cifs, \$(NTVFS_CIFS_OBJ), "bin/cifs.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_simple, \$(NTVFS_SIMPLE_OBJ), "bin/ntvfs_simple.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_print, \$(NTVFS_PRINT_OBJ), "bin/ntvfs_print.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_ipc, \$(NTVFS_IPC_OBJ), "bin/ntvfs_ipc.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_posix, \$(NTVFS_POSIX_OBJ), "bin/ntvfs_posix.$SHLIBEXT$", NTVFS) - -# Tank FS -SMB_MODULE(ntvfs_csm, \$(NTVFS_CSM_OBJ), "bin/ntvfs_csm.$SHLIBEXT$", NTVFS) -STFS_ENABLED="#" -if test "$MODULE_ntvfs_csm"; then - SMBD_EXTRA_LIBS="$SMBD_EXTRA_LIBS \$\(STFS_LIBS\)" - STFS_ENABLED= -fi -AC_SUBST(STFS_ENABLED) +SMB_MODULE(ntvfs_cifs, STATIC, \$(NTVFS_CIFS_OBJ), "bin/cifs.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_simple, STATIC, \$(NTVFS_SIMPLE_OBJ), "bin/ntvfs_simple.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_print, STATIC, \$(NTVFS_PRINT_OBJ), "bin/ntvfs_print.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_ipc, STATIC, \$(NTVFS_IPC_OBJ), "bin/ntvfs_ipc.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_posix, NOT, \$(NTVFS_POSIX_OBJ), "bin/ntvfs_posix.$SHLIBEXT$", NTVFS) SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o) -- cgit From 9b736c3d9e459241232f2313ad6f99a352633c19 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 1 Feb 2004 12:16:26 +0000 Subject: Makefile.in cleanups: lib/util_smbd.c is not used anymore reorder the SMB_MODULE() parameters the goal is to autogenerate the make rules for shared modules: dnl SMB_MODULE(1:name,2:subsystem,3:default_build, 4:object_files,5:shared_object,6:libs 7:whatif-static,8:whatif-shared,9:whatif-not) and generate _LIBS and MODULE__LIBS with the SMB_MODULE() macro metze (This used to be commit 904ce91ed9e3b26d591278984ae32fa99bac01fd) --- source4/ntvfs/config.m4 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index b9d79e61de..c7d4f59c1f 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -1,9 +1,9 @@ dnl # NTVFS Server subsystem -SMB_MODULE(ntvfs_cifs, STATIC, \$(NTVFS_CIFS_OBJ), "bin/cifs.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_simple, STATIC, \$(NTVFS_SIMPLE_OBJ), "bin/ntvfs_simple.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_print, STATIC, \$(NTVFS_PRINT_OBJ), "bin/ntvfs_print.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_ipc, STATIC, \$(NTVFS_IPC_OBJ), "bin/ntvfs_ipc.$SHLIBEXT$", NTVFS) -SMB_MODULE(ntvfs_posix, NOT, \$(NTVFS_POSIX_OBJ), "bin/ntvfs_posix.$SHLIBEXT$", NTVFS) +SMB_MODULE(ntvfs_cifs, NTVFS, STATIC, \$(NTVFS_CIFS_OBJ), "bin/cifs.$SHLIBEXT$") +SMB_MODULE(ntvfs_simple, NTVFS, STATIC, \$(NTVFS_SIMPLE_OBJ), "bin/ntvfs_simple.$SHLIBEXT$") +SMB_MODULE(ntvfs_print, NTVFS, STATIC, \$(NTVFS_PRINT_OBJ), "bin/ntvfs_print.$SHLIBEXT$") +SMB_MODULE(ntvfs_ipc, NTVFS, STATIC, \$(NTVFS_IPC_OBJ), "bin/ntvfs_ipc.$SHLIBEXT$") +SMB_MODULE(ntvfs_posix, NTVFS, NOT, \$(NTVFS_POSIX_OBJ), "bin/ntvfs_posix.$SHLIBEXT$") SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o) -- cgit From 894e02f80c254da4edca5dbae99561d205c63fbe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 2 Feb 2004 13:28:29 +0000 Subject: some DEBUG and comment fixes metze (This used to be commit 5ac4f878687eb0fa95a2e5830a8372168a27d3b3) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + source4/ntvfs/ipc/vfs_ipc.c | 6 ++++-- source4/ntvfs/ntvfs_base.c | 8 ++++---- source4/ntvfs/print/vfs_print.c | 3 ++- source4/ntvfs/simple/vfs_simple.c | 3 ++- 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 10fd56cb44..976fa96b55 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -686,6 +686,7 @@ NTSTATUS ntvfs_cifs_init(void) ZERO_STRUCT(ops); + /* fill in the name and type */ ops.name = "cifs"; ops.type = NTVFS_DISK; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index c6d5a52960..cf1d21bf33 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -686,9 +686,11 @@ NTSTATUS ntvfs_ipc_init(void) ZERO_STRUCT(ops); - /* fill in all the operations */ - ops.name = "ipc"; + /* fill in the name and type */ + ops.name = "default"; ops.type = NTVFS_IPC; + + /* fill in all the operations */ ops.connect = ipc_connect; ops.disconnect = ipc_disconnect; ops.unlink = ipc_unlink; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index e4009fd1f0..3e1f77edce 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -48,7 +48,7 @@ static NTSTATUS ntvfs_register(void *_ops) if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { /* its already registered! */ - DEBUG(2,("NTVFS backend '%s' for type %d already registered\n", + DEBUG(0,("NTVFS backend '%s' for type %d already registered\n", ops->name, (int)ops->type)); return NT_STATUS_OBJECT_NAME_COLLISION; } @@ -63,6 +63,9 @@ static NTSTATUS ntvfs_register(void *_ops) num_backends++; + DEBUG(3,("NTVFS backend '%s' for type %d registered\n", + ops->name,ops->type)); + return NT_STATUS_OK; } @@ -130,9 +133,6 @@ BOOL ntvfs_init(void) NTSTATUS ntvfs_init_connection(struct request_context *req) { const char *handler = lp_ntvfs_handler(req->conn->service); - - if (strequal(handler, "default")) - handler = "ipc"; req->conn->ntvfs_ops = ntvfs_backend_byname(handler, req->conn->type); diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index a9484d4329..f56b906501 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -88,7 +88,8 @@ NTSTATUS ntvfs_print_init(void) struct ntvfs_ops ops; ZERO_STRUCT(ops); - + + /* fill in the name and type */ ops.name = "default"; ops.type = NTVFS_PRINT; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 7972a3565a..157bf03320 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -819,7 +819,8 @@ NTSTATUS ntvfs_simple_init(void) struct ntvfs_ops ops; ZERO_STRUCT(ops); - + + /* fill in the name and type */ ops.name = "simple"; ops.type = NTVFS_DISK; -- cgit From c61089219b82ff94f83e1fb428e8b47ad778c868 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 2 Feb 2004 13:43:03 +0000 Subject: - we now specify the object files in the subsystems config.m4 file I plan to convert all objectfile group to use SMB_SUBSYSTEM later I'll add a SMB_BINARY() and SMB_LIBRARY(), then there will be no more need to touch Makefile.in, because all make rules will be autogenerated by configure - convert the PROCESS_MODEL subsystem to this new scheme and move the pthread test to smbd/process_model.m4 - convert the CHARSET subsystem to this new scheme and move the iconv test to lib/iconv.m4 (This used to be commit 2e57ee884ebea194ee79ac20e84e385481b56aa2) --- source4/ntvfs/config.m4 | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index c7d4f59c1f..aabaa7edfc 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -1,9 +1,17 @@ dnl # NTVFS Server subsystem -SMB_MODULE(ntvfs_cifs, NTVFS, STATIC, \$(NTVFS_CIFS_OBJ), "bin/cifs.$SHLIBEXT$") -SMB_MODULE(ntvfs_simple, NTVFS, STATIC, \$(NTVFS_SIMPLE_OBJ), "bin/ntvfs_simple.$SHLIBEXT$") -SMB_MODULE(ntvfs_print, NTVFS, STATIC, \$(NTVFS_PRINT_OBJ), "bin/ntvfs_print.$SHLIBEXT$") -SMB_MODULE(ntvfs_ipc, NTVFS, STATIC, \$(NTVFS_IPC_OBJ), "bin/ntvfs_ipc.$SHLIBEXT$") -SMB_MODULE(ntvfs_posix, NTVFS, NOT, \$(NTVFS_POSIX_OBJ), "bin/ntvfs_posix.$SHLIBEXT$") +SMB_MODULE(ntvfs_cifs, NTVFS, STATIC, [ntvfs/cifs/vfs_cifs.o]) -SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o) +SMB_MODULE(ntvfs_simple, NTVFS, STATIC, + [ntvfs/simple/vfs_simple.o ntvfs/simple/svfs_util.o], + ntvfs/simple/svfs_private.h) + +SMB_MODULE(ntvfs_print, NTVFS, STATIC, [ntvfs/print/vfs_print.o]) + +SMB_MODULE(ntvfs_ipc, NTVFS, STATIC, [ntvfs/ipc/vfs_ipc.o]) + +SMB_MODULE(ntvfs_posix, NTVFS, NOT, [ntvfs/posix/vfs_posix.o]) + +SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o, + [ntvfs/ntvfs_generic.o ntvfs/ntvfs_util.o], + ntvfs_public_proto.h) -- cgit From 1c798aba40fb0e389c7a54ad3d8f7d45876f2809 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Feb 2004 11:10:56 +0000 Subject: - port AUTH and PASSDB subsystems to new SMB_SUBSYSTEM() scheme - some const fixes in ntvfs metze (This used to be commit af89a78123068767b1d134969c5651a0fd978b0d) --- source4/ntvfs/ntvfs_base.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 3e1f77edce..7ed8c738b6 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -30,7 +30,7 @@ * can be more than one backend with the same name, as long as they * have different typesx */ static struct { - struct ntvfs_ops *ops; + const struct ntvfs_ops *ops; } *backends = NULL; static int num_backends; @@ -44,7 +44,8 @@ static int num_backends; */ static NTSTATUS ntvfs_register(void *_ops) { - struct ntvfs_ops *ops = _ops; + const struct ntvfs_ops *ops = _ops; + struct ntvfs_ops *new_ops; if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { /* its already registered! */ @@ -58,8 +59,10 @@ static NTSTATUS ntvfs_register(void *_ops) smb_panic("out of memory in ntvfs_register"); } - backends[num_backends].ops = smb_xmemdup(ops, sizeof(*ops)); - backends[num_backends].ops->name = smb_xstrdup(ops->name); + new_ops = smb_xmemdup(ops, sizeof(*ops)); + new_ops->name = smb_xstrdup(ops->name); + + backends[num_backends].ops = new_ops; num_backends++; @@ -73,7 +76,7 @@ static NTSTATUS ntvfs_register(void *_ops) /* return the operations structure for a named backend of the specified type */ -struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) +const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) { int i; -- cgit From 009fa83b136fbb4544a9b79074ab17e357493c32 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Feb 2004 11:18:54 +0000 Subject: move include/ntvfs.h to ntvfs/ntvfs.h metze (This used to be commit 041dc8c83df21c4cff9a62b9381ebc68b3876e77) --- source4/ntvfs/ntvfs.h | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 source4/ntvfs/ntvfs.h (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h new file mode 100644 index 0000000000..b03ab218c6 --- /dev/null +++ b/source4/ntvfs/ntvfs.h @@ -0,0 +1,87 @@ +/* + Unix SMB/CIFS implementation. + NTVFS structures and defines + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* modules can use the following to determine if the interface has changed */ +#define NTVFS_INTERFACE_VERSION 1 + + + +/* the ntvfs operations structure - contains function pointers to + the backend implementations of each operation */ +struct ntvfs_ops { + const char *name; + enum ntvfs_type type; + + /* initial setup */ + NTSTATUS (*connect)(struct request_context *req, const char *sharename); + NTSTATUS (*disconnect)(struct tcon_context *conn); + + /* path operations */ + NTSTATUS (*unlink)(struct request_context *req, struct smb_unlink *unl); + NTSTATUS (*chkpath)(struct request_context *req, struct smb_chkpath *cp); + NTSTATUS (*qpathinfo)(struct request_context *req, union smb_fileinfo *st); + NTSTATUS (*setpathinfo)(struct request_context *req, union smb_setfileinfo *st); + NTSTATUS (*open)(struct request_context *req, union smb_open *oi); + NTSTATUS (*mkdir)(struct request_context *req, union smb_mkdir *md); + NTSTATUS (*rmdir)(struct request_context *req, struct smb_rmdir *rd); + NTSTATUS (*rename)(struct request_context *req, union smb_rename *ren); + NTSTATUS (*copy)(struct request_context *req, struct smb_copy *cp); + + /* directory search */ + NTSTATUS (*search_first)(struct request_context *req, union smb_search_first *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)); + NTSTATUS (*search_next)(struct request_context *req, union smb_search_next *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)); + NTSTATUS (*search_close)(struct request_context *req, union smb_search_close *io); + + /* operations on open files */ + NTSTATUS (*ioctl)(struct request_context *req, union smb_ioctl *io); + NTSTATUS (*read)(struct request_context *req, union smb_read *io); + NTSTATUS (*write)(struct request_context *req, union smb_write *io); + NTSTATUS (*seek)(struct request_context *req, struct smb_seek *io); + NTSTATUS (*flush)(struct request_context *req, struct smb_flush *flush); + NTSTATUS (*close)(struct request_context *req, union smb_close *io); + NTSTATUS (*exit)(struct request_context *req); + NTSTATUS (*lock)(struct request_context *req, union smb_lock *lck); + NTSTATUS (*setfileinfo)(struct request_context *req, union smb_setfileinfo *info); + NTSTATUS (*qfileinfo)(struct request_context *req, union smb_fileinfo *info); + + /* filesystem operations */ + NTSTATUS (*fsinfo)(struct request_context *req, union smb_fsinfo *fs); + + /* printing specific operations */ + NTSTATUS (*lpq)(struct request_context *req, union smb_lpq *lpq); + + /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ + NTSTATUS (*trans2)(struct request_context *req, struct smb_trans2 *trans2); + + /* trans interface - used by IPC backend for pipes and RAP calls */ + NTSTATUS (*trans)(struct request_context *req, struct smb_trans2 *trans); +}; + + +/* this structure is used by backends to determine the size of some critical types */ +struct ntvfs_critical_sizes { + int interface_version; + int sizeof_ntvfs_ops; + int sizeof_SMB_OFF_T; + int sizeof_tcon_context; + int sizeof_request_context; +}; -- cgit From f848aff0c28fcbacb4290e67b7c217b1aaa0fade Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Feb 2004 12:37:54 +0000 Subject: if vfs_cifs want to modify the ntvfs_ops struct, it should use a temporary copy of the struct! metze (This used to be commit 372522c64f2aea76b3fe136752d4da40e61d2bec) --- source4/ntvfs/cifs/vfs_cifs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 976fa96b55..878dbf2357 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -148,7 +148,12 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) /* if we are mapping trans2, then we need to not give a trans2 pointer in the operations structure */ if (private->map_calls && in_list("trans2", private->map_calls, True)) { - conn->ntvfs_ops->trans2 = NULL; + struct ntvfs_ops *ops = talloc_memdup(conn->mem_ctx,conn->ntvfs_ops,sizeof(*ops)); + if (!ops) { + return NT_STATUS_NO_MEMORY; + } + ops->trans2 = NULL; + conn->ntvfs_ops = ops; } /* we need to tell the event loop that we wish to receive read events -- cgit From ab615698ad385b3ec9c8bde9100dde9f8e5a7b20 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Mar 2004 07:13:11 +0000 Subject: in the async socket handling routines in the cifs backend don't assume that conn->ntvfs_private is set correctly, instead use our copy of the private pointer in the fde callback. This allows the cifs backend to be used on conjunction with a NTVFS filter module. (This used to be commit 8047b806e78815706bca81a77d04d5874ffd7d6e) --- source4/ntvfs/cifs/vfs_cifs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 878dbf2357..966a670677 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -73,8 +73,8 @@ static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 f */ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags) { - struct tcon_context *conn = fde->private; - struct cvfs_private *private = conn->ntvfs_private; + struct cvfs_private *private = fde->private; + struct tcon_context *conn = private->conn; DEBUG(5,("cifs_socket_handler event on fd %d\n", fde->fd)); @@ -160,7 +160,7 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) on our SMB connection to the server */ fde.fd = private->transport->socket->fd; fde.flags = EVENT_FD_READ; - fde.private = req->conn; + fde.private = private; fde.handler = cifs_socket_handler; event_add_fd(conn->smb->events, &fde); -- cgit From b53aad11d59b32d70ac189525795446f47ad8cd2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Mar 2004 07:17:15 +0000 Subject: added the "nbench" ntvfs backend. This is used to capture NBENCH load files, and also serves as an example of how to write a NTVFS filter module for Samba4. (This used to be commit 04f8996dd32d92c5df1b6b1b27c6e71e99bc77da) --- source4/ntvfs/config.m4 | 2 + source4/ntvfs/nbench/README | 14 + source4/ntvfs/nbench/vfs_nbench.c | 700 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 716 insertions(+) create mode 100644 source4/ntvfs/nbench/README create mode 100644 source4/ntvfs/nbench/vfs_nbench.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index aabaa7edfc..58d0768d7a 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -12,6 +12,8 @@ SMB_MODULE(ntvfs_ipc, NTVFS, STATIC, [ntvfs/ipc/vfs_ipc.o]) SMB_MODULE(ntvfs_posix, NTVFS, NOT, [ntvfs/posix/vfs_posix.o]) +SMB_MODULE(ntvfs_nbench, NTVFS, STATIC, [ntvfs/nbench/vfs_nbench.o]) + SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o, [ntvfs/ntvfs_generic.o ntvfs/ntvfs_util.o], ntvfs_public_proto.h) diff --git a/source4/ntvfs/nbench/README b/source4/ntvfs/nbench/README new file mode 100644 index 0000000000..9aaae9d7ee --- /dev/null +++ b/source4/ntvfs/nbench/README @@ -0,0 +1,14 @@ +This module provides a way to capture file sharing loads for the +NBENCH benchmark client. It also servers as an example of a NTVFS +filter module. + +Here is an example config that passes through to the CIFS NTVFS backend. + +[bench] + ntvfs handler = nbench + nbench:passthru = cifs + cifs:server = myserver + cifs:user = myuser + cifs:password = mypass + cifs:domain = MYDOMAIN + cifs:share = bench diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c new file mode 100644 index 0000000000..34f7b784a5 --- /dev/null +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -0,0 +1,700 @@ +/* + Unix SMB/CIFS implementation. + + a pass-thru NTVFS module to record a NBENCH load file + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + "passthru" in this module refers to the next level of NTVFS being used +*/ + +#include "includes.h" + +/* this is stored in ntvfs_private */ +struct nbench_private { + const struct ntvfs_ops *passthru_ops; + void *passthru_private; + const struct ntvfs_ops *nbench_ops; + int log_fd; +}; + + +/* + log one request to the nbench log +*/ +static void nbench_log(struct nbench_private *private, + const char *format, ...) +{ + va_list ap; + char *s = NULL; + + va_start(ap, format); + vasprintf(&s, format, ap); + va_end(ap); + + write(private->log_fd, s, strlen(s)); + free(s); +} + + +/* + when we call the next stacked level of NTVFS module we need + to give it its own private pointer, plus its own NTVFS operations structure. + Then we need to restore both of these after the call, as the next level could + modify either of these +*/ +#define PASS_THRU(conn, op, args) do { \ + conn->ntvfs_private = private->passthru_private; \ + conn->ntvfs_ops = private->passthru_ops; \ +\ + status = private->passthru_ops->op args; \ +\ + private->passthru_private = conn->ntvfs_private; \ + private->passthru_ops = conn->ntvfs_ops; \ +\ + conn->ntvfs_private = private; \ + conn->ntvfs_ops = private->nbench_ops; \ +} while (0) + +/* + this pass through macro operates on request contexts, and disables + async calls. + + async calls are a pain for the nbench module as it makes pulling the + status code and any result parameters much harder. +*/ +#define PASS_THRU_REQ(req, op, args) do { \ + void *send_fn_saved = req->async.send_fn; \ + req->async.send_fn = NULL; \ + PASS_THRU(req->conn, op, args); \ + req->async.send_fn = send_fn_saved; \ +} while (0) + + +/* + connect to a share - used when a tree_connect operation comes in. +*/ +static NTSTATUS nbench_connect(struct request_context *req, const char *sharename) +{ + struct nbench_private *private; + const char *passthru; + NTSTATUS status; + char *logname = NULL; + + private = talloc_p(req->conn->mem_ctx, struct nbench_private); + if (!private) { + return NT_STATUS_NO_MEMORY; + } + + asprintf(&logname, "/tmp/nbenchlog.%u", getpid()); + private->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); + free(logname); + + if (private->log_fd == -1) { + DEBUG(0,("Failed to open nbench log\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + passthru = lp_parm_string(req->conn->service, "nbench", "passthru"); + + private->passthru_private = NULL; + private->nbench_ops = req->conn->ntvfs_ops; + private->passthru_ops = ntvfs_backend_byname(passthru, NTVFS_DISK); + + if (!private->passthru_ops) { + DEBUG(0,("Unable to connect to '%s' pass through backend\n", passthru)); + return NT_STATUS_UNSUCCESSFUL; + } + + PASS_THRU(req->conn, connect, (req, sharename)); + + return status; +} + +/* + disconnect from a share +*/ +static NTSTATUS nbench_disconnect(struct tcon_context *conn) +{ + struct nbench_private *private = conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU(conn, disconnect, (conn)); + + close(private->log_fd); + + return status; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS nbench_unlink(struct request_context *req, struct smb_unlink *unl) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, unlink, (req, unl)); + + nbench_log(private, "Unlink \"%s\" 0x%x %s\n", + unl->in.pattern, unl->in.attrib, + get_nt_error_c_code(status)); + + return status; +} + +/* + ioctl interface +*/ +static NTSTATUS nbench_ioctl(struct request_context *req, union smb_ioctl *io) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, ioctl, (req, io)); + + nbench_log(private, "Ioctl - NOT HANDLED\n"); + + return status; +} + +/* + check if a directory exists +*/ +static NTSTATUS nbench_chkpath(struct request_context *req, struct smb_chkpath *cp) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, chkpath, (req, cp)); + + nbench_log(private, "Chkpath \"%s\" %s\n", + cp->in.path, + get_nt_error_c_code(status)); + + return status; +} + +/* + return info on a pathname +*/ +static NTSTATUS nbench_qpathinfo(struct request_context *req, union smb_fileinfo *info) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, qpathinfo, (req, info)); + + nbench_log(private, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", + info->generic.in.fname, + info->generic.level, + get_nt_error_c_code(status)); + + return status; +} + +/* + query info on a open file +*/ +static NTSTATUS nbench_qfileinfo(struct request_context *req, union smb_fileinfo *info) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, qfileinfo, (req, info)); + + nbench_log(private, "QUERY_FILE_INFORMATION %d %d %s\n", + info->generic.in.fnum, + info->generic.level, + get_nt_error_c_code(status)); + + return status; +} + + +/* + set info on a pathname +*/ +static NTSTATUS nbench_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, setpathinfo, (req, st)); + + nbench_log(private, "SET_PATH_INFORMATION \"%s\" %d %s\n", + st->generic.file.fname, + st->generic.level, + get_nt_error_c_code(status)); + + return status; +} + +/* + open a file +*/ +static NTSTATUS nbench_open(struct request_context *req, union smb_open *io) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, open, (req, io)); + + switch (io->generic.level) { + case RAW_OPEN_NTCREATEX: + nbench_log(private, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", + io->ntcreatex.in.fname, + io->ntcreatex.in.create_options, + io->ntcreatex.in.open_disposition, + io->ntcreatex.out.fnum, + get_nt_error_c_code(status)); + break; + + default: + nbench_log(private, "Open-%d - NOT HANDLED\n", + io->generic.level); + break; + } + + return status; +} + +/* + create a directory +*/ +static NTSTATUS nbench_mkdir(struct request_context *req, union smb_mkdir *md) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, mkdir, (req, md)); + + nbench_log(private, "Mkdir - NOT HANDLED\n"); + + return status; +} + +/* + remove a directory +*/ +static NTSTATUS nbench_rmdir(struct request_context *req, struct smb_rmdir *rd) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, rmdir, (req, rd)); + + nbench_log(private, "Rmdir \"%s\" %s\n", + rd->in.path, + get_nt_error_c_code(status)); + + return status; +} + +/* + rename a set of files +*/ +static NTSTATUS nbench_rename(struct request_context *req, union smb_rename *ren) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, rename, (req, ren)); + + switch (ren->generic.level) { + case RAW_RENAME_RENAME: + nbench_log(private, "Rename \"%s\" \"%s\" %s\n", + ren->rename.in.pattern1, + ren->rename.in.pattern2, + get_nt_error_c_code(status)); + break; + + default: + nbench_log(private, "Rename-%d - NOT HANDLED\n", + ren->generic.level); + break; + } + + return status; +} + +/* + copy a set of files +*/ +static NTSTATUS nbench_copy(struct request_context *req, struct smb_copy *cp) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, copy, (req, cp)); + + nbench_log(private, "Copy - NOT HANDLED\n"); + + return status; +} + +/* + read from a file +*/ +static NTSTATUS nbench_read(struct request_context *req, union smb_read *rd) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, read, (req, rd)); + + switch (rd->generic.level) { + case RAW_READ_READX: + nbench_log(private, "ReadX %d %d %d %d %s\n", + rd->readx.in.fnum, + (int)rd->readx.in.offset, + rd->readx.in.maxcnt, + rd->readx.out.nread, + get_nt_error_c_code(status)); + break; + default: + nbench_log(private, "Read-%d - NOT HANDLED\n", + rd->generic.level); + break; + } + + return status; +} + +/* + write to a file +*/ +static NTSTATUS nbench_write(struct request_context *req, union smb_write *wr) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, write, (req, wr)); + + switch (wr->generic.level) { + case RAW_WRITE_WRITEX: + nbench_log(private, "WriteX %d %d %d %d %s\n", + wr->writex.in.fnum, + (int)wr->writex.in.offset, + wr->writex.in.count, + wr->writex.out.nwritten, + get_nt_error_c_code(status)); + break; + + case RAW_WRITE_WRITE: + nbench_log(private, "Write %d %d %d %d %s\n", + wr->write.in.fnum, + wr->write.in.offset, + wr->write.in.count, + wr->write.out.nwritten, + get_nt_error_c_code(status)); + break; + + default: + nbench_log(private, "Write-%d - NOT HANDLED\n", + wr->generic.level); + break; + } + + return status; +} + +/* + seek in a file +*/ +static NTSTATUS nbench_seek(struct request_context *req, struct smb_seek *io) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, seek, (req, io)); + + nbench_log(private, "Seek - NOT HANDLED\n"); + + return status; +} + +/* + flush a file +*/ +static NTSTATUS nbench_flush(struct request_context *req, struct smb_flush *io) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, flush, (req, io)); + + nbench_log(private, "Flush %d %s\n", + io->in.fnum, + get_nt_error_c_code(status)); + + return status; +} + +/* + close a file +*/ +static NTSTATUS nbench_close(struct request_context *req, union smb_close *io) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, close, (req, io)); + + switch (io->generic.level) { + case RAW_CLOSE_CLOSE: + nbench_log(private, "Close %d %s\n", + io->close.in.fnum, + get_nt_error_c_code(status)); + break; + + default: + nbench_log(private, "Close-%d - NOT HANDLED\n", + io->generic.level); + break; + } + + return status; +} + +/* + exit - closing files +*/ +static NTSTATUS nbench_exit(struct request_context *req) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, exit, (req)); + + return status; +} + +/* + lock a byte range +*/ +static NTSTATUS nbench_lock(struct request_context *req, union smb_lock *lck) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, lock, (req, lck)); + + if (lck->generic.level == RAW_LOCK_LOCKX && + lck->lockx.in.lock_cnt == 1 && + lck->lockx.in.ulock_cnt == 0) { + nbench_log(private, "LockX %d %d %d %s\n", + lck->lockx.in.fnum, + (int)lck->lockx.in.locks[0].offset, + (int)lck->lockx.in.locks[0].count, + get_nt_error_c_code(status)); + } else if (lck->generic.level == RAW_LOCK_LOCKX && + lck->lockx.in.ulock_cnt == 1) { + nbench_log(private, "UnlockX %d %d %d %s\n", + lck->lockx.in.fnum, + (int)lck->lockx.in.locks[0].offset, + (int)lck->lockx.in.locks[0].count, + get_nt_error_c_code(status)); + } else { + nbench_log(private, "Lock-%d - NOT HANDLED\n", lck->generic.level); + } + + return status; +} + +/* + set info on a open file +*/ +static NTSTATUS nbench_setfileinfo(struct request_context *req, + union smb_setfileinfo *info) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, setfileinfo, (req, info)); + + nbench_log(private, "Setfileinfo %d %d %s\n", + info->generic.file.fnum, + info->generic.level, + get_nt_error_c_code(status)); + + return status; +} + + +/* + return filesystem space info +*/ +static NTSTATUS nbench_fsinfo(struct request_context *req, union smb_fsinfo *fs) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, fsinfo, (req, fs)); + + nbench_log(private, "Fsinfo %d %s", + fs->generic.level, + get_nt_error_c_code(status)); + + return status; +} + +/* + return print queue info +*/ +static NTSTATUS nbench_lpq(struct request_context *req, union smb_lpq *lpq) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, lpq, (req, lpq)); + + nbench_log(private, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); + + return status; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS nbench_search_first(struct request_context *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, search_first, (req, io, search_private, callback)); + + switch (io->generic.level) { + case RAW_SEARCH_BOTH_DIRECTORY_INFO: + nbench_log(private, "Search \"%s\" %d %d %d %s\n", + io->t2ffirst.in.pattern, + io->generic.level, + io->t2ffirst.in.max_count, + io->t2ffirst.out.count, + get_nt_error_c_code(status)); + break; + + default: + nbench_log(private, "Search-%d - NOT HANDLED\n", io->generic.level); + break; + } + + return status; +} + +/* continue a search */ +static NTSTATUS nbench_search_next(struct request_context *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, search_next, (req, io, search_private, callback)); + + nbench_log(private, "Searchnext-%d - NOT HANDLED\n", io->generic.level); + + return status; +} + +/* close a search */ +static NTSTATUS nbench_search_close(struct request_context *req, union smb_search_close *io) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, search_close, (req, io)); + + nbench_log(private, "Searchclose-%d - NOT HANDLED\n", io->generic.level); + + return status; +} + +/* SMBtrans - not used on file shares */ +static NTSTATUS nbench_trans(struct request_context *req, struct smb_trans2 *trans2) +{ + struct nbench_private *private = req->conn->ntvfs_private; + NTSTATUS status; + + PASS_THRU_REQ(req, trans, (req,trans2)); + + nbench_log(private, "Trans - NOT HANDLED\n"); + + return status; +} + +/* + initialise the nbench backend, registering ourselves with the ntvfs subsystem + */ +NTSTATUS ntvfs_nbench_init(void) +{ + NTSTATUS ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in the name and type */ + ops.name = "nbench"; + ops.type = NTVFS_DISK; + + /* fill in all the operations */ + ops.connect = nbench_connect; + ops.disconnect = nbench_disconnect; + ops.unlink = nbench_unlink; + ops.chkpath = nbench_chkpath; + ops.qpathinfo = nbench_qpathinfo; + ops.setpathinfo = nbench_setpathinfo; + ops.open = nbench_open; + ops.mkdir = nbench_mkdir; + ops.rmdir = nbench_rmdir; + ops.rename = nbench_rename; + ops.copy = nbench_copy; + ops.ioctl = nbench_ioctl; + ops.read = nbench_read; + ops.write = nbench_write; + ops.seek = nbench_seek; + ops.flush = nbench_flush; + ops.close = nbench_close; + ops.exit = nbench_exit; + ops.lock = nbench_lock; + ops.setfileinfo = nbench_setfileinfo; + ops.qfileinfo = nbench_qfileinfo; + ops.fsinfo = nbench_fsinfo; + ops.lpq = nbench_lpq; + ops.search_first = nbench_search_first; + ops.search_next = nbench_search_next; + ops.search_close = nbench_search_close; + ops.trans = nbench_trans; + + /* we don't register a trans2 handler as we want to be able to + log individual trans2 requests */ + ops.trans2 = NULL; + + /* register ourselves with the NTVFS subsystem. */ + ret = register_backend("ntvfs", &ops); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register nbench backend!\n")); + } + + return ret; +} -- cgit From 1f6b3f5b5be5d8351e95aafe1d5ead70db51d7ed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Mar 2004 09:13:35 +0000 Subject: fixed a typo (This used to be commit 10b137c6e3c1a640597ff4a0db10d635b51b806b) --- source4/ntvfs/nbench/vfs_nbench.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 34f7b784a5..d1add8b3f7 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -549,7 +549,7 @@ static NTSTATUS nbench_fsinfo(struct request_context *req, union smb_fsinfo *fs) PASS_THRU_REQ(req, fsinfo, (req, fs)); - nbench_log(private, "Fsinfo %d %s", + nbench_log(private, "Fsinfo %d %s\n", fs->generic.level, get_nt_error_c_code(status)); -- cgit From 1b71c60c36f0e2dc70b83688194c7aa3512623e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Mar 2004 02:01:42 +0000 Subject: fixed the label for search requests (This used to be commit 8dbf08549e17a48a5cff114671122edb035dd900) --- source4/ntvfs/nbench/vfs_nbench.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index d1add8b3f7..4ff82fabb2 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -585,7 +585,7 @@ static NTSTATUS nbench_search_first(struct request_context *req, union smb_searc switch (io->generic.level) { case RAW_SEARCH_BOTH_DIRECTORY_INFO: - nbench_log(private, "Search \"%s\" %d %d %d %s\n", + nbench_log(private, "FIND_FIRST \"%s\" %d %d %d %s\n", io->t2ffirst.in.pattern, io->generic.level, io->t2ffirst.in.max_count, -- cgit From 77f39da07598f45bdea0939bf5c28a63082a514f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Mar 2004 05:06:57 +0000 Subject: make sure the tags in the NBENCH test match the tags in the generated load files (This used to be commit 1c5dc25b3b678d7c5d271cc9bee5bf80cfbec3b9) --- source4/ntvfs/nbench/vfs_nbench.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 4ff82fabb2..acdeec455a 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -530,7 +530,7 @@ static NTSTATUS nbench_setfileinfo(struct request_context *req, PASS_THRU_REQ(req, setfileinfo, (req, info)); - nbench_log(private, "Setfileinfo %d %d %s\n", + nbench_log(private, "SET_FILE_INFORMATION %d %d %s\n", info->generic.file.fnum, info->generic.level, get_nt_error_c_code(status)); @@ -549,7 +549,7 @@ static NTSTATUS nbench_fsinfo(struct request_context *req, union smb_fsinfo *fs) PASS_THRU_REQ(req, fsinfo, (req, fs)); - nbench_log(private, "Fsinfo %d %s\n", + nbench_log(private, "QUERY_FS_INFORMATION %d %s\n", fs->generic.level, get_nt_error_c_code(status)); -- cgit From 5e31a56e725b41f9759535de0322459baa3ced5f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Mar 2004 04:07:02 +0000 Subject: add config hints for cifs backend (This used to be commit bba81f1c7a87499f610ca19fbc5f1485d368c5b8) --- source4/ntvfs/cifs/README | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/README b/source4/ntvfs/cifs/README index a43ad09bdf..c6232fe2db 100644 --- a/source4/ntvfs/cifs/README +++ b/source4/ntvfs/cifs/README @@ -3,3 +3,14 @@ backend that talks to a remote CIFS server. The primary aim of this backend is for debugging and development, although some poeple may find it useful as a CIFS gateway. + +Here is a typical config: + +[myshare] + ntvfs handler = cifs + cifs:server = myserver + cifs:user = tridge + cifs:password = mypass + cifs:domain = TESTDOM + cifs:share = test + -- cgit From 19680ba4df36400cc8834795434118960d5cafc4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Apr 2004 08:02:55 +0000 Subject: r65: added support for file streams in the simple NTVFS backend (This used to be commit 9a9cc44a05510a69ad902db4d01dc12b6ac4f8ba) --- source4/ntvfs/simple/svfs.h | 8 ++++ source4/ntvfs/simple/svfs_util.c | 26 +++++++++--- source4/ntvfs/simple/vfs_simple.c | 84 +++++++++++++++++++++++++++++++++++---- 3 files changed, 105 insertions(+), 13 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index e74fd07fce..6e44d290da 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -8,6 +8,8 @@ struct svfs_private { /* next available search handle */ uint16 next_search_handle; + + struct svfs_file *open_files; }; struct svfs_dir { @@ -19,6 +21,12 @@ struct svfs_dir { } *files; }; +struct svfs_file { + struct svfs_file *next, *prev; + int fd; + char *name; +}; + struct search_state { struct search_state *next, *prev; TALLOC_CTX *mem_ctx; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index baa6f86d94..598b85f1ad 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -52,9 +52,8 @@ char *svfs_unix_path(struct request_context *req, const char *name) returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, const char *pattern) +struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct request_context *req, const char *unix_path) { - char *unix_path; char *p, *mask; struct svfs_dir *dir; DIR *odir; @@ -62,9 +61,6 @@ struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, con uint_t allocated = 0; char *low_mask; - unix_path = svfs_unix_path(req, pattern); - if (!unix_path) { return NULL; } - dir = talloc(mem_ctx, sizeof(struct svfs_dir)); if (!dir) { return NULL; } @@ -93,6 +89,11 @@ struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, con char *full_name; char *low_name; + if (strchr(dent->d_name, ':') && !strchr(unix_path, ':')) { + /* don't show streams in dir listing */ + continue; + } + low_name = talloc_strdup(mem_ctx, dent->d_name); if (!low_name) { continue; } strlower(low_name); @@ -129,6 +130,21 @@ struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, con return dir; } +/* + read a directory and find all matching file names and stat info + returned names are separate unix and DOS names. The returned names + are relative to the directory +*/ +struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, const char *pattern) +{ + char *unix_path; + + unix_path = svfs_unix_path(req, pattern); + if (!unix_path) { return NULL; } + + return svfs_list_unix(mem_ctx, req, unix_path); +} + /******************************************************************* set the time on a file via file descriptor diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 157bf03320..6e51d8a638 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -73,6 +73,20 @@ static NTSTATUS svfs_disconnect(struct tcon_context *req) return NT_STATUS_OK; } +/* + find open file handle given fd +*/ +static struct svfs_file *find_fd(struct svfs_private *private, int fd) +{ + struct svfs_file *f; + for (f=private->open_files;f;f=f->next) { + if (f->fd == fd) { + return f; + } + } + return NULL; +} + /* delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) @@ -124,8 +138,27 @@ static NTSTATUS svfs_chkpath(struct request_context *req, struct smb_chkpath *cp /* approximately map a struct stat to a generic fileinfo struct */ -static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinfo *info, struct stat *st) +static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinfo *info, + struct stat *st, const char *unix_path) { + struct svfs_dir *dir = NULL; + char *pattern = NULL; + int i; + char *s, *short_name; + + s = strrchr(unix_path, '/'); + if (s) { + short_name = s+1; + } else { + short_name = ""; + } + + asprintf(&pattern, "%s:*", unix_path); + + if (pattern) { + dir = svfs_list_unix(req->mem_ctx, req, pattern); + } + unix_to_nt_time(&info->generic.out.create_time, st->st_ctime); unix_to_nt_time(&info->generic.out.access_time, st->st_atime); unix_to_nt_time(&info->generic.out.write_time, st->st_mtime); @@ -141,8 +174,8 @@ static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinf info->generic.out.delete_pending = 0; info->generic.out.ea_size = 0; info->generic.out.num_eas = 0; - info->generic.out.fname.s = talloc_strdup(req->mem_ctx, "TODO - STORE FILENAME"); - info->generic.out.alt_fname.s = talloc_strdup(req->mem_ctx, "TODO - STORE ALT_FN"); + info->generic.out.fname.s = talloc_strdup(req->mem_ctx, short_name); + info->generic.out.alt_fname.s = talloc_strdup(req->mem_ctx, short_name); info->generic.out.ex_attrib = 0; info->generic.out.compressed_size = 0; info->generic.out.format = 0; @@ -157,15 +190,23 @@ static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinf info->generic.out.reparse_tag = 0; info->generic.out.num_streams = 0; /* setup a single data stream */ - info->generic.out.num_streams = 1; - info->generic.out.streams = talloc(req->mem_ctx, sizeof(info->stream_info.out.streams[0])); + info->generic.out.num_streams = 1 + (dir?dir->count:0); + info->generic.out.streams = talloc_array_p(req->mem_ctx, + struct stream_struct, + info->generic.out.num_streams); if (!info->generic.out.streams) { return NT_STATUS_NO_MEMORY; } info->generic.out.streams[0].size = st->st_size; info->generic.out.streams[0].alloc_size = st->st_size; info->generic.out.streams[0].stream_name.s = talloc_strdup(req->mem_ctx,"::$DATA"); - /* REWRITE: end */ + + for (i=0;dir && icount;i++) { + s = strchr(dir->files[i].name, ':'); + info->generic.out.streams[1+i].size = dir->files[i].st.st_size; + info->generic.out.streams[1+i].alloc_size = dir->files[i].st.st_size; + info->generic.out.streams[1+i].stream_name.s = s?s:dir->files[i].name; + } return NT_STATUS_OK; } @@ -192,7 +233,7 @@ static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo * return map_nt_error_from_unix(errno); } DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); - return svfs_map_fileinfo(req, info, &st); + return svfs_map_fileinfo(req, info, &st, unix_path); } /* @@ -200,11 +241,18 @@ static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo * */ static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) { + struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_file *f; struct stat st; if (info->generic.level != RAW_FILEINFO_GENERIC) { return ntvfs_map_qfileinfo(req, info); } + + f = find_fd(private, info->generic.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } if (fstat(info->generic.in.fnum, &st) == -1) { if (errno == 0) @@ -212,7 +260,7 @@ static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo * return map_nt_error_from_unix(errno); } - return svfs_map_fileinfo(req, info, &st); + return svfs_map_fileinfo(req, info, &st, f->name); } @@ -221,9 +269,11 @@ static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo * */ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) { + struct svfs_private *private = req->conn->ntvfs_private; char *unix_path; struct stat st; int fd, flags; + struct svfs_file *f; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(req, io); @@ -289,6 +339,12 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) return map_nt_error_from_unix(errno); } + f = talloc_p(req->conn->mem_ctx, struct svfs_file); + f->fd = fd; + f->name = talloc_strdup(req->conn->mem_ctx, unix_path); + + DLIST_ADD(private->open_files, f); + ZERO_STRUCT(io->generic.out); unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); @@ -461,15 +517,27 @@ static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) */ static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) { + struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_file *f; + if (io->generic.level != RAW_CLOSE_CLOSE) { /* we need a mapping function */ return NT_STATUS_INVALID_LEVEL; } + f = find_fd(private, io->close.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + if (close(io->close.in.fnum) != 0) { return map_nt_error_from_unix(errno); } + DLIST_REMOVE(private->open_files, f); + talloc_free(req->conn->mem_ctx, f->name); + talloc_free(req->conn->mem_ctx, f); + return NT_STATUS_OK; } -- cgit From 2aee8406676a2698ae55f9fe7b29b62fdb475fa9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Apr 2004 11:17:58 +0000 Subject: r112: the simple backend now registers as both "simple" and "default" so older smb.conf settings will work (This used to be commit 6f6285ce603b55b1c68cf54621e22aa777b6c5c5) --- source4/ntvfs/simple/vfs_simple.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 6e51d8a638..18f6559510 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -889,7 +889,6 @@ NTSTATUS ntvfs_simple_init(void) ZERO_STRUCT(ops); /* fill in the name and type */ - ops.name = "simple"; ops.type = NTVFS_DISK; /* fill in all the operations */ @@ -921,12 +920,23 @@ NTSTATUS ntvfs_simple_init(void) ops.search_close = svfs_search_close; ops.trans = svfs_trans; - /* register ourselves with the NTVFS subsystem. We register under the name 'default' - as we wish to be the default backend */ + /* register ourselves with the NTVFS subsystem. We register + under two names 'simple' and 'default' + */ + ops.name = "simple"; ret = register_backend("ntvfs", &ops); if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register POSIX backend!\n")); + DEBUG(0,("Failed to register simple backend with name: %s!\n", + ops.name)); + } + + /* also register as "default" */ + ops.name = "default"; + ret = register_backend("ntvfs", &ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register simple backend with name: %s!\n", + ops.name)); } return ret; -- cgit From a8dfb92795c159dd9c8478a19ca0e0a650850bc6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Apr 2004 11:30:59 +0000 Subject: r113: added support for "read only = yes" in simple backend (This used to be commit d268e455f15ec0d2b9e9e7abd8c7135ff4c19fcd) --- source4/ntvfs/simple/vfs_simple.c | 52 +++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 13 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 18f6559510..4802c11d6a 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -33,6 +33,8 @@ #define O_DIRECTORY 0 #endif +#define CHECK_READ_ONLY(req) do { if (lp_readonly(req->conn->service)) return NT_STATUS_ACCESS_DENIED; } while (0) + /* connect to a share - used when a tree_connect operation comes in. For a disk based backend we needs to ensure that the base @@ -95,6 +97,8 @@ static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) { char *unix_path; + CHECK_READ_ONLY(req); + unix_path = svfs_unix_path(req, unl->in.pattern); /* ignoring wildcards ... */ @@ -274,39 +278,49 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) struct stat st; int fd, flags; struct svfs_file *f; + int create_flags, rdwr_flags; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(req, io); } + if (lp_readonly(req->conn->service)) { + create_flags = 0; + rdwr_flags = O_RDONLY; + } else { + create_flags = O_CREAT; + rdwr_flags = O_RDWR; + } + unix_path = svfs_unix_path(req, io->ntcreatex.in.fname); switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: - flags = O_RDWR | O_CREAT | O_TRUNC; + case NTCREATEX_DISP_OVERWRITE_IF: + flags = create_flags | O_TRUNC; break; case NTCREATEX_DISP_OPEN: - flags = O_RDWR; + case NTCREATEX_DISP_OVERWRITE: + flags = 0; break; case NTCREATEX_DISP_CREATE: - flags = O_RDWR | O_CREAT | O_EXCL; + flags = create_flags | O_EXCL; break; case NTCREATEX_DISP_OPEN_IF: - flags = O_RDWR | O_CREAT; - break; - case NTCREATEX_DISP_OVERWRITE: - flags = O_RDWR; - break; - case NTCREATEX_DISP_OVERWRITE_IF: - flags = O_RDWR | O_CREAT | O_TRUNC; + flags = create_flags; break; default: - flags = O_RDWR; + flags = 0; break; } + + flags |= rdwr_flags; if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { flags = O_RDONLY | O_DIRECTORY; + if (lp_readonly(req->conn->service)) { + goto do_open; + } switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_CREATE: if (mkdir(unix_path, 0755) == -1) { @@ -322,9 +336,9 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) break; } } - DEBUG(9,("svfs_open: file %s flags=0x%x\n", unix_path, flags)); + +do_open: fd = open(unix_path, flags, 0644); - DEBUG(9,("svfs_open: fd=%d errno=%d\n", fd, errno)); if (fd == -1) { if (errno == 0) errno = ENOENT; @@ -367,6 +381,8 @@ static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md) { char *unix_path; + CHECK_READ_ONLY(req); + if (md->generic.level != RAW_MKDIR_MKDIR) { return NT_STATUS_INVALID_LEVEL; } @@ -387,6 +403,8 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) { char *unix_path; + CHECK_READ_ONLY(req); + unix_path = svfs_unix_path(req, rd->in.path); if (rmdir(unix_path) == -1) { @@ -403,6 +421,8 @@ static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) { char *unix_path1, *unix_path2; + CHECK_READ_ONLY(req); + if (ren->generic.level != RAW_RENAME_RENAME) { return NT_STATUS_INVALID_LEVEL; } @@ -458,6 +478,8 @@ static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr) { ssize_t ret; + CHECK_READ_ONLY(req); + switch (wr->generic.level) { case RAW_WRITE_WRITEX: ret = pwrite(wr->writex.in.fnum, @@ -563,6 +585,8 @@ static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck) */ static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) { + CHECK_READ_ONLY(req); + return NT_STATUS_NOT_SUPPORTED; } @@ -574,6 +598,8 @@ static NTSTATUS svfs_setfileinfo(struct request_context *req, { struct utimbuf unix_times; int fd; + + CHECK_READ_ONLY(req); switch (info->generic.level) { case RAW_SFILEINFO_END_OF_FILE_INFO: -- cgit From 2f4bb85be50b56acacd822f08d0fde19daff2d90 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Apr 2004 11:46:00 +0000 Subject: r114: - remember to initialise open_files - use talloc_p when possible (This used to be commit db7f7ac165ded15f0b8157eb899ea6828a033da9) --- source4/ntvfs/simple/vfs_simple.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 4802c11d6a..c2ad7d7aa4 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -47,12 +47,13 @@ static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) struct tcon_context *conn = req->conn; struct svfs_private *private; - conn->ntvfs_private = talloc(conn->mem_ctx, sizeof(struct svfs_private)); + conn->ntvfs_private = talloc_p(conn->mem_ctx, struct svfs_private); private = conn->ntvfs_private; private->next_search_handle = 0; private->connectpath = talloc_strdup(conn->mem_ctx, lp_pathname(conn->service)); + private->open_files = NULL; /* the directory must exist */ if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { -- cgit From 91b30df39bfaec8bfa32be40a13fd62008f66b9e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 10 Apr 2004 18:24:45 +0000 Subject: r147: - Remove dublicate ldap tests (richard the current test is in libads/config.m4 :-) - Move sendfile check to ntvfs/config.m4 - Move comparison_fn_t check to build/m4/rewrite.m4 Please do not new tests to configure.in directly, please add them to the subsystems config.m4 file where they belong to or to build/m4/rewrite.m4 if you don't know where to put it for now Thanks I know samba4's build system is not completly rewritten. I have a lot of updatest in my local tree, but it's not complete yet when it's complete I'll write documentation for it:-) metze (This used to be commit 31c23f14d60a4aa41e0500e369f25ed6dc7ddae7) --- source4/ntvfs/config.m4 | 230 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index 58d0768d7a..a0b07ffd1b 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -1,5 +1,235 @@ dnl # NTVFS Server subsystem +################################################# +# check for sendfile support + +with_sendfile_support=yes +AC_MSG_CHECKING(whether to check to support sendfile) +AC_ARG_WITH(sendfile-support, +[ --with-sendfile-support Check for sendfile support (default=yes)], +[ case "$withval" in + yes) + + AC_MSG_RESULT(yes); + + case "$host_os" in + *linux*) + AC_CACHE_CHECK([for linux sendfile64 support],samba_cv_HAVE_SENDFILE64,[ + AC_TRY_LINK([#include ], +[\ +int tofd, fromfd; +off64_t offset; +size_t total; +ssize_t nwritten = sendfile64(tofd, fromfd, &offset, total); +], +samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)]) + + AC_CACHE_CHECK([for linux sendfile support],samba_cv_HAVE_SENDFILE,[ + AC_TRY_LINK([#include ], +[\ +int tofd, fromfd; +off_t offset; +size_t total; +ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); +], +samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) + +# Try and cope with broken Linux sendfile.... + AC_CACHE_CHECK([for broken linux sendfile support],samba_cv_HAVE_BROKEN_LINUX_SENDFILE,[ + AC_TRY_LINK([\ +#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) +#undef _FILE_OFFSET_BITS +#endif +#include ], +[\ +int tofd, fromfd; +off_t offset; +size_t total; +ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); +], +samba_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,samba_cv_HAVE_BROKEN_LINUX_SENDFILE=no)]) + + if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE64,1,[Whether 64-bit sendfile() is available]) + AC_DEFINE(LINUX_SENDFILE_API,1,[Whether linux sendfile() API is available]) + AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used]) + elif test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available]) + AC_DEFINE(LINUX_SENDFILE_API,1,[Whether linux sendfile() API is available]) + AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used]) + elif test x"$samba_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then + AC_DEFINE(LINUX_BROKEN_SENDFILE_API,1,[Whether (linux) sendfile() is broken]) + AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile should be used]) + else + AC_MSG_RESULT(no); + fi + + ;; + *freebsd*) + AC_CACHE_CHECK([for freebsd sendfile support],samba_cv_HAVE_SENDFILE,[ + AC_TRY_LINK([\ +#include +#include +#include +#include ], +[\ + int fromfd, tofd, ret, total=0; + off_t offset, nwritten; + struct sf_hdtr hdr; + struct iovec hdtrl; + hdr.headers = &hdtrl; + hdr.hdr_cnt = 1; + hdr.trailers = NULL; + hdr.trl_cnt = 0; + hdtrl.iov_base = NULL; + hdtrl.iov_len = 0; + ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0); +], +samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) + + if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() support is available]) + AC_DEFINE(FREEBSD_SENDFILE_API,1,[Whether the FreeBSD sendfile() API is available]) + AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) + else + AC_MSG_RESULT(no); + fi + ;; + + *hpux*) + AC_CACHE_CHECK([for hpux sendfile64 support],samba_cv_HAVE_SENDFILE64,[ + AC_TRY_LINK([\ +#include +#include ], +[\ + int fromfd, tofd; + size_t total=0; + struct iovec hdtrl[2]; + ssize_t nwritten; + off64_t offset; + + hdtrl[0].iov_base = 0; + hdtrl[0].iov_len = 0; + + nwritten = sendfile64(tofd, fromfd, offset, total, &hdtrl[0], 0); +], +samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)]) + if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE64,1,[Whether sendfile64() is available]) + AC_DEFINE(HPUX_SENDFILE_API,1,[Whether the hpux sendfile() API is available]) + AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) + else + AC_MSG_RESULT(no); + fi + + AC_CACHE_CHECK([for hpux sendfile support],samba_cv_HAVE_SENDFILE,[ + AC_TRY_LINK([\ +#include +#include ], +[\ + int fromfd, tofd; + size_t total=0; + struct iovec hdtrl[2]; + ssize_t nwritten; + off_t offset; + + hdtrl[0].iov_base = 0; + hdtrl[0].iov_len = 0; + + nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0); +], +samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) + if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then + AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available]) + AC_DEFINE(HPUX_SENDFILE_API,1,[Whether the hpux sendfile() API is available]) + AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) + else + AC_MSG_RESULT(no); + fi + ;; + + *solaris*) + AC_CHECK_LIB(sendfile,sendfilev) + AC_CACHE_CHECK([for solaris sendfilev64 support],samba_cv_HAVE_SENDFILEV64,[ + AC_TRY_LINK([\ +#include ], +[\ + int sfvcnt; + size_t xferred; + struct sendfilevec vec[2]; + ssize_t nwritten; + int tofd; + + sfvcnt = 2; + + vec[0].sfv_fd = SFV_FD_SELF; + vec[0].sfv_flag = 0; + vec[0].sfv_off = 0; + vec[0].sfv_len = 0; + + vec[1].sfv_fd = 0; + vec[1].sfv_flag = 0; + vec[1].sfv_off = 0; + vec[1].sfv_len = 0; + nwritten = sendfilev64(tofd, vec, sfvcnt, &xferred); +], +samba_cv_HAVE_SENDFILEV64=yes,samba_cv_HAVE_SENDFILEV64=no)]) + + if test x"$samba_cv_HAVE_SENDFILEV64" = x"yes"; then + AC_DEFINE(HAVE_SENDFILEV64,1,[Whether sendfilev64() is available]) + AC_DEFINE(SOLARIS_SENDFILE_API,1,[Whether the soloris sendfile() API is available]) + AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) + else + AC_MSG_RESULT(no); + fi + + AC_CACHE_CHECK([for solaris sendfilev support],samba_cv_HAVE_SENDFILEV,[ + AC_TRY_LINK([\ +#include ], +[\ + int sfvcnt; + size_t xferred; + struct sendfilevec vec[2]; + ssize_t nwritten; + int tofd; + + sfvcnt = 2; + + vec[0].sfv_fd = SFV_FD_SELF; + vec[0].sfv_flag = 0; + vec[0].sfv_off = 0; + vec[0].sfv_len = 0; + + vec[1].sfv_fd = 0; + vec[1].sfv_flag = 0; + vec[1].sfv_off = 0; + vec[1].sfv_len = 0; + nwritten = sendfilev(tofd, vec, sfvcnt, &xferred); +], +samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)]) + + if test x"$samba_cv_HAVE_SENDFILEV" = x"yes"; then + AC_DEFINE(HAVE_SENDFILEV,1,[Whether sendfilev() is available]) + AC_DEFINE(SOLARIS_SENDFILE_API,1,[Whether the solaris sendfile() API is available]) + AC_DEFINE(WITH_SENDFILE,1,[Whether to include sendfile() support]) + else + AC_MSG_RESULT(no); + fi + ;; + + *) + ;; + esac + ;; + *) + AC_MSG_RESULT(no) + ;; + esac ], + AC_MSG_RESULT(yes) +) +# end check for sendfile support +################################################# + SMB_MODULE(ntvfs_cifs, NTVFS, STATIC, [ntvfs/cifs/vfs_cifs.o]) SMB_MODULE(ntvfs_simple, NTVFS, STATIC, -- cgit From ac193579e7db00c7a2ea0aadaaf0d34c10dcf1a5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 10 Apr 2004 20:18:22 +0000 Subject: r152: a quick airport commit .... added ldbedit, a _really_ useful command added ldbadd, ldbdel, ldbsearch and ldbmodify to build solved lots of timezone issues, we now pass the torture tests with client and server in different zones fixed several build issues I know this breaks the no-LDAP build. Wait till I arrive in San Jose for that fix. (This used to be commit af34710d4da1841653624fe304b1c8d812c0fdd9) --- source4/ntvfs/cifs/vfs_cifs.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 966a670677..2a87d59a06 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -145,14 +145,15 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) private->map_calls = talloc_strdup(conn->mem_ctx, map_calls); } - /* if we are mapping trans2, then we need to not give a trans2 + /* if we are mapping trans2, then we need to give a trans2 pointer in the operations structure */ if (private->map_calls && in_list("trans2", private->map_calls, True)) { struct ntvfs_ops *ops = talloc_memdup(conn->mem_ctx,conn->ntvfs_ops,sizeof(*ops)); + static NTSTATUS cvfs_trans2(struct request_context *,struct smb_trans2 *); if (!ops) { return NT_STATUS_NO_MEMORY; } - ops->trans2 = NULL; + ops->trans2 = cvfs_trans2; conn->ntvfs_ops = ops; } @@ -725,10 +726,10 @@ NTSTATUS ntvfs_cifs_init(void) ops.trans = cvfs_trans; /* only define this one for trans2 testing */ - ops.trans2 = cvfs_trans2; - - /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ + ops.trans2 = NULL; + /* register ourselves with the NTVFS subsystem. We register + under the name 'cifs'. */ ret = register_backend("ntvfs", &ops); if (!NT_STATUS_IS_OK(ret)) { -- cgit From ee0588bb6fbfbb250f5f2a3373556b100f2eb399 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Apr 2004 14:19:03 +0000 Subject: r312: let ntvfs posix backend return NT_STATUS_ACCESS_DENIED in the connect hook and print out an error message to the debug log which say: use 'cifs' or 'simple' as ntvfs handler this also warns about 'root' fileaccess in the 'simple' module the 'default' ntvfs handler is now registered by the posix backend metze (This used to be commit 84b3589daa60cfdd2c868d9468192b0a6e1eebae) --- source4/ntvfs/config.m4 | 2 +- source4/ntvfs/posix/vfs_posix.c | 99 ++++++--------------------------------- source4/ntvfs/simple/vfs_simple.c | 10 +--- 3 files changed, 16 insertions(+), 95 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index a0b07ffd1b..420c3ec62a 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -240,7 +240,7 @@ SMB_MODULE(ntvfs_print, NTVFS, STATIC, [ntvfs/print/vfs_print.o]) SMB_MODULE(ntvfs_ipc, NTVFS, STATIC, [ntvfs/ipc/vfs_ipc.o]) -SMB_MODULE(ntvfs_posix, NTVFS, NOT, [ntvfs/posix/vfs_posix.o]) +SMB_MODULE(ntvfs_posix, NTVFS, STATIC, [ntvfs/posix/vfs_posix.o]) SMB_MODULE(ntvfs_nbench, NTVFS, STATIC, [ntvfs/nbench/vfs_nbench.o]) diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 9a35f19322..e013e01979 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -1,8 +1,8 @@ /* Unix SMB/CIFS implementation. POSIX NTVFS backend - Copyright (C) Andrew Tridgell 1992-2003 - Copyright (C) Andrew Bartlett 2001 + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan (metze) Metzmacher 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,98 +31,28 @@ directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS pvfs_connect(struct ntvfs_context *ctx, const char *sharename) +static NTSTATUS pvfs_connect(struct request_context *req, const char *sharename) { - struct stat st; - struct connection_struct *conn = ctx->conn; - NTSTATUS status; - - /* the directory must exist */ - if (stat(conn->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { - DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", - conn->connectpath, lp_servicename(SNUM(conn)))); - return NT_STATUS_BAD_NETWORK_NAME; - } - - /* Initialise old VFS function pointers */ - if (!smbd_vfs_init(conn)) { - DEBUG(0, ("vfs_init failed for service %s\n", lp_servicename(SNUM(conn)))); - return NT_STATUS_BAD_NETWORK_NAME; - } - - /* become the user for the rest */ - status = ntvfs_change_to_user(ctx); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* the posix backend can do preexec */ - status = ntvfs_connect_preexec(ctx); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* Invoke the old POSIX VFS make connection hook */ - if (conn->vfs_ops.connect && - conn->vfs_ops.connect(conn, lp_servicename(snum), user) < 0) { - DEBUG(0,("make_connection: POSIX VFS make connection failed!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - } - - - /* - * Print out the 'connected as' stuff here as we need - * to know the effective uid and gid we will be using - * (at least initially). - */ - if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) { - dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address ); - dbgtext( "connect to service %s ", lp_servicename(SNUM(conn)) ); - dbgtext( "initially as user %s ", user ); - dbgtext( "(uid=%d, gid=%d) ", (int)geteuid(), (int)getegid() ); - dbgtext( "(pid %d)\n", (int)sys_getpid() ); - } - - return NT_STATUS_OK; + DEBUG(0, ("Connection to share [%s] ACCESS DENIED!\n", sharename)); + DEBUGADD(0,("This is because your using the 'ntvfs handler = default'.\n")); + DEBUGADD(0,("This backend is not functional at the moment.\n")); + DEBUGADD(0,("Please use one of the following backends:\n")); + DEBUGADD(0,("cifs - a proxy to another cifs-server\n")); + DEBUGADD(0,("simple - a very, very simple posix backend\n")); + DEBUGADD(0,(" all file acess is done as user 'root'\n")); + DEBUGADD(0,(" Please don't use this a sensitive data!!!\n")); + + return NT_STATUS_ACCESS_DENIED; } /* disconnect from a share */ -static NTSTATUS pvfs_disconnect(struct ntvfs_context *ctx) +static NTSTATUS pvfs_disconnect(struct tcon_context *tcon) { return NT_STATUS_OK; } -/* - delete a file - the dirtype specifies the file types to include in the search. - The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) -*/ -static NTSTATUS pvfs_unlink(struct ntvfs_context *ctx, const char *name, uint16 dirtype) -{ - NTSTATUS status; - - if (ntvfs_dfs_redirect(ctx, name)) { - return NT_STATUS_PATH_NOT_COVERED; - } - - status = unlink_internals(ctx->conn, dirtype, name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - ntvfs_run_change_notify_queue(); - - return NT_STATUS_OK; -} - - - - - - - /* initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem */ @@ -139,7 +69,6 @@ NTSTATUS ntvfs_posix_init(void) /* fill in all the operations */ ops.connect = pvfs_connect; ops.disconnect = pvfs_disconnect; - ops.unlink = pvfs_unlink; /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index c2ad7d7aa4..e36e4a62c4 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -948,7 +948,7 @@ NTSTATUS ntvfs_simple_init(void) ops.trans = svfs_trans; /* register ourselves with the NTVFS subsystem. We register - under two names 'simple' and 'default' + under names 'simple' */ ops.name = "simple"; ret = register_backend("ntvfs", &ops); @@ -958,13 +958,5 @@ NTSTATUS ntvfs_simple_init(void) ops.name)); } - /* also register as "default" */ - ops.name = "default"; - ret = register_backend("ntvfs", &ops); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register simple backend with name: %s!\n", - ops.name)); - } - return ret; } -- cgit From 8aa6f931d68001d7f9cb390afdd32093aa3573ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 21 Apr 2004 14:28:06 +0000 Subject: r313: add the warning about fileaccess as user 'root' to a README file and DEBUG(0,()) it on each tree connect metze (This used to be commit d52eb75107f291635afcfbe5b79d863f54349793) --- source4/ntvfs/simple/README | 10 ++++++++++ source4/ntvfs/simple/vfs_simple.c | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 source4/ntvfs/simple/README (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/README b/source4/ntvfs/simple/README new file mode 100644 index 0000000000..f1de5d9f80 --- /dev/null +++ b/source4/ntvfs/simple/README @@ -0,0 +1,10 @@ +This module (ntvfs 'simple') provides a very, very simple posix backend. + +WARNING: All file access is done as user 'root'!!! + Only use this module for testing, with only test data!!! + +For activating this module use: + +[testshare] + path = /tmp/testshare + nfvfs handler = simple diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index e36e4a62c4..37edd8aa11 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -65,6 +65,8 @@ static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) conn->fs_type = talloc_strdup(conn->mem_ctx, "NTFS"); conn->dev_type = talloc_strdup(conn->mem_ctx, "A:"); + DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); + return NT_STATUS_OK; } -- cgit From 0f581e4af943a7e5dfd71d1c308ac668f287aed3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 May 2004 11:23:50 +0000 Subject: r623: setUserInfo level 24 (password set) now works in the SAMR server. This includes all of the password complexity, password history and other password restrictions. (This used to be commit cb070b9084d95cf5178edbef951b75eab62b7220) --- source4/ntvfs/ipc/vfs_ipc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index cf1d21bf33..1c02e8fadc 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -252,6 +252,11 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, *ps = p; + /* tell the RPC layer the transport session key */ + if (req->user_ctx->vuser) { + dcesrv_set_session_key(p->dce_conn, req->user_ctx->vuser->session_key); + } + return NT_STATUS_OK; } -- cgit From f236700ef67d4f93ec56ec7808584552e94e0dfe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 May 2004 10:20:53 +0000 Subject: r665: merge over the new build system from my tmp branch to the main SAMBA_4_0 tree. NOTE: that it's not completely ready, but it's functional:-) metze (This used to be commit c78a2ddb28ec50d6570a83b1f66f18a5c3621731) --- source4/ntvfs/config.m4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index 420c3ec62a..1cf5b39a7c 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -233,8 +233,8 @@ samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)]) SMB_MODULE(ntvfs_cifs, NTVFS, STATIC, [ntvfs/cifs/vfs_cifs.o]) SMB_MODULE(ntvfs_simple, NTVFS, STATIC, - [ntvfs/simple/vfs_simple.o ntvfs/simple/svfs_util.o], - ntvfs/simple/svfs_private.h) + [ntvfs/simple/vfs_simple.o], + [ntvfs/simple/svfs_util.o]) SMB_MODULE(ntvfs_print, NTVFS, STATIC, [ntvfs/print/vfs_print.o]) @@ -245,5 +245,5 @@ SMB_MODULE(ntvfs_posix, NTVFS, STATIC, [ntvfs/posix/vfs_posix.o]) SMB_MODULE(ntvfs_nbench, NTVFS, STATIC, [ntvfs/nbench/vfs_nbench.o]) SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o, - [ntvfs/ntvfs_generic.o ntvfs/ntvfs_util.o], - ntvfs_public_proto.h) + [ntvfs/ntvfs_generic.o + ntvfs/ntvfs_util.o]) -- cgit From b340a61cb935e014090eed7105f8f50c3a00e71b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 May 2004 07:17:51 +0000 Subject: r755: - disallow process_model _thread when we don't have pwread/pwrite and have to use the nonthreadsafe wrapper - add pread/pwrite wrapper to ntvfs_simple - fix const warning in ntvfs_simple metze (This used to be commit f0b2e42978a28204f497cccb07e407f409e3bf50) --- source4/ntvfs/simple/vfs_simple.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 37edd8aa11..1abf5ed9af 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -35,6 +35,26 @@ #define CHECK_READ_ONLY(req) do { if (lp_readonly(req->conn->service)) return NT_STATUS_ACCESS_DENIED; } while (0) +#ifndef HAVE_PREAD +static ssize_t pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) +{ + if (lseek(__fd, __offset, SEEK_SET) != __offset) { + return -1; + } + return read(__fd, __buf, __nbytes); +} +#endif + +#ifndef HAVE_PWRITE +static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) +{ + if (lseek(__fd, __offset, SEEK_SET) != __offset) { + return -1; + } + return write(__fd, __buf, __nbytes); +} +#endif + /* connect to a share - used when a tree_connect operation comes in. For a disk based backend we needs to ensure that the base @@ -151,7 +171,7 @@ static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinf struct svfs_dir *dir = NULL; char *pattern = NULL; int i; - char *s, *short_name; + const char *s, *short_name; s = strrchr(unix_path, '/'); if (s) { -- cgit From cfc2f3c5ab426d31cc11e47ff4c308cb72209db8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 18 May 2004 13:13:17 +0000 Subject: r766: convert ntvfs/* to a config.mk file metze (This used to be commit 62d456c144e76b0d14225c2eed5b35bdf9650057) --- source4/ntvfs/config.m4 | 18 ++++++-------- source4/ntvfs/config.mk | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 source4/ntvfs/config.mk (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index 1cf5b39a7c..b5dbd7e3b7 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -230,20 +230,16 @@ samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)]) # end check for sendfile support ################################################# -SMB_MODULE(ntvfs_cifs, NTVFS, STATIC, [ntvfs/cifs/vfs_cifs.o]) +SMB_MODULE_MK(ntvfs_cifs, NTVFS, STATIC, ntvfs/config.mk) -SMB_MODULE(ntvfs_simple, NTVFS, STATIC, - [ntvfs/simple/vfs_simple.o], - [ntvfs/simple/svfs_util.o]) +SMB_MODULE_MK(ntvfs_simple, NTVFS, STATIC, ntvfs/config.mk) -SMB_MODULE(ntvfs_print, NTVFS, STATIC, [ntvfs/print/vfs_print.o]) +SMB_MODULE_MK(ntvfs_print, NTVFS, STATIC, ntvfs/config.mk) -SMB_MODULE(ntvfs_ipc, NTVFS, STATIC, [ntvfs/ipc/vfs_ipc.o]) +SMB_MODULE_MK(ntvfs_ipc, NTVFS, STATIC, ntvfs/config.mk) -SMB_MODULE(ntvfs_posix, NTVFS, STATIC, [ntvfs/posix/vfs_posix.o]) +SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) -SMB_MODULE(ntvfs_nbench, NTVFS, STATIC, [ntvfs/nbench/vfs_nbench.o]) +SMB_MODULE_MK(ntvfs_nbench, NTVFS, STATIC, ntvfs/config.mk) -SMB_SUBSYSTEM(NTVFS,ntvfs/ntvfs_base.o, - [ntvfs/ntvfs_generic.o - ntvfs/ntvfs_util.o]) +SMB_SUBSYSTEM_MK(NTVFS,ntvfs/config.mk) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk new file mode 100644 index 0000000000..0feb380824 --- /dev/null +++ b/source4/ntvfs/config.mk @@ -0,0 +1,65 @@ +# NTVFS Server subsystem + +################################################ +# Start MODULE ntvfs_cifs +[MODULE::ntvfs_cifs] +INIT_OBJ_FILES = \ + ntvfs/cifs/vfs_cifs.o +REQUIRED_SUBSYSTEMS = \ + LIBCLI +# End MODULE ntvfs_cifs +################################################ + +################################################ +# Start MODULE ntvfs_simple +[MODULE::ntvfs_simple] +INIT_OBJ_FILES = \ + ntvfs/simple/vfs_simple.o +ADD_OBJ_FILES = \ + ntvfs/simple/svfs_util.o +# End MODULE ntvfs_cifs +################################################ + +################################################ +# Start MODULE ntvfs_print +[MODULE::ntvfs_print] +INIT_OBJ_FILES = \ + ntvfs/print/vfs_print.o +# End MODULE ntvfs_print +################################################ + +################################################ +# Start MODULE ntvfs_ipc +[MODULE::ntvfs_ipc] +INIT_OBJ_FILES = \ + ntvfs/ipc/vfs_ipc.o +# End MODULE ntvfs_ipc +################################################ + +################################################ +# Start MODULE ntvfs_posix +[MODULE::ntvfs_posix] +INIT_OBJ_FILES = \ + ntvfs/posix/vfs_posix.o +# End MODULE ntvfs_posix +################################################ + +################################################ +# Start MODULE ntvfs_nbench +[MODULE::ntvfs_nbench] +INIT_OBJ_FILES = \ + ntvfs/nbench/vfs_nbench.o +# End MODULE ntvfs_nbench +################################################ + +################################################ +# Start SUBSYSTEM NTVFS +[SUBSYSTEM::NTVFS] +INIT_OBJ_FILES = \ + ntvfs/ntvfs_base.o +ADD_OBJ_FILES = \ + ntvfs/ntvfs_generic.o \ + ntvfs/ntvfs_util.o +# +# End SUBSYSTEM NTVFS +################################################ -- cgit From b744493be566d1edcfcc9c4b0d1bfbc271918203 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 24 May 2004 23:01:20 +0000 Subject: r862: remove acl and sendfile stuff it will be readded inside the ntvfs_posix module metze (This used to be commit ec624aefa86934da23105a5c014080b464efac28) --- source4/ntvfs/config.m4 | 230 ------------------------------------------------ 1 file changed, 230 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index b5dbd7e3b7..f23610fef4 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -1,235 +1,5 @@ dnl # NTVFS Server subsystem -################################################# -# check for sendfile support - -with_sendfile_support=yes -AC_MSG_CHECKING(whether to check to support sendfile) -AC_ARG_WITH(sendfile-support, -[ --with-sendfile-support Check for sendfile support (default=yes)], -[ case "$withval" in - yes) - - AC_MSG_RESULT(yes); - - case "$host_os" in - *linux*) - AC_CACHE_CHECK([for linux sendfile64 support],samba_cv_HAVE_SENDFILE64,[ - AC_TRY_LINK([#include ], -[\ -int tofd, fromfd; -off64_t offset; -size_t total; -ssize_t nwritten = sendfile64(tofd, fromfd, &offset, total); -], -samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)]) - - AC_CACHE_CHECK([for linux sendfile support],samba_cv_HAVE_SENDFILE,[ - AC_TRY_LINK([#include ], -[\ -int tofd, fromfd; -off_t offset; -size_t total; -ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); -], -samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) - -# Try and cope with broken Linux sendfile.... - AC_CACHE_CHECK([for broken linux sendfile support],samba_cv_HAVE_BROKEN_LINUX_SENDFILE,[ - AC_TRY_LINK([\ -#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64) -#undef _FILE_OFFSET_BITS -#endif -#include ], -[\ -int tofd, fromfd; -off_t offset; -size_t total; -ssize_t nwritten = sendfile(tofd, fromfd, &offset, total); -], -samba_cv_HAVE_BROKEN_LINUX_SENDFILE=yes,samba_cv_HAVE_BROKEN_LINUX_SENDFILE=no)]) - - if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then - AC_DEFINE(HAVE_SENDFILE64,1,[Whether 64-bit sendfile() is available]) - AC_DEFINE(LINUX_SENDFILE_API,1,[Whether linux sendfile() API is available]) - AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used]) - elif test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then - AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available]) - AC_DEFINE(LINUX_SENDFILE_API,1,[Whether linux sendfile() API is available]) - AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() should be used]) - elif test x"$samba_cv_HAVE_BROKEN_LINUX_SENDFILE" = x"yes"; then - AC_DEFINE(LINUX_BROKEN_SENDFILE_API,1,[Whether (linux) sendfile() is broken]) - AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile should be used]) - else - AC_MSG_RESULT(no); - fi - - ;; - *freebsd*) - AC_CACHE_CHECK([for freebsd sendfile support],samba_cv_HAVE_SENDFILE,[ - AC_TRY_LINK([\ -#include -#include -#include -#include ], -[\ - int fromfd, tofd, ret, total=0; - off_t offset, nwritten; - struct sf_hdtr hdr; - struct iovec hdtrl; - hdr.headers = &hdtrl; - hdr.hdr_cnt = 1; - hdr.trailers = NULL; - hdr.trl_cnt = 0; - hdtrl.iov_base = NULL; - hdtrl.iov_len = 0; - ret = sendfile(fromfd, tofd, offset, total, &hdr, &nwritten, 0); -], -samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) - - if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then - AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() support is available]) - AC_DEFINE(FREEBSD_SENDFILE_API,1,[Whether the FreeBSD sendfile() API is available]) - AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) - else - AC_MSG_RESULT(no); - fi - ;; - - *hpux*) - AC_CACHE_CHECK([for hpux sendfile64 support],samba_cv_HAVE_SENDFILE64,[ - AC_TRY_LINK([\ -#include -#include ], -[\ - int fromfd, tofd; - size_t total=0; - struct iovec hdtrl[2]; - ssize_t nwritten; - off64_t offset; - - hdtrl[0].iov_base = 0; - hdtrl[0].iov_len = 0; - - nwritten = sendfile64(tofd, fromfd, offset, total, &hdtrl[0], 0); -], -samba_cv_HAVE_SENDFILE64=yes,samba_cv_HAVE_SENDFILE64=no)]) - if test x"$samba_cv_HAVE_SENDFILE64" = x"yes"; then - AC_DEFINE(HAVE_SENDFILE64,1,[Whether sendfile64() is available]) - AC_DEFINE(HPUX_SENDFILE_API,1,[Whether the hpux sendfile() API is available]) - AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) - else - AC_MSG_RESULT(no); - fi - - AC_CACHE_CHECK([for hpux sendfile support],samba_cv_HAVE_SENDFILE,[ - AC_TRY_LINK([\ -#include -#include ], -[\ - int fromfd, tofd; - size_t total=0; - struct iovec hdtrl[2]; - ssize_t nwritten; - off_t offset; - - hdtrl[0].iov_base = 0; - hdtrl[0].iov_len = 0; - - nwritten = sendfile(tofd, fromfd, offset, total, &hdtrl[0], 0); -], -samba_cv_HAVE_SENDFILE=yes,samba_cv_HAVE_SENDFILE=no)]) - if test x"$samba_cv_HAVE_SENDFILE" = x"yes"; then - AC_DEFINE(HAVE_SENDFILE,1,[Whether sendfile() is available]) - AC_DEFINE(HPUX_SENDFILE_API,1,[Whether the hpux sendfile() API is available]) - AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) - else - AC_MSG_RESULT(no); - fi - ;; - - *solaris*) - AC_CHECK_LIB(sendfile,sendfilev) - AC_CACHE_CHECK([for solaris sendfilev64 support],samba_cv_HAVE_SENDFILEV64,[ - AC_TRY_LINK([\ -#include ], -[\ - int sfvcnt; - size_t xferred; - struct sendfilevec vec[2]; - ssize_t nwritten; - int tofd; - - sfvcnt = 2; - - vec[0].sfv_fd = SFV_FD_SELF; - vec[0].sfv_flag = 0; - vec[0].sfv_off = 0; - vec[0].sfv_len = 0; - - vec[1].sfv_fd = 0; - vec[1].sfv_flag = 0; - vec[1].sfv_off = 0; - vec[1].sfv_len = 0; - nwritten = sendfilev64(tofd, vec, sfvcnt, &xferred); -], -samba_cv_HAVE_SENDFILEV64=yes,samba_cv_HAVE_SENDFILEV64=no)]) - - if test x"$samba_cv_HAVE_SENDFILEV64" = x"yes"; then - AC_DEFINE(HAVE_SENDFILEV64,1,[Whether sendfilev64() is available]) - AC_DEFINE(SOLARIS_SENDFILE_API,1,[Whether the soloris sendfile() API is available]) - AC_DEFINE(WITH_SENDFILE,1,[Whether sendfile() support should be included]) - else - AC_MSG_RESULT(no); - fi - - AC_CACHE_CHECK([for solaris sendfilev support],samba_cv_HAVE_SENDFILEV,[ - AC_TRY_LINK([\ -#include ], -[\ - int sfvcnt; - size_t xferred; - struct sendfilevec vec[2]; - ssize_t nwritten; - int tofd; - - sfvcnt = 2; - - vec[0].sfv_fd = SFV_FD_SELF; - vec[0].sfv_flag = 0; - vec[0].sfv_off = 0; - vec[0].sfv_len = 0; - - vec[1].sfv_fd = 0; - vec[1].sfv_flag = 0; - vec[1].sfv_off = 0; - vec[1].sfv_len = 0; - nwritten = sendfilev(tofd, vec, sfvcnt, &xferred); -], -samba_cv_HAVE_SENDFILEV=yes,samba_cv_HAVE_SENDFILEV=no)]) - - if test x"$samba_cv_HAVE_SENDFILEV" = x"yes"; then - AC_DEFINE(HAVE_SENDFILEV,1,[Whether sendfilev() is available]) - AC_DEFINE(SOLARIS_SENDFILE_API,1,[Whether the solaris sendfile() API is available]) - AC_DEFINE(WITH_SENDFILE,1,[Whether to include sendfile() support]) - else - AC_MSG_RESULT(no); - fi - ;; - - *) - ;; - esac - ;; - *) - AC_MSG_RESULT(no) - ;; - esac ], - AC_MSG_RESULT(yes) -) -# end check for sendfile support -################################################# - SMB_MODULE_MK(ntvfs_cifs, NTVFS, STATIC, ntvfs/config.mk) SMB_MODULE_MK(ntvfs_simple, NTVFS, STATIC, ntvfs/config.mk) -- cgit From 579c13da43d5b40ac6d6c1436399fbc1d8dfd054 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 May 2004 13:57:39 +0000 Subject: r873: converted samba4 to use real 64 bit integers instead of structures. This was suggested by metze recently. I checked on the build farm and all the machines we have support 64 bit ints, and support the LL suffix for 64 bit constants. I suspect some won't support strtoll() and related functions, so we will probably need replacements for those. (This used to be commit 9a9244a1c66654c12abe4379661cba83a73c4c21) --- source4/ntvfs/ntvfs_generic.c | 24 ++++++++++++------------ source4/ntvfs/simple/svfs_util.c | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index ea62f8c9a6..116b716474 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -153,7 +153,7 @@ NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) ZERO_STRUCT(io->openx.out); io->openx.out.fnum = io2.generic.out.fnum; io->openx.out.attrib = io2.generic.out.attrib; - io->openx.out.write_time = nt_time_to_unix(&io2.generic.out.write_time); + io->openx.out.write_time = nt_time_to_unix(io2.generic.out.write_time); io->openx.out.size = io2.generic.out.size; return NT_STATUS_OK; @@ -235,7 +235,7 @@ NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) ZERO_STRUCT(io->openx.out); io->open.out.fnum = io2.generic.out.fnum; io->open.out.attrib = io2.generic.out.attrib; - io->open.out.write_time = nt_time_to_unix(&io2.generic.out.write_time); + io->open.out.write_time = nt_time_to_unix(io2.generic.out.write_time); io->open.out.size = io2.generic.out.size; io->open.out.rmode = DOS_OPEN_RDWR; @@ -378,15 +378,15 @@ NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *inf case RAW_FILEINFO_GETATTR: info->getattr.out.attrib = info2->generic.out.attrib & 0xff; info->getattr.out.size = info2->generic.out.size; - info->getattr.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); + info->getattr.out.write_time = nt_time_to_unix(info2->generic.out.write_time); return NT_STATUS_OK; case RAW_FILEINFO_GETATTRE: info->getattre.out.attrib = info2->generic.out.attrib; info->getattre.out.size = info2->generic.out.size; - info->getattre.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); - info->getattre.out.create_time = nt_time_to_unix(&info2->generic.out.create_time); - info->getattre.out.access_time = nt_time_to_unix(&info2->generic.out.access_time); + info->getattre.out.write_time = nt_time_to_unix(info2->generic.out.write_time); + info->getattre.out.create_time = nt_time_to_unix(info2->generic.out.create_time); + info->getattre.out.access_time = nt_time_to_unix(info2->generic.out.access_time); info->getattre.out.alloc_size = info2->generic.out.alloc_size; return NT_STATUS_OK; @@ -427,18 +427,18 @@ NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *inf return NT_STATUS_OK; case RAW_FILEINFO_STANDARD: - info->standard.out.create_time = nt_time_to_unix(&info2->generic.out.create_time); - info->standard.out.access_time = nt_time_to_unix(&info2->generic.out.access_time); - info->standard.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); + info->standard.out.create_time = nt_time_to_unix(info2->generic.out.create_time); + info->standard.out.access_time = nt_time_to_unix(info2->generic.out.access_time); + info->standard.out.write_time = nt_time_to_unix(info2->generic.out.write_time); info->standard.out.size = info2->generic.out.size; info->standard.out.alloc_size = info2->generic.out.alloc_size; info->standard.out.attrib = info2->generic.out.attrib; return NT_STATUS_OK; case RAW_FILEINFO_EA_SIZE: - info->ea_size.out.create_time = nt_time_to_unix(&info2->generic.out.create_time); - info->ea_size.out.access_time = nt_time_to_unix(&info2->generic.out.access_time); - info->ea_size.out.write_time = nt_time_to_unix(&info2->generic.out.write_time); + info->ea_size.out.create_time = nt_time_to_unix(info2->generic.out.create_time); + info->ea_size.out.access_time = nt_time_to_unix(info2->generic.out.access_time); + info->ea_size.out.write_time = nt_time_to_unix(info2->generic.out.write_time); info->ea_size.out.size = info2->generic.out.size; info->ea_size.out.alloc_size = info2->generic.out.alloc_size; info->ea_size.out.attrib = info2->generic.out.attrib; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 598b85f1ad..11e70d72c2 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -180,9 +180,9 @@ uint16 svfs_unix_to_dos_attrib(mode_t mode) /* build a file_id from a stat struct */ -large_t svfs_file_id(struct stat *st) +uint64_t svfs_file_id(struct stat *st) { - large_t ret = st->st_ino; + uint64_t ret = st->st_ino; ret <<= 32; ret |= st->st_dev; return ret; -- cgit From f9d8f8843dc0ab8c9d59abde7222e0f118b86b5d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 16:24:13 +0000 Subject: r884: convert samba4 to use [u]int32_t instead of [u]int32 metze (This used to be commit 0e5517d937a2eb7cf707991d1c7498c1ab456095) --- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/reference/ref_util.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 1c02e8fadc..635b14b821 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -54,7 +54,7 @@ struct ipc_private { static uint16 find_next_fnum(struct ipc_private *ipc) { struct pipe_state *p; - uint32 ret; + uint32_t ret; if (ipc->num_open == 0xFFFF) { return 0; diff --git a/source4/ntvfs/reference/ref_util.c b/source4/ntvfs/reference/ref_util.c index 8234944ebd..75f3ac4948 100644 --- a/source4/ntvfs/reference/ref_util.c +++ b/source4/ntvfs/reference/ref_util.c @@ -133,7 +133,7 @@ struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, con /* convert a unix stat struct to a dos attrib */ -uint32 svfs_file_attrib(struct stat *st) +uint32_t svfs_file_attrib(struct stat *st) { if (S_ISDIR(st->st_mode)) { return FILE_ATTRIBUTE_DIRECTORY; -- cgit From f88bf54c7f6d1c2ef833047eb8327953c304b5ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 17:24:24 +0000 Subject: r889: convert samba4 to use [u]int16_t instead of [u]int16 metze (This used to be commit af6f1f8a01bebbecd99bc8c066519e89966e65e3) --- source4/ntvfs/cifs/vfs_cifs.c | 4 ++-- source4/ntvfs/ipc/vfs_ipc.c | 16 ++++++++-------- source4/ntvfs/reference/ref.h | 4 ++-- source4/ntvfs/simple/svfs.h | 4 ++-- source4/ntvfs/simple/svfs_util.c | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2a87d59a06..751280ad6c 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -60,7 +60,7 @@ static void idle_func(struct cli_transport *transport, void *p_private) a handler for oplock break events from the server - these need to be passed along to the client */ -static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 fnum, uint8 level, void *p_private) +static BOOL oplock_handler(struct cli_transport *transport, uint16_t tid, uint16_t fnum, uint8 level, void *p_private) { struct cvfs_private *private = p_private; @@ -71,7 +71,7 @@ static BOOL oplock_handler(struct cli_transport *transport, uint16 tid, uint16 f /* a handler for read events on a connection to a backend server */ -static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16 flags) +static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16_t flags) { struct cvfs_private *private = fde->private; struct tcon_context *conn = private->conn; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 635b14b821..9a2589a2ee 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -32,17 +32,17 @@ pipes */ struct ipc_private { - uint16 next_fnum; - uint16 num_open; + uint16_t next_fnum; + uint16_t num_open; /* a list of open pipes */ struct pipe_state { struct pipe_state *next, *prev; TALLOC_CTX *mem_ctx; const char *pipe_name; - uint16 fnum; + uint16_t fnum; struct dcesrv_connection *dce_conn; - uint16 ipc_state; + uint16_t ipc_state; } *pipe_list; }; @@ -51,7 +51,7 @@ struct ipc_private { /* find the next fnum available on this connection */ -static uint16 find_next_fnum(struct ipc_private *ipc) +static uint16_t find_next_fnum(struct ipc_private *ipc) { struct pipe_state *p; uint32_t ret; @@ -88,7 +88,7 @@ static void pipe_shutdown(struct ipc_private *private, struct pipe_state *p) /* find a open pipe give a file descriptor */ -static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16 fnum) +static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t fnum) { struct pipe_state *p; @@ -369,7 +369,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) { struct ipc_private *private = req->conn->ntvfs_private; DATA_BLOB data; - uint16 fnum; + uint16_t fnum; struct pipe_state *p; NTSTATUS status; @@ -421,7 +421,7 @@ static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr) { struct ipc_private *private = req->conn->ntvfs_private; DATA_BLOB data; - uint16 fnum; + uint16_t fnum; struct pipe_state *p; NTSTATUS status; diff --git a/source4/ntvfs/reference/ref.h b/source4/ntvfs/reference/ref.h index 00eab76094..8ac4556420 100644 --- a/source4/ntvfs/reference/ref.h +++ b/source4/ntvfs/reference/ref.h @@ -10,7 +10,7 @@ struct rvfs_private { struct search_state *search; /* next available search handle */ - uint16 next_search_handle; + uint16_t next_search_handle; }; struct rvfs_dir { @@ -24,7 +24,7 @@ struct rvfs_dir { struct search_state { struct search_state *next, *prev; TALLOC_CTX *mem_ctx; - uint16 handle; + uint16_t handle; uint_t current_index; struct rvfs_dir *dir; }; diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index 6e44d290da..373e6dc126 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -7,7 +7,7 @@ struct svfs_private { struct search_state *search; /* next available search handle */ - uint16 next_search_handle; + uint16_t next_search_handle; struct svfs_file *open_files; }; @@ -30,7 +30,7 @@ struct svfs_file { struct search_state { struct search_state *next, *prev; TALLOC_CTX *mem_ctx; - uint16 handle; + uint16_t handle; uint_t current_index; struct svfs_dir *dir; }; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 11e70d72c2..ec1c07dff7 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -169,9 +169,9 @@ int svfs_file_utime(int fd, struct utimbuf *times) /* map a unix file attrib to a DOS attribute */ -uint16 svfs_unix_to_dos_attrib(mode_t mode) +uint16_t svfs_unix_to_dos_attrib(mode_t mode) { - uint16 ret = 0; + uint16_t ret = 0; if (S_ISDIR(mode)) ret |= FILE_ATTRIBUTE_DIRECTORY; if (!(mode & S_IWUSR)) ret |= FILE_ATTRIBUTE_READONLY; return ret; -- cgit From fcd718c7d8a6850ae8719f23ed044b06b57501cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 25 May 2004 17:50:17 +0000 Subject: r890: convert samba4 to use [u]int8_t instead of [u]int8 metze (This used to be commit 2986c5f08c8f0c26a2ea7b6ce20aae025183109f) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 751280ad6c..27c9e38ec4 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -60,7 +60,7 @@ static void idle_func(struct cli_transport *transport, void *p_private) a handler for oplock break events from the server - these need to be passed along to the client */ -static BOOL oplock_handler(struct cli_transport *transport, uint16_t tid, uint16_t fnum, uint8 level, void *p_private) +static BOOL oplock_handler(struct cli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) { struct cvfs_private *private = p_private; -- cgit From 770e3307ce3da928762e15a136c562df86a9c799 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Jun 2004 10:12:52 +0000 Subject: r962: convert 'unsigned' and 'unsigned int' to uint_t metze (This used to be commit 57151e80eb1090281401930c8fe25b20a8cf3a38) --- source4/ntvfs/ntvfs_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 116b716474..0781558e8e 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -273,7 +273,7 @@ NTSTATUS ntvfs_map_fsinfo(struct request_context *req, union smb_fsinfo *fs) case RAW_QFS_DSKATTR: { /* map from generic to DSKATTR */ - unsigned bpunit = 64; + uint_t bpunit = 64; /* we need to scale the sizes to fit */ for (bpunit=64; bpunit<0x10000; bpunit *= 2) { -- cgit From 0d466258be1fc7156de469daec07b79701557168 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jun 2004 01:39:08 +0000 Subject: r1019: Push the auth subsystem away from using typedef, and over to the 'all goodness and light' struct ;-) Break apart the auth subsystem's return strucutres, into the parts that a netlogon call cares about, and the parts that are for a local session. This is the 'struct session_info' and it will almost completly replace the current information stored on a vuid, but be generic to all login methods (RPC over TCP, for example). Andrew Bartlett (This used to be commit d199697014d9562f9439a30b950fda798c5ef419) --- source4/ntvfs/ipc/vfs_ipc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 9a2589a2ee..7ebf35d5cb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -254,7 +254,9 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, /* tell the RPC layer the transport session key */ if (req->user_ctx->vuser) { - dcesrv_set_session_key(p->dce_conn, req->user_ctx->vuser->session_key); + /* TODO: Fix this to push more than just a session key + * down - we need the entire session_info, reference counted... */ + dcesrv_set_session_key(p->dce_conn, req->user_ctx->vuser->session_info->session_key); } return NT_STATUS_OK; -- cgit From b717b40235b2433b26b20ced36142c250f9c411e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 7 Jun 2004 21:34:32 +0000 Subject: r1078: the dxesrv_crypto_* implementations should now explicit set the dce_conn->auth_state.session_info ( the ntlmssp one works fine, but the schannel one isn't implemented yet) this is also set by the ntvfs_ipc backend on the endpoint connect. metze (This used to be commit ad3dd1789e9f124493519cb4731d9f5a563fd051) --- source4/ntvfs/ipc/vfs_ipc.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7ebf35d5cb..9279e0e85a 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -195,6 +195,7 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, TALLOC_CTX *mem_ctx; NTSTATUS status; struct dcesrv_ep_description ep_description; + struct auth_session_info *session_info = NULL; struct ipc_private *private = req->conn->ntvfs_private; mem_ctx = talloc_init("ipc_open '%s'", fname); @@ -240,7 +241,18 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, ep_description.type = ENDPOINT_SMB; ep_description.info.smb_pipe = p->pipe_name; - status = dcesrv_endpoint_search_connect(&req->smb->dcesrv, &ep_description, &p->dce_conn); + /* tell the RPC layer the session_info */ + if (req->user_ctx->vuser) { + /* + * TODO: we need to reference count the entire session_info + */ + session_info = req->user_ctx->vuser->session_info; + } + + status = dcesrv_endpoint_search_connect(&req->smb->dcesrv, + &ep_description, + session_info, + &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { talloc_destroy(mem_ctx); return status; @@ -252,13 +264,6 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, *ps = p; - /* tell the RPC layer the transport session key */ - if (req->user_ctx->vuser) { - /* TODO: Fix this to push more than just a session key - * down - we need the entire session_info, reference counted... */ - dcesrv_set_session_key(p->dce_conn, req->user_ctx->vuser->session_info->session_key); - } - return NT_STATUS_OK; } -- cgit From b1268fc4455f61ee49412fc256106cd34e98ce7c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Jun 2004 23:50:55 +0000 Subject: r1123: Make all lp_ string functions return 'const char *'. Fix other 'const' warnings in the torture code. Andrew Bartlett (This used to be commit 5d39d7497f189da15d659b3f83b7314026040a15) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 27c9e38ec4..9e8768ae22 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -92,7 +92,7 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) struct tcon_context *conn = req->conn; NTSTATUS status; struct cvfs_private *private; - char *map_calls; + const char *map_calls; struct fd_event fde; const char *host, *user, *pass, *domain, *remote_share; -- cgit From b00103dac1bf9e559e132c62e768dba9408b94eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 16 Jun 2004 06:49:24 +0000 Subject: r1165: fixed handling of SMBtrans replies that should return STATUS_BUFFER_OVERFLOW when more data is present. (This used to be commit 0e557fe85748558affd20a58455c4b75fee69e27) --- source4/ntvfs/ipc/vfs_ipc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 9279e0e85a..5b61c9285e 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -401,7 +401,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) } status = dcesrv_output_blob(p->dce_conn, &data); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_IS_ERR(status)) { return status; } @@ -418,7 +418,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) return NT_STATUS_NOT_SUPPORTED; } - return NT_STATUS_OK; + return status; } /* @@ -624,7 +624,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t the error is encoded at the dcerpc level */ status = dcesrv_output_blob(p->dce_conn, &trans->out.data); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_IS_ERR(status)) { return status; } @@ -632,7 +632,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t trans->out.setup = NULL; trans->out.params = data_blob(NULL, 0); - return NT_STATUS_OK; + return status; } -- cgit From 37fcf2236433bc5e74f19d2afac3d1d0055dcd01 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 27 Jun 2004 11:06:10 +0000 Subject: r1268: varient -> variant (This used to be commit de5984c95602ca67e8ac3139c3aa4330b74266e0) --- source4/ntvfs/ntvfs_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 0781558e8e..d7d6f67a94 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -27,7 +27,7 @@ these functions must supply the generic call, but can if it wants to also implement other levels if the need arises - this allows backend writers to only implement one varient of each + this allows backend writers to only implement one variant of each call unless they need fine grained control of the calls. */ -- cgit From d4ae6ae74d712b74800e360590052d318d2fd101 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Jun 2004 07:41:15 +0000 Subject: r1277: rename struct server_context to smbsrv_ontext because I need server_context fot the generic server infastructure metze (This used to be commit 0712f9f30797e65362c99423c0cf158a2f539000) --- source4/ntvfs/cifs/vfs_cifs.c | 8 ++++---- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/ntvfs_generic.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9e8768ae22..0c00beecbb 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -51,8 +51,8 @@ struct async_info { static void idle_func(struct cli_transport *transport, void *p_private) { struct cvfs_private *private = p_private; - if (socket_pending(private->conn->smb->socket.fd)) { - smbd_process_async(private->conn->smb); + if (socket_pending(private->conn->smb_ctx->socket.fd)) { + smbd_process_async(private->conn->smb_ctx); } } @@ -164,7 +164,7 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) fde.private = private; fde.handler = cifs_socket_handler; - event_add_fd(conn->smb->events, &fde); + event_add_fd(conn->smb_ctx->events, &fde); /* we need to receive oplock break requests from the server */ cli_oplock_handler(private->transport, oplock_handler, private); @@ -180,7 +180,7 @@ static NTSTATUS cvfs_disconnect(struct tcon_context *conn) { struct cvfs_private *private = conn->ntvfs_private; - event_remove_fd_all(conn->smb->events, private->transport->socket->fd); + event_remove_fd_all(conn->smb_ctx->events, private->transport->socket->fd); smb_tree_disconnect(private->tree); cli_tree_close(private->tree); diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 5b61c9285e..8cef711d69 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -249,7 +249,7 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, session_info = req->user_ctx->vuser->session_info; } - status = dcesrv_endpoint_search_connect(&req->smb->dcesrv, + status = dcesrv_endpoint_search_connect(&req->smb_ctx->dcesrv, &ep_description, session_info, &p->dce_conn); diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index d7d6f67a94..0f5f0badcb 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -290,7 +290,7 @@ NTSTATUS ntvfs_map_fsinfo(struct request_context *req, union smb_fsinfo *fs) (fs2.generic.out.blocks_free * (double)fs2.generic.out.block_size) / (bpunit * 512); /* we must return a maximum of 2G to old DOS systems, or they get very confused */ - if (bpunit > 64 && req->smb->negotiate.protocol <= PROTOCOL_LANMAN2) { + if (bpunit > 64 && req->smb_ctx->negotiate.protocol <= PROTOCOL_LANMAN2) { fs->dskattr.out.blocks_per_unit = 64; fs->dskattr.out.units_total = 0xFFFF; fs->dskattr.out.units_free = 0xFFFF; -- cgit From 4ddb2d347d86818a13d71d0eb2f0f8983c2cc41f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Jun 2004 08:27:36 +0000 Subject: r1279: rename struct tcon_context to smbsrv_tcon metze (This used to be commit 99473fab4b1ff87a795f3c08f4c521d9beb504c0) --- source4/ntvfs/cifs/vfs_cifs.c | 90 +++++++++++++++++++-------------------- source4/ntvfs/ipc/vfs_ipc.c | 24 +++++------ source4/ntvfs/nbench/vfs_nbench.c | 80 +++++++++++++++++----------------- source4/ntvfs/ntvfs.h | 4 +- source4/ntvfs/ntvfs_base.c | 10 ++--- source4/ntvfs/ntvfs_generic.c | 10 ++--- source4/ntvfs/print/vfs_print.c | 4 +- source4/ntvfs/simple/svfs_util.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 50 +++++++++++----------- 9 files changed, 137 insertions(+), 137 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 0c00beecbb..6af8cd1878 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -31,7 +31,7 @@ struct cvfs_private { struct cli_tree *tree; struct cli_transport *transport; - struct tcon_context *conn; + struct smbsrv_tcon *tcon; const char *map_calls; }; @@ -51,8 +51,8 @@ struct async_info { static void idle_func(struct cli_transport *transport, void *p_private) { struct cvfs_private *private = p_private; - if (socket_pending(private->conn->smb_ctx->socket.fd)) { - smbd_process_async(private->conn->smb_ctx); + if (socket_pending(private->tcon->smb_ctx->socket.fd)) { + smbd_process_async(private->tcon->smb_ctx); } } @@ -65,7 +65,7 @@ static BOOL oplock_handler(struct cli_transport *transport, uint16_t tid, uint16 struct cvfs_private *private = p_private; DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); - return req_send_oplock_break(private->conn, fnum, level); + return req_send_oplock_break(private->tcon, fnum, level); } /* @@ -74,13 +74,13 @@ static BOOL oplock_handler(struct cli_transport *transport, uint16_t tid, uint16 static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16_t flags) { struct cvfs_private *private = fde->private; - struct tcon_context *conn = private->conn; + struct smbsrv_tcon *tcon = private->tcon; DEBUG(5,("cifs_socket_handler event on fd %d\n", fde->fd)); if (!cli_request_receive_next(private->transport)) { /* the connection to our server is dead */ - close_cnum(conn); + close_cnum(tcon); } } @@ -89,7 +89,7 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, */ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) { - struct tcon_context *conn = req->conn; + struct smbsrv_tcon *tcon = req->tcon; NTSTATUS status; struct cvfs_private *private; const char *map_calls; @@ -100,11 +100,11 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. */ - host = lp_parm_string(req->conn->service, "cifs", "server"); - user = lp_parm_string(req->conn->service, "cifs", "user"); - pass = lp_parm_string(req->conn->service, "cifs", "password"); - domain = lp_parm_string(req->conn->service, "cifs", "domain"); - remote_share = lp_parm_string(req->conn->service, "cifs", "share"); + host = lp_parm_string(req->tcon->service, "cifs", "server"); + user = lp_parm_string(req->tcon->service, "cifs", "user"); + pass = lp_parm_string(req->tcon->service, "cifs", "password"); + domain = lp_parm_string(req->tcon->service, "cifs", "domain"); + remote_share = lp_parm_string(req->tcon->service, "cifs", "share"); if (!remote_share) { remote_share = sharename; } @@ -114,13 +114,13 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) return NT_STATUS_INVALID_PARAMETER; } - private = talloc(req->conn->mem_ctx, sizeof(struct cvfs_private)); + private = talloc(req->tcon->mem_ctx, sizeof(struct cvfs_private)); if (!private) { return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(private); - req->conn->ntvfs_private = (void *)private; + req->tcon->ntvfs_private = (void *)private; status = cli_tree_full_connection(&private->tree, "vfs_cifs", @@ -135,26 +135,26 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) private->transport = private->tree->session->transport; private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); - private->conn = req->conn; + private->tcon = req->tcon; - conn->fs_type = talloc_strdup(conn->mem_ctx, "NTFS"); - conn->dev_type = talloc_strdup(conn->mem_ctx, "A:"); + tcon->fs_type = talloc_strdup(tcon->mem_ctx, "NTFS"); + tcon->dev_type = talloc_strdup(tcon->mem_ctx, "A:"); - map_calls = lp_parm_string(req->conn->service, "cifs", "map calls"); + map_calls = lp_parm_string(req->tcon->service, "cifs", "map calls"); if (map_calls) { - private->map_calls = talloc_strdup(conn->mem_ctx, map_calls); + private->map_calls = talloc_strdup(tcon->mem_ctx, map_calls); } /* if we are mapping trans2, then we need to give a trans2 pointer in the operations structure */ if (private->map_calls && in_list("trans2", private->map_calls, True)) { - struct ntvfs_ops *ops = talloc_memdup(conn->mem_ctx,conn->ntvfs_ops,sizeof(*ops)); + struct ntvfs_ops *ops = talloc_memdup(tcon->mem_ctx,tcon->ntvfs_ops,sizeof(*ops)); static NTSTATUS cvfs_trans2(struct request_context *,struct smb_trans2 *); if (!ops) { return NT_STATUS_NO_MEMORY; } ops->trans2 = cvfs_trans2; - conn->ntvfs_ops = ops; + tcon->ntvfs_ops = ops; } /* we need to tell the event loop that we wish to receive read events @@ -164,7 +164,7 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) fde.private = private; fde.handler = cifs_socket_handler; - event_add_fd(conn->smb_ctx->events, &fde); + event_add_fd(tcon->smb_ctx->events, &fde); /* we need to receive oplock break requests from the server */ cli_oplock_handler(private->transport, oplock_handler, private); @@ -176,11 +176,11 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS cvfs_disconnect(struct tcon_context *conn) +static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) { - struct cvfs_private *private = conn->ntvfs_private; + struct cvfs_private *private = tcon->ntvfs_private; - event_remove_fd_all(conn->smb_ctx->events, private->transport->socket->fd); + event_remove_fd_all(tcon->smb_ctx->events, private->transport->socket->fd); smb_tree_disconnect(private->tree); cli_tree_close(private->tree); @@ -225,7 +225,7 @@ static void async_simple(struct cli_request *c_req) */ static NTSTATUS cvfs_unlink(struct request_context *req, struct smb_unlink *unl) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; /* see if the front end will allow us to perform this @@ -255,7 +255,7 @@ static void async_ioctl(struct cli_request *c_req) */ static NTSTATUS cvfs_ioctl(struct request_context *req, union smb_ioctl *io) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; /* see if the front end will allow us to perform this @@ -274,7 +274,7 @@ static NTSTATUS cvfs_ioctl(struct request_context *req, union smb_ioctl *io) */ static NTSTATUS cvfs_chkpath(struct request_context *req, struct smb_chkpath *cp) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -302,7 +302,7 @@ static void async_qpathinfo(struct cli_request *c_req) */ static NTSTATUS cvfs_qpathinfo(struct request_context *req, union smb_fileinfo *info) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -330,7 +330,7 @@ static void async_qfileinfo(struct cli_request *c_req) */ static NTSTATUS cvfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -348,7 +348,7 @@ static NTSTATUS cvfs_qfileinfo(struct request_context *req, union smb_fileinfo * */ static NTSTATUS cvfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -377,7 +377,7 @@ static void async_open(struct cli_request *c_req) */ static NTSTATUS cvfs_open(struct request_context *req, union smb_open *io) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (private->map_calls && in_list("open", private->map_calls, True) && @@ -399,7 +399,7 @@ static NTSTATUS cvfs_open(struct request_context *req, union smb_open *io) */ static NTSTATUS cvfs_mkdir(struct request_context *req, union smb_mkdir *md) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -416,7 +416,7 @@ static NTSTATUS cvfs_mkdir(struct request_context *req, union smb_mkdir *md) */ static NTSTATUS cvfs_rmdir(struct request_context *req, struct smb_rmdir *rd) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -432,7 +432,7 @@ static NTSTATUS cvfs_rmdir(struct request_context *req, struct smb_rmdir *rd) */ static NTSTATUS cvfs_rename(struct request_context *req, union smb_rename *ren) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -468,7 +468,7 @@ static void async_read(struct cli_request *c_req) */ static NTSTATUS cvfs_read(struct request_context *req, union smb_read *rd) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -496,7 +496,7 @@ static void async_write(struct cli_request *c_req) */ static NTSTATUS cvfs_write(struct request_context *req, union smb_write *wr) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -529,7 +529,7 @@ static NTSTATUS cvfs_flush(struct request_context *req, struct smb_flush *io) */ static NTSTATUS cvfs_close(struct request_context *req, union smb_close *io) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -554,7 +554,7 @@ static NTSTATUS cvfs_exit(struct request_context *req) */ static NTSTATUS cvfs_lock(struct request_context *req, union smb_lock *lck) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -571,7 +571,7 @@ static NTSTATUS cvfs_lock(struct request_context *req, union smb_lock *lck) static NTSTATUS cvfs_setfileinfo(struct request_context *req, union smb_setfileinfo *info) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -599,7 +599,7 @@ static void async_fsinfo(struct cli_request *c_req) */ static NTSTATUS cvfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { @@ -626,7 +626,7 @@ static NTSTATUS cvfs_search_first(struct request_context *req, union smb_search_ void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; return smb_raw_search_first(private->tree, req->mem_ctx, io, search_private, callback); } @@ -636,7 +636,7 @@ static NTSTATUS cvfs_search_next(struct request_context *req, union smb_search_n void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; return smb_raw_search_next(private->tree, req->mem_ctx, io, search_private, callback); } @@ -644,7 +644,7 @@ static NTSTATUS cvfs_search_next(struct request_context *req, union smb_search_n /* close a search */ static NTSTATUS cvfs_search_close(struct request_context *req, union smb_search_close *io) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; return smb_raw_search_close(private->tree, io); } @@ -663,7 +663,7 @@ static void async_trans2(struct cli_request *c_req) /* raw trans2 */ static NTSTATUS cvfs_trans2(struct request_context *req, struct smb_trans2 *trans2) { - struct cvfs_private *private = req->conn->ntvfs_private; + struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; if (!req->async.send_fn) { diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 8cef711d69..b726dd6116 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -107,18 +107,18 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t */ static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) { - struct tcon_context *conn = req->conn; + struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; - conn->fs_type = talloc_strdup(conn->mem_ctx, "IPC"); - conn->dev_type = talloc_strdup(conn->mem_ctx, "IPC"); + tcon->fs_type = talloc_strdup(tcon->mem_ctx, "IPC"); + tcon->dev_type = talloc_strdup(tcon->mem_ctx, "IPC"); /* prepare the private state for this connection */ - private = talloc(conn->mem_ctx, sizeof(struct ipc_private)); + private = talloc(tcon->mem_ctx, sizeof(struct ipc_private)); if (!private) { return NT_STATUS_NO_MEMORY; } - conn->ntvfs_private = (void *)private; + tcon->ntvfs_private = (void *)private; private->pipe_list = NULL; private->next_fnum = 1; @@ -130,7 +130,7 @@ static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS ipc_disconnect(struct tcon_context *tcon) +static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon) { struct ipc_private *private = tcon->ntvfs_private; @@ -196,7 +196,7 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, NTSTATUS status; struct dcesrv_ep_description ep_description; struct auth_session_info *session_info = NULL; - struct ipc_private *private = req->conn->ntvfs_private; + struct ipc_private *private = req->tcon->ntvfs_private; mem_ctx = talloc_init("ipc_open '%s'", fname); if (!mem_ctx) { @@ -374,7 +374,7 @@ static NTSTATUS ipc_copy(struct request_context *req, struct smb_copy *cp) */ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) { - struct ipc_private *private = req->conn->ntvfs_private; + struct ipc_private *private = req->tcon->ntvfs_private; DATA_BLOB data; uint16_t fnum; struct pipe_state *p; @@ -426,7 +426,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) */ static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr) { - struct ipc_private *private = req->conn->ntvfs_private; + struct ipc_private *private = req->tcon->ntvfs_private; DATA_BLOB data; uint16_t fnum; struct pipe_state *p; @@ -495,7 +495,7 @@ static NTSTATUS ipc_flush(struct request_context *req, struct smb_flush *io) */ static NTSTATUS ipc_close(struct request_context *req, union smb_close *io) { - struct ipc_private *private = req->conn->ntvfs_private; + struct ipc_private *private = req->tcon->ntvfs_private; struct pipe_state *p; if (io->generic.level != RAW_CLOSE_CLOSE) { @@ -595,7 +595,7 @@ NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *i static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *trans) { struct pipe_state *p; - struct ipc_private *private = req->conn->ntvfs_private; + struct ipc_private *private = req->tcon->ntvfs_private; NTSTATUS status; /* the fnum is in setup[1] */ @@ -640,7 +640,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t static NTSTATUS ipc_set_nm_pipe_state(struct request_context *req, struct smb_trans2 *trans) { struct pipe_state *p; - struct ipc_private *private = req->conn->ntvfs_private; + struct ipc_private *private = req->tcon->ntvfs_private; /* the fnum is in setup[1] */ p = pipe_state_find(private, trans->in.setup[1]); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index acdeec455a..5e9fd430cc 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -59,17 +59,17 @@ static void nbench_log(struct nbench_private *private, Then we need to restore both of these after the call, as the next level could modify either of these */ -#define PASS_THRU(conn, op, args) do { \ - conn->ntvfs_private = private->passthru_private; \ - conn->ntvfs_ops = private->passthru_ops; \ +#define PASS_THRU(tcon, op, args) do { \ + tcon->ntvfs_private = private->passthru_private; \ + tcon->ntvfs_ops = private->passthru_ops; \ \ status = private->passthru_ops->op args; \ \ - private->passthru_private = conn->ntvfs_private; \ - private->passthru_ops = conn->ntvfs_ops; \ + private->passthru_private = tcon->ntvfs_private; \ + private->passthru_ops = tcon->ntvfs_ops; \ \ - conn->ntvfs_private = private; \ - conn->ntvfs_ops = private->nbench_ops; \ + tcon->ntvfs_private = private; \ + tcon->ntvfs_ops = private->nbench_ops; \ } while (0) /* @@ -82,7 +82,7 @@ static void nbench_log(struct nbench_private *private, #define PASS_THRU_REQ(req, op, args) do { \ void *send_fn_saved = req->async.send_fn; \ req->async.send_fn = NULL; \ - PASS_THRU(req->conn, op, args); \ + PASS_THRU(req->tcon, op, args); \ req->async.send_fn = send_fn_saved; \ } while (0) @@ -97,7 +97,7 @@ static NTSTATUS nbench_connect(struct request_context *req, const char *sharenam NTSTATUS status; char *logname = NULL; - private = talloc_p(req->conn->mem_ctx, struct nbench_private); + private = talloc_p(req->tcon->mem_ctx, struct nbench_private); if (!private) { return NT_STATUS_NO_MEMORY; } @@ -111,10 +111,10 @@ static NTSTATUS nbench_connect(struct request_context *req, const char *sharenam return NT_STATUS_UNSUCCESSFUL; } - passthru = lp_parm_string(req->conn->service, "nbench", "passthru"); + passthru = lp_parm_string(req->tcon->service, "nbench", "passthru"); private->passthru_private = NULL; - private->nbench_ops = req->conn->ntvfs_ops; + private->nbench_ops = req->tcon->ntvfs_ops; private->passthru_ops = ntvfs_backend_byname(passthru, NTVFS_DISK); if (!private->passthru_ops) { @@ -122,7 +122,7 @@ static NTSTATUS nbench_connect(struct request_context *req, const char *sharenam return NT_STATUS_UNSUCCESSFUL; } - PASS_THRU(req->conn, connect, (req, sharename)); + PASS_THRU(req->tcon, connect, (req, sharename)); return status; } @@ -130,12 +130,12 @@ static NTSTATUS nbench_connect(struct request_context *req, const char *sharenam /* disconnect from a share */ -static NTSTATUS nbench_disconnect(struct tcon_context *conn) +static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon) { - struct nbench_private *private = conn->ntvfs_private; + struct nbench_private *private = tcon->ntvfs_private; NTSTATUS status; - PASS_THRU(conn, disconnect, (conn)); + PASS_THRU(tcon, disconnect, (tcon)); close(private->log_fd); @@ -148,7 +148,7 @@ static NTSTATUS nbench_disconnect(struct tcon_context *conn) */ static NTSTATUS nbench_unlink(struct request_context *req, struct smb_unlink *unl) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, unlink, (req, unl)); @@ -165,7 +165,7 @@ static NTSTATUS nbench_unlink(struct request_context *req, struct smb_unlink *un */ static NTSTATUS nbench_ioctl(struct request_context *req, union smb_ioctl *io) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, ioctl, (req, io)); @@ -180,7 +180,7 @@ static NTSTATUS nbench_ioctl(struct request_context *req, union smb_ioctl *io) */ static NTSTATUS nbench_chkpath(struct request_context *req, struct smb_chkpath *cp) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, chkpath, (req, cp)); @@ -197,7 +197,7 @@ static NTSTATUS nbench_chkpath(struct request_context *req, struct smb_chkpath * */ static NTSTATUS nbench_qpathinfo(struct request_context *req, union smb_fileinfo *info) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, qpathinfo, (req, info)); @@ -215,7 +215,7 @@ static NTSTATUS nbench_qpathinfo(struct request_context *req, union smb_fileinfo */ static NTSTATUS nbench_qfileinfo(struct request_context *req, union smb_fileinfo *info) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, qfileinfo, (req, info)); @@ -234,7 +234,7 @@ static NTSTATUS nbench_qfileinfo(struct request_context *req, union smb_fileinfo */ static NTSTATUS nbench_setpathinfo(struct request_context *req, union smb_setfileinfo *st) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, setpathinfo, (req, st)); @@ -252,7 +252,7 @@ static NTSTATUS nbench_setpathinfo(struct request_context *req, union smb_setfil */ static NTSTATUS nbench_open(struct request_context *req, union smb_open *io) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, open, (req, io)); @@ -281,7 +281,7 @@ static NTSTATUS nbench_open(struct request_context *req, union smb_open *io) */ static NTSTATUS nbench_mkdir(struct request_context *req, union smb_mkdir *md) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, mkdir, (req, md)); @@ -296,7 +296,7 @@ static NTSTATUS nbench_mkdir(struct request_context *req, union smb_mkdir *md) */ static NTSTATUS nbench_rmdir(struct request_context *req, struct smb_rmdir *rd) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, rmdir, (req, rd)); @@ -313,7 +313,7 @@ static NTSTATUS nbench_rmdir(struct request_context *req, struct smb_rmdir *rd) */ static NTSTATUS nbench_rename(struct request_context *req, union smb_rename *ren) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, rename, (req, ren)); @@ -340,7 +340,7 @@ static NTSTATUS nbench_rename(struct request_context *req, union smb_rename *ren */ static NTSTATUS nbench_copy(struct request_context *req, struct smb_copy *cp) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, copy, (req, cp)); @@ -355,7 +355,7 @@ static NTSTATUS nbench_copy(struct request_context *req, struct smb_copy *cp) */ static NTSTATUS nbench_read(struct request_context *req, union smb_read *rd) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, read, (req, rd)); @@ -383,7 +383,7 @@ static NTSTATUS nbench_read(struct request_context *req, union smb_read *rd) */ static NTSTATUS nbench_write(struct request_context *req, union smb_write *wr) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, write, (req, wr)); @@ -421,7 +421,7 @@ static NTSTATUS nbench_write(struct request_context *req, union smb_write *wr) */ static NTSTATUS nbench_seek(struct request_context *req, struct smb_seek *io) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, seek, (req, io)); @@ -436,7 +436,7 @@ static NTSTATUS nbench_seek(struct request_context *req, struct smb_seek *io) */ static NTSTATUS nbench_flush(struct request_context *req, struct smb_flush *io) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, flush, (req, io)); @@ -453,7 +453,7 @@ static NTSTATUS nbench_flush(struct request_context *req, struct smb_flush *io) */ static NTSTATUS nbench_close(struct request_context *req, union smb_close *io) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, close, (req, io)); @@ -479,7 +479,7 @@ static NTSTATUS nbench_close(struct request_context *req, union smb_close *io) */ static NTSTATUS nbench_exit(struct request_context *req) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, exit, (req)); @@ -492,7 +492,7 @@ static NTSTATUS nbench_exit(struct request_context *req) */ static NTSTATUS nbench_lock(struct request_context *req, union smb_lock *lck) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, lock, (req, lck)); @@ -525,7 +525,7 @@ static NTSTATUS nbench_lock(struct request_context *req, union smb_lock *lck) static NTSTATUS nbench_setfileinfo(struct request_context *req, union smb_setfileinfo *info) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, setfileinfo, (req, info)); @@ -544,7 +544,7 @@ static NTSTATUS nbench_setfileinfo(struct request_context *req, */ static NTSTATUS nbench_fsinfo(struct request_context *req, union smb_fsinfo *fs) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, fsinfo, (req, fs)); @@ -561,7 +561,7 @@ static NTSTATUS nbench_fsinfo(struct request_context *req, union smb_fsinfo *fs) */ static NTSTATUS nbench_lpq(struct request_context *req, union smb_lpq *lpq) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, lpq, (req, lpq)); @@ -578,7 +578,7 @@ static NTSTATUS nbench_search_first(struct request_context *req, union smb_searc void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, search_first, (req, io, search_private, callback)); @@ -606,7 +606,7 @@ static NTSTATUS nbench_search_next(struct request_context *req, union smb_search void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, search_next, (req, io, search_private, callback)); @@ -619,7 +619,7 @@ static NTSTATUS nbench_search_next(struct request_context *req, union smb_search /* close a search */ static NTSTATUS nbench_search_close(struct request_context *req, union smb_search_close *io) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, search_close, (req, io)); @@ -632,7 +632,7 @@ static NTSTATUS nbench_search_close(struct request_context *req, union smb_searc /* SMBtrans - not used on file shares */ static NTSTATUS nbench_trans(struct request_context *req, struct smb_trans2 *trans2) { - struct nbench_private *private = req->conn->ntvfs_private; + struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; PASS_THRU_REQ(req, trans, (req,trans2)); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index b03ab218c6..dd245b09ce 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -31,7 +31,7 @@ struct ntvfs_ops { /* initial setup */ NTSTATUS (*connect)(struct request_context *req, const char *sharename); - NTSTATUS (*disconnect)(struct tcon_context *conn); + NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon); /* path operations */ NTSTATUS (*unlink)(struct request_context *req, struct smb_unlink *unl); @@ -82,6 +82,6 @@ struct ntvfs_critical_sizes { int interface_version; int sizeof_ntvfs_ops; int sizeof_SMB_OFF_T; - int sizeof_tcon_context; + int sizeof_smbsrv_tcon; int sizeof_request_context; }; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 7ed8c738b6..bb751bae01 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -102,7 +102,7 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) NTVFS_INTERFACE_VERSION, sizeof(struct ntvfs_ops), sizeof(SMB_OFF_T), - sizeof(struct tcon_context), + sizeof(struct smbsrv_tcon), sizeof(struct request_context), }; @@ -135,12 +135,12 @@ BOOL ntvfs_init(void) */ NTSTATUS ntvfs_init_connection(struct request_context *req) { - const char *handler = lp_ntvfs_handler(req->conn->service); + const char *handler = lp_ntvfs_handler(req->tcon->service); - req->conn->ntvfs_ops = ntvfs_backend_byname(handler, req->conn->type); + req->tcon->ntvfs_ops = ntvfs_backend_byname(handler, req->tcon->type); - if (!req->conn->ntvfs_ops) { - DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handler, req->conn->type)); + if (!req->tcon->ntvfs_ops) { + DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handler, req->tcon->type)); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 0f5f0badcb..b2cf107b7d 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -145,7 +145,7 @@ NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) io2.generic.in.file_attr = io->openx.in.file_attrs; io2.generic.in.fname = io->openx.in.fname; - status = req->conn->ntvfs_ops->open(req, &io2); + status = req->tcon->ntvfs_ops->open(req, &io2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -227,7 +227,7 @@ NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", io->open.in.flags, io2.generic.in.access_mask, io2.generic.in.share_access)); - status = req->conn->ntvfs_ops->open(req, &io2); + status = req->tcon->ntvfs_ops->open(req, &io2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -261,7 +261,7 @@ NTSTATUS ntvfs_map_fsinfo(struct request_context *req, union smb_fsinfo *fs) /* ask the backend for the generic info */ fs2.generic.level = RAW_QFS_GENERIC; - status = req->conn->ntvfs_ops->fsinfo(req, &fs2); + status = req->tcon->ntvfs_ops->fsinfo(req, &fs2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -603,7 +603,7 @@ NTSTATUS ntvfs_map_qfileinfo(struct request_context *req, union smb_fileinfo *in info2.generic.level = RAW_FILEINFO_GENERIC; info2.generic.in.fnum = info->generic.in.fnum; - status = req->conn->ntvfs_ops->qfileinfo(req, &info2); + status = req->tcon->ntvfs_ops->qfileinfo(req, &info2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -626,7 +626,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct request_context *req, union smb_fileinfo *in info2.generic.level = RAW_FILEINFO_GENERIC; info2.generic.in.fname = info->generic.in.fname; - status = req->conn->ntvfs_ops->qpathinfo(req, &info2); + status = req->tcon->ntvfs_ops->qpathinfo(req, &info2); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index f56b906501..a2ac429458 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -37,7 +37,7 @@ static NTSTATUS print_connect(struct request_context *req, const char *sharename /* disconnect from a share */ -static NTSTATUS print_disconnect(struct tcon_context *conn) +static NTSTATUS print_disconnect(struct smbsrv_tcon *tcon) { return NT_STATUS_OK; } @@ -71,7 +71,7 @@ static NTSTATUS print_ioctl(struct request_context *req, union smb_ioctl *io) p = io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); push_string(NULL, p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); - push_string(NULL, p+18, lp_servicename(req->conn->service), 13, STR_TERMINATE|STR_ASCII); + push_string(NULL, p+18, lp_servicename(req->tcon->service), 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index ec1c07dff7..0f0555ac18 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -31,7 +31,7 @@ */ char *svfs_unix_path(struct request_context *req, const char *name) { - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; char *ret; if (*name != '\\') { diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 1abf5ed9af..013419e4ee 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -33,7 +33,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (lp_readonly(req->conn->service)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (lp_readonly(req->tcon->service)) return NT_STATUS_ACCESS_DENIED; } while (0) #ifndef HAVE_PREAD static ssize_t pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) @@ -64,15 +64,15 @@ static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offs static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) { struct stat st; - struct tcon_context *conn = req->conn; + struct smbsrv_tcon *tcon = req->tcon; struct svfs_private *private; - conn->ntvfs_private = talloc_p(conn->mem_ctx, struct svfs_private); + tcon->ntvfs_private = talloc_p(tcon->mem_ctx, struct svfs_private); - private = conn->ntvfs_private; + private = tcon->ntvfs_private; private->next_search_handle = 0; - private->connectpath = talloc_strdup(conn->mem_ctx, lp_pathname(conn->service)); + private->connectpath = talloc_strdup(tcon->mem_ctx, lp_pathname(tcon->service)); private->open_files = NULL; /* the directory must exist */ @@ -82,8 +82,8 @@ static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) return NT_STATUS_BAD_NETWORK_NAME; } - conn->fs_type = talloc_strdup(conn->mem_ctx, "NTFS"); - conn->dev_type = talloc_strdup(conn->mem_ctx, "A:"); + tcon->fs_type = talloc_strdup(tcon->mem_ctx, "NTFS"); + tcon->dev_type = talloc_strdup(tcon->mem_ctx, "A:"); DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); @@ -93,7 +93,7 @@ static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS svfs_disconnect(struct tcon_context *req) +static NTSTATUS svfs_disconnect(struct smbsrv_tcon *tcon) { return NT_STATUS_OK; } @@ -268,7 +268,7 @@ static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo * */ static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) { - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; struct svfs_file *f; struct stat st; @@ -296,7 +296,7 @@ static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo * */ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) { - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; char *unix_path; struct stat st; int fd, flags; @@ -307,7 +307,7 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) return ntvfs_map_open(req, io); } - if (lp_readonly(req->conn->service)) { + if (lp_readonly(req->tcon->service)) { create_flags = 0; rdwr_flags = O_RDONLY; } else { @@ -341,7 +341,7 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { flags = O_RDONLY | O_DIRECTORY; - if (lp_readonly(req->conn->service)) { + if (lp_readonly(req->tcon->service)) { goto do_open; } switch (io->generic.in.open_disposition) { @@ -376,9 +376,9 @@ do_open: return map_nt_error_from_unix(errno); } - f = talloc_p(req->conn->mem_ctx, struct svfs_file); + f = talloc_p(req->tcon->mem_ctx, struct svfs_file); f->fd = fd; - f->name = talloc_strdup(req->conn->mem_ctx, unix_path); + f->name = talloc_strdup(req->tcon->mem_ctx, unix_path); DLIST_ADD(private->open_files, f); @@ -562,7 +562,7 @@ static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) */ static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) { - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; struct svfs_file *f; if (io->generic.level != RAW_CLOSE_CLOSE) { @@ -580,8 +580,8 @@ static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) } DLIST_REMOVE(private->open_files, f); - talloc_free(req->conn->mem_ctx, f->name); - talloc_free(req->conn->mem_ctx, f); + talloc_free(req->tcon->mem_ctx, f->name); + talloc_free(req->tcon->mem_ctx, f); return NT_STATUS_OK; } @@ -661,7 +661,7 @@ static NTSTATUS svfs_setfileinfo(struct request_context *req, */ static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) { - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { @@ -690,8 +690,8 @@ static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, lp_servicename(req->conn->service)); - fs->generic.out.fs_type = req->conn->fs_type; + fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, lp_servicename(req->tcon->service)); + fs->generic.out.fs_type = req->tcon->fs_type; return NT_STATUS_OK; } @@ -703,7 +703,7 @@ static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) { struct stat st; - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; if (fs->generic.level != RAW_FSATTR_GENERIC) { return ntvfs_map_fsattr(req, fs); @@ -722,7 +722,7 @@ static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) fs->generic.out.serial_number = 1; fs->generic.out.fs_type = talloc_strdup(req->mem_ctx, "NTFS"); fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, - lp_servicename(req->conn->service)); + lp_servicename(req->tcon->service)); return NT_STATUS_OK; } @@ -745,7 +745,7 @@ static NTSTATUS svfs_search_first(struct request_context *req, union smb_search_ { struct svfs_dir *dir; int i; - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; struct search_state *search; union smb_search_data file; TALLOC_CTX *mem_ctx; @@ -819,7 +819,7 @@ static NTSTATUS svfs_search_next(struct request_context *req, union smb_search_n { struct svfs_dir *dir; int i; - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; struct search_state *search; union smb_search_data file; uint_t max_count; @@ -902,7 +902,7 @@ found: /* close a search */ static NTSTATUS svfs_search_close(struct request_context *req, union smb_search_close *io) { - struct svfs_private *private = req->conn->ntvfs_private; + struct svfs_private *private = req->tcon->ntvfs_private; struct search_state *search; for (search=private->search; search; search = search->next) { -- cgit From 8bf537d119be3e1823ad41b8b8af0d163251b1c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Jun 2004 08:39:00 +0000 Subject: r1280: rename struct request_context to smbsrv_request metze (This used to be commit a85d2db5826a84b812ea5162a11f54edd25f74e3) --- source4/ntvfs/cifs/vfs_cifs.c | 76 +++++++++++++++++++------------------- source4/ntvfs/ipc/vfs_ipc.c | 62 +++++++++++++++---------------- source4/ntvfs/nbench/vfs_nbench.c | 52 +++++++++++++------------- source4/ntvfs/ntvfs.h | 56 ++++++++++++++-------------- source4/ntvfs/ntvfs_base.c | 4 +- source4/ntvfs/ntvfs_generic.c | 10 ++--- source4/ntvfs/posix/vfs_posix.c | 2 +- source4/ntvfs/print/vfs_print.c | 6 +-- source4/ntvfs/reference/ref_util.c | 4 +- source4/ntvfs/reference/vfs_ref.c | 56 ++++++++++++++-------------- source4/ntvfs/simple/svfs_util.c | 6 +-- source4/ntvfs/simple/vfs_simple.c | 56 ++++++++++++++-------------- 12 files changed, 195 insertions(+), 195 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 6af8cd1878..b0389b9e59 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -38,7 +38,7 @@ struct cvfs_private { /* a structure used to pass information to an async handler */ struct async_info { - struct request_context *req; + struct smbsrv_request *req; void *parms; }; @@ -87,7 +87,7 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, /* connect to a share - used when a tree_connect operation comes in. */ -static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) +static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; NTSTATUS status; @@ -149,7 +149,7 @@ static NTSTATUS cvfs_connect(struct request_context *req, const char *sharename) pointer in the operations structure */ if (private->map_calls && in_list("trans2", private->map_calls, True)) { struct ntvfs_ops *ops = talloc_memdup(tcon->mem_ctx,tcon->ntvfs_ops,sizeof(*ops)); - static NTSTATUS cvfs_trans2(struct request_context *,struct smb_trans2 *); + static NTSTATUS cvfs_trans2(struct smbsrv_request *,struct smb_trans2 *); if (!ops) { return NT_STATUS_NO_MEMORY; } @@ -195,7 +195,7 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) static void async_simple(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = cli_request_simple_recv(c_req); req->async.send_fn(req); } @@ -223,7 +223,7 @@ static void async_simple(struct cli_request *c_req) delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS cvfs_unlink(struct request_context *req, struct smb_unlink *unl) +static NTSTATUS cvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -245,7 +245,7 @@ static NTSTATUS cvfs_unlink(struct request_context *req, struct smb_unlink *unl) static void async_ioctl(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_ioctl_recv(c_req, req->mem_ctx, async->parms); req->async.send_fn(req); } @@ -253,7 +253,7 @@ static void async_ioctl(struct cli_request *c_req) /* ioctl interface */ -static NTSTATUS cvfs_ioctl(struct request_context *req, union smb_ioctl *io) +static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -272,7 +272,7 @@ static NTSTATUS cvfs_ioctl(struct request_context *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS cvfs_chkpath(struct request_context *req, struct smb_chkpath *cp) +static NTSTATUS cvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -292,7 +292,7 @@ static NTSTATUS cvfs_chkpath(struct request_context *req, struct smb_chkpath *cp static void async_qpathinfo(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_pathinfo_recv(c_req, req->mem_ctx, async->parms); req->async.send_fn(req); } @@ -300,7 +300,7 @@ static void async_qpathinfo(struct cli_request *c_req) /* return info on a pathname */ -static NTSTATUS cvfs_qpathinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS cvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -320,7 +320,7 @@ static NTSTATUS cvfs_qpathinfo(struct request_context *req, union smb_fileinfo * static void async_qfileinfo(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_fileinfo_recv(c_req, req->mem_ctx, async->parms); req->async.send_fn(req); } @@ -328,7 +328,7 @@ static void async_qfileinfo(struct cli_request *c_req) /* query info on a open file */ -static NTSTATUS cvfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -346,7 +346,7 @@ static NTSTATUS cvfs_qfileinfo(struct request_context *req, union smb_fileinfo * /* set info on a pathname */ -static NTSTATUS cvfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +static NTSTATUS cvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -367,7 +367,7 @@ static NTSTATUS cvfs_setpathinfo(struct request_context *req, union smb_setfilei static void async_open(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_open_recv(c_req, req->mem_ctx, async->parms); req->async.send_fn(req); } @@ -375,7 +375,7 @@ static void async_open(struct cli_request *c_req) /* open a file */ -static NTSTATUS cvfs_open(struct request_context *req, union smb_open *io) +static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -397,7 +397,7 @@ static NTSTATUS cvfs_open(struct request_context *req, union smb_open *io) /* create a directory */ -static NTSTATUS cvfs_mkdir(struct request_context *req, union smb_mkdir *md) +static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -414,7 +414,7 @@ static NTSTATUS cvfs_mkdir(struct request_context *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS cvfs_rmdir(struct request_context *req, struct smb_rmdir *rd) +static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -430,7 +430,7 @@ static NTSTATUS cvfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS cvfs_rename(struct request_context *req, union smb_rename *ren) +static NTSTATUS cvfs_rename(struct smbsrv_request *req, union smb_rename *ren) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -447,7 +447,7 @@ static NTSTATUS cvfs_rename(struct request_context *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS cvfs_copy(struct request_context *req, struct smb_copy *cp) +static NTSTATUS cvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -458,7 +458,7 @@ static NTSTATUS cvfs_copy(struct request_context *req, struct smb_copy *cp) static void async_read(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_read_recv(c_req, async->parms); req->async.send_fn(req); } @@ -466,7 +466,7 @@ static void async_read(struct cli_request *c_req) /* read from a file */ -static NTSTATUS cvfs_read(struct request_context *req, union smb_read *rd) +static NTSTATUS cvfs_read(struct smbsrv_request *req, union smb_read *rd) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -486,7 +486,7 @@ static NTSTATUS cvfs_read(struct request_context *req, union smb_read *rd) static void async_write(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_write_recv(c_req, async->parms); req->async.send_fn(req); } @@ -494,7 +494,7 @@ static void async_write(struct cli_request *c_req) /* write to a file */ -static NTSTATUS cvfs_write(struct request_context *req, union smb_write *wr) +static NTSTATUS cvfs_write(struct smbsrv_request *req, union smb_write *wr) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -511,7 +511,7 @@ static NTSTATUS cvfs_write(struct request_context *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS cvfs_seek(struct request_context *req, struct smb_seek *io) +static NTSTATUS cvfs_seek(struct smbsrv_request *req, struct smb_seek *io) { return NT_STATUS_NOT_SUPPORTED; } @@ -519,7 +519,7 @@ static NTSTATUS cvfs_seek(struct request_context *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS cvfs_flush(struct request_context *req, struct smb_flush *io) +static NTSTATUS cvfs_flush(struct smbsrv_request *req, struct smb_flush *io) { return NT_STATUS_OK; } @@ -527,7 +527,7 @@ static NTSTATUS cvfs_flush(struct request_context *req, struct smb_flush *io) /* close a file */ -static NTSTATUS cvfs_close(struct request_context *req, union smb_close *io) +static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -544,7 +544,7 @@ static NTSTATUS cvfs_close(struct request_context *req, union smb_close *io) /* exit - closing files? */ -static NTSTATUS cvfs_exit(struct request_context *req) +static NTSTATUS cvfs_exit(struct smbsrv_request *req) { return NT_STATUS_NOT_SUPPORTED; } @@ -552,7 +552,7 @@ static NTSTATUS cvfs_exit(struct request_context *req) /* lock a byte range */ -static NTSTATUS cvfs_lock(struct request_context *req, union smb_lock *lck) +static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -568,7 +568,7 @@ static NTSTATUS cvfs_lock(struct request_context *req, union smb_lock *lck) /* set info on a open file */ -static NTSTATUS cvfs_setfileinfo(struct request_context *req, +static NTSTATUS cvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { struct cvfs_private *private = req->tcon->ntvfs_private; @@ -589,7 +589,7 @@ static NTSTATUS cvfs_setfileinfo(struct request_context *req, static void async_fsinfo(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_fsinfo_recv(c_req, req->mem_ctx, async->parms); req->async.send_fn(req); } @@ -597,7 +597,7 @@ static void async_fsinfo(struct cli_request *c_req) /* return filesystem space info */ -static NTSTATUS cvfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) +static NTSTATUS cvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -614,7 +614,7 @@ static NTSTATUS cvfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) /* return print queue info */ -static NTSTATUS cvfs_lpq(struct request_context *req, union smb_lpq *lpq) +static NTSTATUS cvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -622,7 +622,7 @@ static NTSTATUS cvfs_lpq(struct request_context *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -static NTSTATUS cvfs_search_first(struct request_context *req, union smb_search_first *io, +static NTSTATUS cvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -632,7 +632,7 @@ static NTSTATUS cvfs_search_first(struct request_context *req, union smb_search_ } /* continue a search */ -static NTSTATUS cvfs_search_next(struct request_context *req, union smb_search_next *io, +static NTSTATUS cvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -642,7 +642,7 @@ static NTSTATUS cvfs_search_next(struct request_context *req, union smb_search_n } /* close a search */ -static NTSTATUS cvfs_search_close(struct request_context *req, union smb_search_close *io) +static NTSTATUS cvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { struct cvfs_private *private = req->tcon->ntvfs_private; @@ -655,13 +655,13 @@ static NTSTATUS cvfs_search_close(struct request_context *req, union smb_search_ static void async_trans2(struct cli_request *c_req) { struct async_info *async = c_req->async.private; - struct request_context *req = async->req; + struct smbsrv_request *req = async->req; req->async.status = smb_raw_trans2_recv(c_req, req->mem_ctx, async->parms); req->async.send_fn(req); } /* raw trans2 */ -static NTSTATUS cvfs_trans2(struct request_context *req, struct smb_trans2 *trans2) +static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) { struct cvfs_private *private = req->tcon->ntvfs_private; struct cli_request *c_req; @@ -677,7 +677,7 @@ static NTSTATUS cvfs_trans2(struct request_context *req, struct smb_trans2 *tran /* SMBtrans - not used on file shares */ -static NTSTATUS cvfs_trans(struct request_context *req, struct smb_trans2 *trans2) +static NTSTATUS cvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b726dd6116..8d3eaa2bb4 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -105,7 +105,7 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t /* connect to a share - always works */ -static NTSTATUS ipc_connect(struct request_context *req, const char *sharename) +static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; @@ -145,7 +145,7 @@ static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon) /* delete a file */ -static NTSTATUS ipc_unlink(struct request_context *req, struct smb_unlink *unl) +static NTSTATUS ipc_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } @@ -154,7 +154,7 @@ static NTSTATUS ipc_unlink(struct request_context *req, struct smb_unlink *unl) /* ioctl interface - we don't do any */ -static NTSTATUS ipc_ioctl(struct request_context *req, union smb_ioctl *io) +static NTSTATUS ipc_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { return NT_STATUS_ACCESS_DENIED; } @@ -162,7 +162,7 @@ static NTSTATUS ipc_ioctl(struct request_context *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS ipc_chkpath(struct request_context *req, struct smb_chkpath *cp) +static NTSTATUS ipc_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { return NT_STATUS_ACCESS_DENIED; } @@ -170,7 +170,7 @@ static NTSTATUS ipc_chkpath(struct request_context *req, struct smb_chkpath *cp) /* return info on a pathname */ -static NTSTATUS ipc_qpathinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS ipc_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -178,7 +178,7 @@ static NTSTATUS ipc_qpathinfo(struct request_context *req, union smb_fileinfo *i /* set info on a pathname */ -static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +static NTSTATUS ipc_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { return NT_STATUS_ACCESS_DENIED; } @@ -188,7 +188,7 @@ static NTSTATUS ipc_setpathinfo(struct request_context *req, union smb_setfilein /* open a file backend - used for MSRPC pipes */ -static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, +static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, struct pipe_state **ps) { struct pipe_state *p; @@ -270,7 +270,7 @@ static NTSTATUS ipc_open_generic(struct request_context *req, const char *fname, /* open a file with ntcreatex - used for MSRPC pipes */ -static NTSTATUS ipc_open_ntcreatex(struct request_context *req, union smb_open *oi) +static NTSTATUS ipc_open_ntcreatex(struct smbsrv_request *req, union smb_open *oi) { struct pipe_state *p; NTSTATUS status; @@ -290,7 +290,7 @@ static NTSTATUS ipc_open_ntcreatex(struct request_context *req, union smb_open * /* open a file with openx - used for MSRPC pipes */ -static NTSTATUS ipc_open_openx(struct request_context *req, union smb_open *oi) +static NTSTATUS ipc_open_openx(struct smbsrv_request *req, union smb_open *oi) { struct pipe_state *p; NTSTATUS status; @@ -318,7 +318,7 @@ static NTSTATUS ipc_open_openx(struct request_context *req, union smb_open *oi) /* open a file - used for MSRPC pipes */ -static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) +static NTSTATUS ipc_open(struct smbsrv_request *req, union smb_open *oi) { NTSTATUS status; @@ -340,7 +340,7 @@ static NTSTATUS ipc_open(struct request_context *req, union smb_open *oi) /* create a directory */ -static NTSTATUS ipc_mkdir(struct request_context *req, union smb_mkdir *md) +static NTSTATUS ipc_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { return NT_STATUS_ACCESS_DENIED; } @@ -348,7 +348,7 @@ static NTSTATUS ipc_mkdir(struct request_context *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS ipc_rmdir(struct request_context *req, struct smb_rmdir *rd) +static NTSTATUS ipc_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { return NT_STATUS_ACCESS_DENIED; } @@ -356,7 +356,7 @@ static NTSTATUS ipc_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS ipc_rename(struct request_context *req, union smb_rename *ren) +static NTSTATUS ipc_rename(struct smbsrv_request *req, union smb_rename *ren) { return NT_STATUS_ACCESS_DENIED; } @@ -364,7 +364,7 @@ static NTSTATUS ipc_rename(struct request_context *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS ipc_copy(struct request_context *req, struct smb_copy *cp) +static NTSTATUS ipc_copy(struct smbsrv_request *req, struct smb_copy *cp) { return NT_STATUS_ACCESS_DENIED; } @@ -372,7 +372,7 @@ static NTSTATUS ipc_copy(struct request_context *req, struct smb_copy *cp) /* read from a file */ -static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) +static NTSTATUS ipc_read(struct smbsrv_request *req, union smb_read *rd) { struct ipc_private *private = req->tcon->ntvfs_private; DATA_BLOB data; @@ -424,7 +424,7 @@ static NTSTATUS ipc_read(struct request_context *req, union smb_read *rd) /* write to a file */ -static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr) +static NTSTATUS ipc_write(struct smbsrv_request *req, union smb_write *wr) { struct ipc_private *private = req->tcon->ntvfs_private; DATA_BLOB data; @@ -477,7 +477,7 @@ static NTSTATUS ipc_write(struct request_context *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS ipc_seek(struct request_context *req, struct smb_seek *io) +static NTSTATUS ipc_seek(struct smbsrv_request *req, struct smb_seek *io) { return NT_STATUS_ACCESS_DENIED; } @@ -485,7 +485,7 @@ static NTSTATUS ipc_seek(struct request_context *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS ipc_flush(struct request_context *req, struct smb_flush *io) +static NTSTATUS ipc_flush(struct smbsrv_request *req, struct smb_flush *io) { return NT_STATUS_ACCESS_DENIED; } @@ -493,7 +493,7 @@ static NTSTATUS ipc_flush(struct request_context *req, struct smb_flush *io) /* close a file */ -static NTSTATUS ipc_close(struct request_context *req, union smb_close *io) +static NTSTATUS ipc_close(struct smbsrv_request *req, union smb_close *io) { struct ipc_private *private = req->tcon->ntvfs_private; struct pipe_state *p; @@ -516,7 +516,7 @@ static NTSTATUS ipc_close(struct request_context *req, union smb_close *io) /* exit - closing files? */ -static NTSTATUS ipc_exit(struct request_context *req) +static NTSTATUS ipc_exit(struct smbsrv_request *req) { return NT_STATUS_ACCESS_DENIED; } @@ -524,7 +524,7 @@ static NTSTATUS ipc_exit(struct request_context *req) /* lock a byte range */ -static NTSTATUS ipc_lock(struct request_context *req, union smb_lock *lck) +static NTSTATUS ipc_lock(struct smbsrv_request *req, union smb_lock *lck) { return NT_STATUS_ACCESS_DENIED; } @@ -532,7 +532,7 @@ static NTSTATUS ipc_lock(struct request_context *req, union smb_lock *lck) /* set info on a open file */ -static NTSTATUS ipc_setfileinfo(struct request_context *req, union smb_setfileinfo *info) +static NTSTATUS ipc_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -540,7 +540,7 @@ static NTSTATUS ipc_setfileinfo(struct request_context *req, union smb_setfilein /* query info on a open file */ -static NTSTATUS ipc_qfileinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS ipc_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -549,7 +549,7 @@ static NTSTATUS ipc_qfileinfo(struct request_context *req, union smb_fileinfo *i /* return filesystem info */ -static NTSTATUS ipc_fsinfo(struct request_context *req, union smb_fsinfo *fs) +static NTSTATUS ipc_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { return NT_STATUS_ACCESS_DENIED; } @@ -557,7 +557,7 @@ static NTSTATUS ipc_fsinfo(struct request_context *req, union smb_fsinfo *fs) /* return print queue info */ -static NTSTATUS ipc_lpq(struct request_context *req, union smb_lpq *lpq) +static NTSTATUS ipc_lpq(struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_ACCESS_DENIED; } @@ -565,7 +565,7 @@ static NTSTATUS ipc_lpq(struct request_context *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -NTSTATUS ipc_search_first(struct request_context *req, union smb_search_first *io, +NTSTATUS ipc_search_first(struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -575,7 +575,7 @@ NTSTATUS ipc_search_first(struct request_context *req, union smb_search_first *i /* continue listing files in a directory */ -NTSTATUS ipc_search_next(struct request_context *req, union smb_search_next *io, +NTSTATUS ipc_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -585,14 +585,14 @@ NTSTATUS ipc_search_next(struct request_context *req, union smb_search_next *io, /* end listing files in a directory */ -NTSTATUS ipc_search_close(struct request_context *req, union smb_search_close *io) +NTSTATUS ipc_search_close(struct smbsrv_request *req, union smb_search_close *io) { return NT_STATUS_ACCESS_DENIED; } /* SMBtrans - handle a DCERPC command */ -static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *trans) +static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *trans) { struct pipe_state *p; struct ipc_private *private = req->tcon->ntvfs_private; @@ -637,7 +637,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct request_context *req, struct smb_trans2 *t /* SMBtrans - set named pipe state */ -static NTSTATUS ipc_set_nm_pipe_state(struct request_context *req, struct smb_trans2 *trans) +static NTSTATUS ipc_set_nm_pipe_state(struct smbsrv_request *req, struct smb_trans2 *trans) { struct pipe_state *p; struct ipc_private *private = req->tcon->ntvfs_private; @@ -663,7 +663,7 @@ static NTSTATUS ipc_set_nm_pipe_state(struct request_context *req, struct smb_tr /* SMBtrans - used to provide access to SMB pipes */ -static NTSTATUS ipc_trans(struct request_context *req, struct smb_trans2 *trans) +static NTSTATUS ipc_trans(struct smbsrv_request *req, struct smb_trans2 *trans) { NTSTATUS status; diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 5e9fd430cc..dceaa9f45b 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -90,7 +90,7 @@ static void nbench_log(struct nbench_private *private, /* connect to a share - used when a tree_connect operation comes in. */ -static NTSTATUS nbench_connect(struct request_context *req, const char *sharename) +static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename) { struct nbench_private *private; const char *passthru; @@ -146,7 +146,7 @@ static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon) delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS nbench_unlink(struct request_context *req, struct smb_unlink *unl) +static NTSTATUS nbench_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -163,7 +163,7 @@ static NTSTATUS nbench_unlink(struct request_context *req, struct smb_unlink *un /* ioctl interface */ -static NTSTATUS nbench_ioctl(struct request_context *req, union smb_ioctl *io) +static NTSTATUS nbench_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -178,7 +178,7 @@ static NTSTATUS nbench_ioctl(struct request_context *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS nbench_chkpath(struct request_context *req, struct smb_chkpath *cp) +static NTSTATUS nbench_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -195,7 +195,7 @@ static NTSTATUS nbench_chkpath(struct request_context *req, struct smb_chkpath * /* return info on a pathname */ -static NTSTATUS nbench_qpathinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS nbench_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -213,7 +213,7 @@ static NTSTATUS nbench_qpathinfo(struct request_context *req, union smb_fileinfo /* query info on a open file */ -static NTSTATUS nbench_qfileinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS nbench_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -232,7 +232,7 @@ static NTSTATUS nbench_qfileinfo(struct request_context *req, union smb_fileinfo /* set info on a pathname */ -static NTSTATUS nbench_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +static NTSTATUS nbench_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -250,7 +250,7 @@ static NTSTATUS nbench_setpathinfo(struct request_context *req, union smb_setfil /* open a file */ -static NTSTATUS nbench_open(struct request_context *req, union smb_open *io) +static NTSTATUS nbench_open(struct smbsrv_request *req, union smb_open *io) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -279,7 +279,7 @@ static NTSTATUS nbench_open(struct request_context *req, union smb_open *io) /* create a directory */ -static NTSTATUS nbench_mkdir(struct request_context *req, union smb_mkdir *md) +static NTSTATUS nbench_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -294,7 +294,7 @@ static NTSTATUS nbench_mkdir(struct request_context *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS nbench_rmdir(struct request_context *req, struct smb_rmdir *rd) +static NTSTATUS nbench_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -311,7 +311,7 @@ static NTSTATUS nbench_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS nbench_rename(struct request_context *req, union smb_rename *ren) +static NTSTATUS nbench_rename(struct smbsrv_request *req, union smb_rename *ren) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -338,7 +338,7 @@ static NTSTATUS nbench_rename(struct request_context *req, union smb_rename *ren /* copy a set of files */ -static NTSTATUS nbench_copy(struct request_context *req, struct smb_copy *cp) +static NTSTATUS nbench_copy(struct smbsrv_request *req, struct smb_copy *cp) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -353,7 +353,7 @@ static NTSTATUS nbench_copy(struct request_context *req, struct smb_copy *cp) /* read from a file */ -static NTSTATUS nbench_read(struct request_context *req, union smb_read *rd) +static NTSTATUS nbench_read(struct smbsrv_request *req, union smb_read *rd) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -381,7 +381,7 @@ static NTSTATUS nbench_read(struct request_context *req, union smb_read *rd) /* write to a file */ -static NTSTATUS nbench_write(struct request_context *req, union smb_write *wr) +static NTSTATUS nbench_write(struct smbsrv_request *req, union smb_write *wr) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -419,7 +419,7 @@ static NTSTATUS nbench_write(struct request_context *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS nbench_seek(struct request_context *req, struct smb_seek *io) +static NTSTATUS nbench_seek(struct smbsrv_request *req, struct smb_seek *io) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -434,7 +434,7 @@ static NTSTATUS nbench_seek(struct request_context *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS nbench_flush(struct request_context *req, struct smb_flush *io) +static NTSTATUS nbench_flush(struct smbsrv_request *req, struct smb_flush *io) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -451,7 +451,7 @@ static NTSTATUS nbench_flush(struct request_context *req, struct smb_flush *io) /* close a file */ -static NTSTATUS nbench_close(struct request_context *req, union smb_close *io) +static NTSTATUS nbench_close(struct smbsrv_request *req, union smb_close *io) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -477,7 +477,7 @@ static NTSTATUS nbench_close(struct request_context *req, union smb_close *io) /* exit - closing files */ -static NTSTATUS nbench_exit(struct request_context *req) +static NTSTATUS nbench_exit(struct smbsrv_request *req) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -490,7 +490,7 @@ static NTSTATUS nbench_exit(struct request_context *req) /* lock a byte range */ -static NTSTATUS nbench_lock(struct request_context *req, union smb_lock *lck) +static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -522,7 +522,7 @@ static NTSTATUS nbench_lock(struct request_context *req, union smb_lock *lck) /* set info on a open file */ -static NTSTATUS nbench_setfileinfo(struct request_context *req, +static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { struct nbench_private *private = req->tcon->ntvfs_private; @@ -542,7 +542,7 @@ static NTSTATUS nbench_setfileinfo(struct request_context *req, /* return filesystem space info */ -static NTSTATUS nbench_fsinfo(struct request_context *req, union smb_fsinfo *fs) +static NTSTATUS nbench_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -559,7 +559,7 @@ static NTSTATUS nbench_fsinfo(struct request_context *req, union smb_fsinfo *fs) /* return print queue info */ -static NTSTATUS nbench_lpq(struct request_context *req, union smb_lpq *lpq) +static NTSTATUS nbench_lpq(struct smbsrv_request *req, union smb_lpq *lpq) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -574,7 +574,7 @@ static NTSTATUS nbench_lpq(struct request_context *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -static NTSTATUS nbench_search_first(struct request_context *req, union smb_search_first *io, +static NTSTATUS nbench_search_first(struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -602,7 +602,7 @@ static NTSTATUS nbench_search_first(struct request_context *req, union smb_searc } /* continue a search */ -static NTSTATUS nbench_search_next(struct request_context *req, union smb_search_next *io, +static NTSTATUS nbench_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -617,7 +617,7 @@ static NTSTATUS nbench_search_next(struct request_context *req, union smb_search } /* close a search */ -static NTSTATUS nbench_search_close(struct request_context *req, union smb_search_close *io) +static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search_close *io) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; @@ -630,7 +630,7 @@ static NTSTATUS nbench_search_close(struct request_context *req, union smb_searc } /* SMBtrans - not used on file shares */ -static NTSTATUS nbench_trans(struct request_context *req, struct smb_trans2 *trans2) +static NTSTATUS nbench_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) { struct nbench_private *private = req->tcon->ntvfs_private; NTSTATUS status; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index dd245b09ce..b7c110ebdb 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -30,50 +30,50 @@ struct ntvfs_ops { enum ntvfs_type type; /* initial setup */ - NTSTATUS (*connect)(struct request_context *req, const char *sharename); + NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename); NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon); /* path operations */ - NTSTATUS (*unlink)(struct request_context *req, struct smb_unlink *unl); - NTSTATUS (*chkpath)(struct request_context *req, struct smb_chkpath *cp); - NTSTATUS (*qpathinfo)(struct request_context *req, union smb_fileinfo *st); - NTSTATUS (*setpathinfo)(struct request_context *req, union smb_setfileinfo *st); - NTSTATUS (*open)(struct request_context *req, union smb_open *oi); - NTSTATUS (*mkdir)(struct request_context *req, union smb_mkdir *md); - NTSTATUS (*rmdir)(struct request_context *req, struct smb_rmdir *rd); - NTSTATUS (*rename)(struct request_context *req, union smb_rename *ren); - NTSTATUS (*copy)(struct request_context *req, struct smb_copy *cp); + NTSTATUS (*unlink)(struct smbsrv_request *req, struct smb_unlink *unl); + NTSTATUS (*chkpath)(struct smbsrv_request *req, struct smb_chkpath *cp); + NTSTATUS (*qpathinfo)(struct smbsrv_request *req, union smb_fileinfo *st); + NTSTATUS (*setpathinfo)(struct smbsrv_request *req, union smb_setfileinfo *st); + NTSTATUS (*open)(struct smbsrv_request *req, union smb_open *oi); + NTSTATUS (*mkdir)(struct smbsrv_request *req, union smb_mkdir *md); + NTSTATUS (*rmdir)(struct smbsrv_request *req, struct smb_rmdir *rd); + NTSTATUS (*rename)(struct smbsrv_request *req, union smb_rename *ren); + NTSTATUS (*copy)(struct smbsrv_request *req, struct smb_copy *cp); /* directory search */ - NTSTATUS (*search_first)(struct request_context *req, union smb_search_first *io, void *private, + NTSTATUS (*search_first)(struct smbsrv_request *req, union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)); - NTSTATUS (*search_next)(struct request_context *req, union smb_search_next *io, void *private, + NTSTATUS (*search_next)(struct smbsrv_request *req, union smb_search_next *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)); - NTSTATUS (*search_close)(struct request_context *req, union smb_search_close *io); + NTSTATUS (*search_close)(struct smbsrv_request *req, union smb_search_close *io); /* operations on open files */ - NTSTATUS (*ioctl)(struct request_context *req, union smb_ioctl *io); - NTSTATUS (*read)(struct request_context *req, union smb_read *io); - NTSTATUS (*write)(struct request_context *req, union smb_write *io); - NTSTATUS (*seek)(struct request_context *req, struct smb_seek *io); - NTSTATUS (*flush)(struct request_context *req, struct smb_flush *flush); - NTSTATUS (*close)(struct request_context *req, union smb_close *io); - NTSTATUS (*exit)(struct request_context *req); - NTSTATUS (*lock)(struct request_context *req, union smb_lock *lck); - NTSTATUS (*setfileinfo)(struct request_context *req, union smb_setfileinfo *info); - NTSTATUS (*qfileinfo)(struct request_context *req, union smb_fileinfo *info); + NTSTATUS (*ioctl)(struct smbsrv_request *req, union smb_ioctl *io); + NTSTATUS (*read)(struct smbsrv_request *req, union smb_read *io); + NTSTATUS (*write)(struct smbsrv_request *req, union smb_write *io); + NTSTATUS (*seek)(struct smbsrv_request *req, struct smb_seek *io); + NTSTATUS (*flush)(struct smbsrv_request *req, struct smb_flush *flush); + NTSTATUS (*close)(struct smbsrv_request *req, union smb_close *io); + NTSTATUS (*exit)(struct smbsrv_request *req); + NTSTATUS (*lock)(struct smbsrv_request *req, union smb_lock *lck); + NTSTATUS (*setfileinfo)(struct smbsrv_request *req, union smb_setfileinfo *info); + NTSTATUS (*qfileinfo)(struct smbsrv_request *req, union smb_fileinfo *info); /* filesystem operations */ - NTSTATUS (*fsinfo)(struct request_context *req, union smb_fsinfo *fs); + NTSTATUS (*fsinfo)(struct smbsrv_request *req, union smb_fsinfo *fs); /* printing specific operations */ - NTSTATUS (*lpq)(struct request_context *req, union smb_lpq *lpq); + NTSTATUS (*lpq)(struct smbsrv_request *req, union smb_lpq *lpq); /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ - NTSTATUS (*trans2)(struct request_context *req, struct smb_trans2 *trans2); + NTSTATUS (*trans2)(struct smbsrv_request *req, struct smb_trans2 *trans2); /* trans interface - used by IPC backend for pipes and RAP calls */ - NTSTATUS (*trans)(struct request_context *req, struct smb_trans2 *trans); + NTSTATUS (*trans)(struct smbsrv_request *req, struct smb_trans2 *trans); }; @@ -83,5 +83,5 @@ struct ntvfs_critical_sizes { int sizeof_ntvfs_ops; int sizeof_SMB_OFF_T; int sizeof_smbsrv_tcon; - int sizeof_request_context; + int sizeof_smbsrv_request; }; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index bb751bae01..f94dacb57f 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -103,7 +103,7 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) sizeof(struct ntvfs_ops), sizeof(SMB_OFF_T), sizeof(struct smbsrv_tcon), - sizeof(struct request_context), + sizeof(struct smbsrv_request), }; return &critical_sizes; @@ -133,7 +133,7 @@ BOOL ntvfs_init(void) /* initialise a connection structure to point at a NTVFS backend */ -NTSTATUS ntvfs_init_connection(struct request_context *req) +NTSTATUS ntvfs_init_connection(struct smbsrv_request *req) { const char *handler = lp_ntvfs_handler(req->tcon->service); diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index b2cf107b7d..ba2ec344f4 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -57,7 +57,7 @@ static BOOL is_exe_file(const char *fname) /* NTVFS open generic to any mapper */ -NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) +NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io) { NTSTATUS status; union smb_open io2; @@ -249,7 +249,7 @@ NTSTATUS ntvfs_map_open(struct request_context *req, union smb_open *io) /* NTVFS fsinfo generic to any mapper */ -NTSTATUS ntvfs_map_fsinfo(struct request_context *req, union smb_fsinfo *fs) +NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { NTSTATUS status; union smb_fsinfo fs2; @@ -368,7 +368,7 @@ NTSTATUS ntvfs_map_fsinfo(struct request_context *req, union smb_fsinfo *fs) /* NTVFS fileinfo generic to any mapper */ -NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *info, union smb_fileinfo *info2) +NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, union smb_fileinfo *info2) { int i; /* and convert it to the required level using results in info2 */ @@ -590,7 +590,7 @@ NTSTATUS ntvfs_map_fileinfo(struct request_context *req, union smb_fileinfo *inf /* NTVFS fileinfo generic to any mapper */ -NTSTATUS ntvfs_map_qfileinfo(struct request_context *req, union smb_fileinfo *info) +NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { NTSTATUS status; union smb_fileinfo info2; @@ -613,7 +613,7 @@ NTSTATUS ntvfs_map_qfileinfo(struct request_context *req, union smb_fileinfo *in /* NTVFS pathinfo generic to any mapper */ -NTSTATUS ntvfs_map_qpathinfo(struct request_context *req, union smb_fileinfo *info) +NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { NTSTATUS status; union smb_fileinfo info2; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e013e01979..90b6f9248d 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -31,7 +31,7 @@ directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS pvfs_connect(struct request_context *req, const char *sharename) +static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) { DEBUG(0, ("Connection to share [%s] ACCESS DENIED!\n", sharename)); DEBUGADD(0,("This is because your using the 'ntvfs handler = default'.\n")); diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index a2ac429458..fa5835843a 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -29,7 +29,7 @@ in. For printing shares this should check that the spool directory is available */ -static NTSTATUS print_connect(struct request_context *req, const char *sharename) +static NTSTATUS print_connect(struct smbsrv_request *req, const char *sharename) { return NT_STATUS_OK; } @@ -45,7 +45,7 @@ static NTSTATUS print_disconnect(struct smbsrv_tcon *tcon) /* lots of operations are not allowed on printing shares - mostly return NT_STATUS_ACCESS_DENIED */ -static NTSTATUS print_unlink(struct request_context *req, struct smb_unlink *unl) +static NTSTATUS print_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } @@ -54,7 +54,7 @@ static NTSTATUS print_unlink(struct request_context *req, struct smb_unlink *unl /* ioctl - used for job query */ -static NTSTATUS print_ioctl(struct request_context *req, union smb_ioctl *io) +static NTSTATUS print_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { char *p; diff --git a/source4/ntvfs/reference/ref_util.c b/source4/ntvfs/reference/ref_util.c index 75f3ac4948..e221086950 100644 --- a/source4/ntvfs/reference/ref_util.c +++ b/source4/ntvfs/reference/ref_util.c @@ -29,7 +29,7 @@ /* convert a windows path to a unix path - don't do any manging or case sensitive handling */ -char *svfs_unix_path(struct request_context *req, const char *name) +char *svfs_unix_path(struct smbsrv_request *req, const char *name) { struct svfs_private *private = req->conn->ntvfs_private; char *ret; @@ -52,7 +52,7 @@ char *svfs_unix_path(struct request_context *req, const char *name) returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, const char *pattern) +struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, const char *pattern) { char *unix_path; char *p, *mask; diff --git a/source4/ntvfs/reference/vfs_ref.c b/source4/ntvfs/reference/vfs_ref.c index 13b4eb5fbc..7a85afa4bb 100644 --- a/source4/ntvfs/reference/vfs_ref.c +++ b/source4/ntvfs/reference/vfs_ref.c @@ -35,7 +35,7 @@ directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) +static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) { struct stat st; struct tcon_context *conn = req->conn; @@ -63,7 +63,7 @@ static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS svfs_disconnect(struct request_context *req) +static NTSTATUS svfs_disconnect(struct smbsrv_request *req) { return NT_STATUS_OK; } @@ -72,7 +72,7 @@ static NTSTATUS svfs_disconnect(struct request_context *req) delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) +static NTSTATUS svfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { char *unix_path; @@ -90,7 +90,7 @@ static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) /* ioctl interface - we don't do any */ -static NTSTATUS svfs_ioctl(struct request_context *req, struct smb_ioctl *io) +static NTSTATUS svfs_ioctl(struct smbsrv_request *req, struct smb_ioctl *io) { return NT_STATUS_INVALID_PARAMETER; } @@ -98,7 +98,7 @@ static NTSTATUS svfs_ioctl(struct request_context *req, struct smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS svfs_chkpath(struct request_context *req, struct smb_chkpath *cp) +static NTSTATUS svfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { char *unix_path; struct stat st; @@ -119,7 +119,7 @@ static NTSTATUS svfs_chkpath(struct request_context *req, struct smb_chkpath *cp /* approximately map a struct stat to a fileinfo struct */ -static NTSTATUS map_fileinfo(struct request_context *req, union smb_fileinfo *info, struct stat *st) +static NTSTATUS map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, struct stat *st) { switch (info->generic.level) { case SMB_FILEINFO_NETWORK_OPEN_INFORMATION: @@ -222,7 +222,7 @@ static NTSTATUS map_fileinfo(struct request_context *req, union smb_fileinfo *in /* return info on a pathname */ -static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { char *unix_path; struct stat st; @@ -239,7 +239,7 @@ static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo * /* query info on a open file */ -static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct stat st; @@ -254,7 +254,7 @@ static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo * /* set info on a pathname */ -static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +static NTSTATUS svfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { return NT_STATUS_NOT_SUPPORTED; } @@ -262,7 +262,7 @@ static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfilei /* open a file */ -static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) +static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) { char *unix_path; struct stat st; @@ -342,7 +342,7 @@ static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) /* create a directory */ -static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md) +static NTSTATUS svfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { char *unix_path; @@ -362,7 +362,7 @@ static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) +static NTSTATUS svfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { char *unix_path; @@ -378,7 +378,7 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) +static NTSTATUS svfs_rename(struct smbsrv_request *req, union smb_rename *ren) { char *unix_path1, *unix_path2; @@ -395,7 +395,7 @@ static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS svfs_copy(struct request_context *req, struct smb_copy *cp) +static NTSTATUS svfs_copy(struct smbsrv_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -403,7 +403,7 @@ static NTSTATUS svfs_copy(struct request_context *req, struct smb_copy *cp) /* read from a file */ -static NTSTATUS svfs_read(struct request_context *req, union smb_read *rd) +static NTSTATUS svfs_read(struct smbsrv_request *req, union smb_read *rd) { ssize_t ret; @@ -428,7 +428,7 @@ static NTSTATUS svfs_read(struct request_context *req, union smb_read *rd) /* write to a file */ -static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr) +static NTSTATUS svfs_write(struct smbsrv_request *req, union smb_write *wr) { ssize_t ret; @@ -472,7 +472,7 @@ static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS svfs_seek(struct request_context *req, struct smb_seek *io) +static NTSTATUS svfs_seek(struct smbsrv_request *req, struct smb_seek *io) { return NT_STATUS_NOT_SUPPORTED; } @@ -480,7 +480,7 @@ static NTSTATUS svfs_seek(struct request_context *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) +static NTSTATUS svfs_flush(struct smbsrv_request *req, struct smb_flush *io) { fsync(io->in.fnum); return NT_STATUS_OK; @@ -489,7 +489,7 @@ static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) /* close a file */ -static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) +static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io) { if (io->generic.level != SMB_CLOSE_CLOSE) { /* we need a mapping function */ @@ -506,7 +506,7 @@ static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) /* exit - closing files? */ -static NTSTATUS svfs_exit(struct request_context *req) +static NTSTATUS svfs_exit(struct smbsrv_request *req) { return NT_STATUS_NOT_SUPPORTED; } @@ -514,7 +514,7 @@ static NTSTATUS svfs_exit(struct request_context *req) /* lock a byte range */ -static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck) +static NTSTATUS svfs_lock(struct smbsrv_request *req, union smb_lock *lck) { DEBUG(0,("REWRITE: not doing byte range locking!\n")); return NT_STATUS_OK; @@ -523,7 +523,7 @@ static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck) /* set info on a open file */ -static NTSTATUS svfs_setfileinfo(struct request_context *req, +static NTSTATUS svfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { DEBUG(0,("REWRITE: svfs_setfileinfo: not doing setfileinfo level %d\n", @@ -549,7 +549,7 @@ static NTSTATUS svfs_setfileinfo(struct request_context *req, /* return filesystem space info */ -static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) +static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { struct svfs_private *private = req->conn->ntvfs_private; @@ -571,7 +571,7 @@ static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) /* return filesystem attribute info */ -static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) +static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs) { struct stat st; struct svfs_private *private = req->conn->ntvfs_private; @@ -601,7 +601,7 @@ static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) /* return print queue info */ -static NTSTATUS svfs_lpq(struct request_context *req, union smb_lpq *lpq) +static NTSTATUS svfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -609,7 +609,7 @@ static NTSTATUS svfs_lpq(struct request_context *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -NTSTATUS svfs_search_first(struct request_context *req, union smb_search_first *io, +NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -683,7 +683,7 @@ NTSTATUS svfs_search_first(struct request_context *req, union smb_search_first * } /* continue a search */ -NTSTATUS svfs_search_next(struct request_context *req, union smb_search_next *io, +NTSTATUS svfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -770,7 +770,7 @@ found: } /* close a search */ -NTSTATUS svfs_search_close(struct request_context *req, union smb_search_close *io) +NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { struct svfs_private *private = req->conn->ntvfs_private; struct search_state *search; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 0f0555ac18..7da9667e3c 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -29,7 +29,7 @@ /* convert a windows path to a unix path - don't do any manging or case sensitive handling */ -char *svfs_unix_path(struct request_context *req, const char *name) +char *svfs_unix_path(struct smbsrv_request *req, const char *name) { struct svfs_private *private = req->tcon->ntvfs_private; char *ret; @@ -52,7 +52,7 @@ char *svfs_unix_path(struct request_context *req, const char *name) returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct request_context *req, const char *unix_path) +struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, const char *unix_path) { char *p, *mask; struct svfs_dir *dir; @@ -135,7 +135,7 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct request_context *req returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct request_context *req, const char *pattern) +struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, const char *pattern) { char *unix_path; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 013419e4ee..ad889daf36 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -61,7 +61,7 @@ static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offs directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS svfs_connect(struct request_context *req, const char *sharename) +static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) { struct stat st; struct smbsrv_tcon *tcon = req->tcon; @@ -116,7 +116,7 @@ static struct svfs_file *find_fd(struct svfs_private *private, int fd) delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) +static NTSTATUS svfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { char *unix_path; @@ -136,7 +136,7 @@ static NTSTATUS svfs_unlink(struct request_context *req, struct smb_unlink *unl) /* ioctl interface - we don't do any */ -static NTSTATUS svfs_ioctl(struct request_context *req, union smb_ioctl *io) +static NTSTATUS svfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { return NT_STATUS_INVALID_PARAMETER; } @@ -144,7 +144,7 @@ static NTSTATUS svfs_ioctl(struct request_context *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS svfs_chkpath(struct request_context *req, struct smb_chkpath *cp) +static NTSTATUS svfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { char *unix_path; struct stat st; @@ -165,7 +165,7 @@ static NTSTATUS svfs_chkpath(struct request_context *req, struct smb_chkpath *cp /* approximately map a struct stat to a generic fileinfo struct */ -static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinfo *info, +static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, struct stat *st, const char *unix_path) { struct svfs_dir *dir = NULL; @@ -241,7 +241,7 @@ static NTSTATUS svfs_map_fileinfo(struct request_context *req, union smb_fileinf /* return info on a pathname */ -static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { char *unix_path; struct stat st; @@ -266,7 +266,7 @@ static NTSTATUS svfs_qpathinfo(struct request_context *req, union smb_fileinfo * /* query info on a open file */ -static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo *info) +static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct svfs_private *private = req->tcon->ntvfs_private; struct svfs_file *f; @@ -294,7 +294,7 @@ static NTSTATUS svfs_qfileinfo(struct request_context *req, union smb_fileinfo * /* open a file */ -static NTSTATUS svfs_open(struct request_context *req, union smb_open *io) +static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) { struct svfs_private *private = req->tcon->ntvfs_private; char *unix_path; @@ -400,7 +400,7 @@ do_open: /* create a directory */ -static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md) +static NTSTATUS svfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { char *unix_path; @@ -422,7 +422,7 @@ static NTSTATUS svfs_mkdir(struct request_context *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) +static NTSTATUS svfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { char *unix_path; @@ -440,7 +440,7 @@ static NTSTATUS svfs_rmdir(struct request_context *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) +static NTSTATUS svfs_rename(struct smbsrv_request *req, union smb_rename *ren) { char *unix_path1, *unix_path2; @@ -463,7 +463,7 @@ static NTSTATUS svfs_rename(struct request_context *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS svfs_copy(struct request_context *req, struct smb_copy *cp) +static NTSTATUS svfs_copy(struct smbsrv_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -471,7 +471,7 @@ static NTSTATUS svfs_copy(struct request_context *req, struct smb_copy *cp) /* read from a file */ -static NTSTATUS svfs_read(struct request_context *req, union smb_read *rd) +static NTSTATUS svfs_read(struct smbsrv_request *req, union smb_read *rd) { ssize_t ret; @@ -497,7 +497,7 @@ static NTSTATUS svfs_read(struct request_context *req, union smb_read *rd) /* write to a file */ -static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr) +static NTSTATUS svfs_write(struct smbsrv_request *req, union smb_write *wr) { ssize_t ret; @@ -543,7 +543,7 @@ static NTSTATUS svfs_write(struct request_context *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS svfs_seek(struct request_context *req, struct smb_seek *io) +static NTSTATUS svfs_seek(struct smbsrv_request *req, struct smb_seek *io) { return NT_STATUS_NOT_SUPPORTED; } @@ -551,7 +551,7 @@ static NTSTATUS svfs_seek(struct request_context *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) +static NTSTATUS svfs_flush(struct smbsrv_request *req, struct smb_flush *io) { fsync(io->in.fnum); return NT_STATUS_OK; @@ -560,7 +560,7 @@ static NTSTATUS svfs_flush(struct request_context *req, struct smb_flush *io) /* close a file */ -static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) +static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io) { struct svfs_private *private = req->tcon->ntvfs_private; struct svfs_file *f; @@ -589,7 +589,7 @@ static NTSTATUS svfs_close(struct request_context *req, union smb_close *io) /* exit - closing files? */ -static NTSTATUS svfs_exit(struct request_context *req) +static NTSTATUS svfs_exit(struct smbsrv_request *req) { return NT_STATUS_NOT_SUPPORTED; } @@ -597,7 +597,7 @@ static NTSTATUS svfs_exit(struct request_context *req) /* lock a byte range */ -static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck) +static NTSTATUS svfs_lock(struct smbsrv_request *req, union smb_lock *lck) { DEBUG(0,("REWRITE: not doing byte range locking!\n")); return NT_STATUS_OK; @@ -606,7 +606,7 @@ static NTSTATUS svfs_lock(struct request_context *req, union smb_lock *lck) /* set info on a pathname */ -static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfileinfo *st) +static NTSTATUS svfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { CHECK_READ_ONLY(req); @@ -616,7 +616,7 @@ static NTSTATUS svfs_setpathinfo(struct request_context *req, union smb_setfilei /* set info on a open file */ -static NTSTATUS svfs_setfileinfo(struct request_context *req, +static NTSTATUS svfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { struct utimbuf unix_times; @@ -659,7 +659,7 @@ static NTSTATUS svfs_setfileinfo(struct request_context *req, /* return filesystem space info */ -static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) +static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { struct svfs_private *private = req->tcon->ntvfs_private; struct stat st; @@ -700,7 +700,7 @@ static NTSTATUS svfs_fsinfo(struct request_context *req, union smb_fsinfo *fs) /* return filesystem attribute info */ -static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) +static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs) { struct stat st; struct svfs_private *private = req->tcon->ntvfs_private; @@ -731,7 +731,7 @@ static NTSTATUS svfs_fsattr(struct request_context *req, union smb_fsattr *fs) /* return print queue info */ -static NTSTATUS svfs_lpq(struct request_context *req, union smb_lpq *lpq) +static NTSTATUS svfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -739,7 +739,7 @@ static NTSTATUS svfs_lpq(struct request_context *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -static NTSTATUS svfs_search_first(struct request_context *req, union smb_search_first *io, +static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -813,7 +813,7 @@ static NTSTATUS svfs_search_first(struct request_context *req, union smb_search_ } /* continue a search */ -static NTSTATUS svfs_search_next(struct request_context *req, union smb_search_next *io, +static NTSTATUS svfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -900,7 +900,7 @@ found: } /* close a search */ -static NTSTATUS svfs_search_close(struct request_context *req, union smb_search_close *io) +static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { struct svfs_private *private = req->tcon->ntvfs_private; struct search_state *search; @@ -921,7 +921,7 @@ static NTSTATUS svfs_search_close(struct request_context *req, union smb_search_ } /* SMBtrans - not used on file shares */ -static NTSTATUS svfs_trans(struct request_context *req, struct smb_trans2 *trans2) +static NTSTATUS svfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } -- cgit From b87fa55bdc69fe50743ddb58977e408853abb4cb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 28 Jun 2004 11:10:24 +0000 Subject: r1286: rename struct tcon_context to smbsrv_tcon metze (This used to be commit a6c0ca9de52b2395b092cb245bb94cbd55dfdd46) --- source4/ntvfs/posix/vfs_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 90b6f9248d..cfbb892d9c 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -48,7 +48,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS pvfs_disconnect(struct tcon_context *tcon) +static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon) { return NT_STATUS_OK; } -- cgit From 118f3edd27f5adacc1da636ed05b33f04999584f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 29 Jun 2004 07:40:14 +0000 Subject: r1291: rename struct smbsrv_context to smbsrv_connection because this is the connection state per transport layer (tcp) connection I also moved the substructs directly into smbsrv_connection, because they don't need a struct name and we should allway pass the complete smbsrv_connection struct into functions metze (This used to be commit 60f823f201fcedf5473008e8453a6351e73a92c7) --- source4/ntvfs/cifs/vfs_cifs.c | 8 ++++---- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/ntvfs_generic.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index b0389b9e59..93b9f2630e 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -51,8 +51,8 @@ struct async_info { static void idle_func(struct cli_transport *transport, void *p_private) { struct cvfs_private *private = p_private; - if (socket_pending(private->tcon->smb_ctx->socket.fd)) { - smbd_process_async(private->tcon->smb_ctx); + if (socket_pending(private->tcon->smb_conn->socket.fd)) { + smbd_process_async(private->tcon->smb_conn); } } @@ -164,7 +164,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) fde.private = private; fde.handler = cifs_socket_handler; - event_add_fd(tcon->smb_ctx->events, &fde); + event_add_fd(tcon->smb_conn->events, &fde); /* we need to receive oplock break requests from the server */ cli_oplock_handler(private->transport, oplock_handler, private); @@ -180,7 +180,7 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) { struct cvfs_private *private = tcon->ntvfs_private; - event_remove_fd_all(tcon->smb_ctx->events, private->transport->socket->fd); + event_remove_fd_all(tcon->smb_conn->events, private->transport->socket->fd); smb_tree_disconnect(private->tree); cli_tree_close(private->tree); diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 8d3eaa2bb4..cf8b49ebb8 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -249,7 +249,7 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, session_info = req->user_ctx->vuser->session_info; } - status = dcesrv_endpoint_search_connect(&req->smb_ctx->dcesrv, + status = dcesrv_endpoint_search_connect(&req->smb_conn->dcesrv, &ep_description, session_info, &p->dce_conn); diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index ba2ec344f4..36cbcabbd5 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -290,7 +290,7 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) (fs2.generic.out.blocks_free * (double)fs2.generic.out.block_size) / (bpunit * 512); /* we must return a maximum of 2G to old DOS systems, or they get very confused */ - if (bpunit > 64 && req->smb_ctx->negotiate.protocol <= PROTOCOL_LANMAN2) { + if (bpunit > 64 && req->smb_conn->negotiate.protocol <= PROTOCOL_LANMAN2) { fs->dskattr.out.blocks_per_unit = 64; fs->dskattr.out.units_total = 0xFFFF; fs->dskattr.out.units_free = 0xFFFF; -- cgit From dc9f55dbec5f892b39d924d5fd033b5eec1e14e4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 29 Jun 2004 09:40:10 +0000 Subject: r1294: A nice, large, commit... This implements gensec for Samba's server side, and brings gensec up to the standards of a full subsystem. This means that use of the subsystem is by gensec_* functions, not function pointers in structures (this is internal). This causes changes in all the existing gensec users. Our RPC server no longer contains it's own generalised security scheme, and now calls gensec directly. Gensec has also taken over the role of auth/auth_ntlmssp.c An important part of gensec, is the output of the 'session_info' struct. This is now reference counted, so that we can correctly free it when a pipe is closed, no matter if it was inherited, or created by per-pipe authentication. The schannel code is reworked, to be in the same file for client and server. ntlm_auth is reworked to use gensec. The major problem with this code is the way it relies on subsystem auto-initialisation. The primary reason for this commit now.is to allow these problems to be looked at, and fixed. There are problems with the new code: - I've tested it with smbtorture, but currently don't have VMware and valgrind working (this I'll fix soon). - The SPNEGO code is client-only at this point. - We still do not do kerberos. Andrew Bartlett (This used to be commit 07fd885fd488fd1051eacc905a2d4962f8a018ec) --- source4/ntvfs/ipc/vfs_ipc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index cf8b49ebb8..f6a0015f1d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -243,9 +243,9 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, /* tell the RPC layer the session_info */ if (req->user_ctx->vuser) { - /* - * TODO: we need to reference count the entire session_info - */ + /* The session info is refcount-increased in the + dcesrv_endpoint_search_connect() function */ + session_info = req->user_ctx->vuser->session_info; } -- cgit From d9f4a8328e851a6dfc2bb064c0fd6805ec54b9a8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Jul 2004 02:54:06 +0000 Subject: r1355: Add const (I missed this when I changed the function prototype earlier) Andrew Bartlett (This used to be commit dbe484a0c2c1ef99b71621208fb3fec68fe4fada) --- source4/ntvfs/ntvfs_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index f94dacb57f..923a131d5e 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -42,7 +42,7 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -static NTSTATUS ntvfs_register(void *_ops) +static NTSTATUS ntvfs_register(const void *_ops) { const struct ntvfs_ops *ops = _ops; struct ntvfs_ops *new_ops; -- cgit From 3a6f761eb061d93837038f0aa75c2ffcb0ba3639 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Jul 2004 16:35:48 +0000 Subject: r1470: Get the smb_trans2 structure out of the rap_cli_call struct. Initial attempt at RAP server infrastructure. Look at rap_server.c for the dummy functions that are supposed to implement the core functionality. ipc_rap.c contains all the data shuffling. _rap_shareenum and _rap_serverenum2 in ipc_rap.c are (I think) regular enough to be auto-generated. I did not test all the corner cases yet, but nevertheless I would like some comments on the general style. Volker P.S: samba-3 smbclient now doesn't freak out anymore, although the results are not entirely correct :-) (This used to be commit 08140cc1a838b4eaa23c897b280a46c95b7ef3e0) --- source4/ntvfs/config.mk | 5 +- source4/ntvfs/ipc/ipc_rap.c | 463 +++++++++++++++++++++++++++++++++++++++++ source4/ntvfs/ipc/rap_server.c | 54 +++++ source4/ntvfs/ipc/vfs_ipc.c | 3 + 4 files changed, 524 insertions(+), 1 deletion(-) create mode 100644 source4/ntvfs/ipc/ipc_rap.c create mode 100644 source4/ntvfs/ipc/rap_server.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 0feb380824..25dd51b487 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -32,7 +32,10 @@ INIT_OBJ_FILES = \ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] INIT_OBJ_FILES = \ - ntvfs/ipc/vfs_ipc.o + ntvfs/ipc/vfs_ipc.o \ + ntvfs/ipc/ipc_rap.o \ + ntvfs/ipc/rap_server.o + # End MODULE ntvfs_ipc ################################################ diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c new file mode 100644 index 0000000000..d2cd0b38d5 --- /dev/null +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -0,0 +1,463 @@ +/* + Unix SMB/CIFS implementation. + RAP handlers + + Copyright (C) Volker Lendecke 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#define NERR_Success 0 +#define NERR_badpass 86 +#define NERR_notsupported 50 + +struct rap_string_heap { + TALLOC_CTX *mem_ctx; + int offset; + int num_strings; + const char **strings; +}; + +struct rap_heap_save { + int offset, num_strings; +}; + +static void rap_heap_save(struct rap_string_heap *heap, + struct rap_heap_save *save) +{ + save->offset = heap->offset; + save->num_strings = heap->num_strings; +} + +static void rap_heap_restore(struct rap_string_heap *heap, + struct rap_heap_save *save) +{ + heap->offset = save->offset; + heap->num_strings = save->num_strings; +} + +struct rap_call { + TALLOC_CTX *mem_ctx; + uint16 callno; + const char *paramdesc; + const char *datadesc; + + uint16 status; + uint16 convert; + + uint16 rcv_paramlen, rcv_datalen; + + struct ndr_push *ndr_push_param; + struct ndr_push *ndr_push_data; + struct rap_string_heap *heap; + + struct ndr_pull *ndr_pull_param; + struct ndr_pull *ndr_pull_data; +}; + +#define RAPNDR_FLAGS (LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); + +static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, + struct smb_trans2 *trans) +{ + struct rap_call *call; + + call = talloc_p(mem_ctx, struct rap_call); + + if (call == NULL) + return NULL; + + ZERO_STRUCTP(call); + + call->mem_ctx = mem_ctx; + + call->ndr_pull_param = ndr_pull_init_blob(&trans->in.params, mem_ctx); + call->ndr_pull_param->flags = RAPNDR_FLAGS; + + call->ndr_pull_data = ndr_pull_init_blob(&trans->in.data, mem_ctx); + call->ndr_pull_data->flags = RAPNDR_FLAGS; + + call->heap = talloc_p(mem_ctx, struct rap_string_heap); + + if (call->heap == NULL) + return NULL; + + ZERO_STRUCTP(call->heap); + + call->heap->mem_ctx = mem_ctx; + + return call; +} + +static NTSTATUS rap_srv_pull_word(struct rap_call *call, uint16 *result) +{ + if (*call->paramdesc++ != 'W') + return NT_STATUS_INVALID_PARAMETER; + + return ndr_pull_uint16(call->ndr_pull_param, result); +} + +static NTSTATUS rap_srv_pull_dword(struct rap_call *call, uint32 *result) +{ + if (*call->paramdesc++ != 'D') + return NT_STATUS_INVALID_PARAMETER; + + return ndr_pull_uint32(call->ndr_pull_param, result); +} + +static NTSTATUS rap_srv_pull_string(struct rap_call *call, const char **result) +{ + char paramdesc = *call->paramdesc++; + + if (paramdesc == 'O') { + *result = NULL; + return NT_STATUS_OK; + } + + if (paramdesc != 'z') + return NT_STATUS_INVALID_PARAMETER; + + return ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, result); +} + +static NTSTATUS rap_srv_pull_bufsize(struct rap_call *call, uint16 *bufsize) +{ + NTSTATUS result; + + if ( (*call->paramdesc++ != 'r') || (*call->paramdesc++ != 'L') ) + return NT_STATUS_INVALID_PARAMETER; + + result = ndr_pull_uint16(call->ndr_pull_param, bufsize); + + if (!NT_STATUS_IS_OK(result)) + return result; + + call->heap->offset = *bufsize; + + return NT_STATUS_OK; +} + +static NTSTATUS rap_srv_pull_expect_multiple(struct rap_call *call) +{ + if ( (*call->paramdesc++ != 'e') || (*call->paramdesc++ != 'h') ) + return NT_STATUS_INVALID_PARAMETER; + + return NT_STATUS_OK; +} + +static NTSTATUS rap_push_string(struct ndr_push *data_push, + struct rap_string_heap *heap, + const char *str) +{ + size_t space; + + if (str == NULL) + str = ""; + + space = strlen(str)+1; + + if (heap->offset < space) + return NT_STATUS_BUFFER_TOO_SMALL; + + heap->offset -= space; + + NDR_CHECK(ndr_push_uint16(data_push, heap->offset)); + NDR_CHECK(ndr_push_uint16(data_push, 0)); + + heap->strings = talloc_realloc(heap->mem_ctx, heap->strings, + sizeof(*heap->strings) * + (heap->num_strings + 1)); + + if (heap->strings == NULL) + return NT_STATUS_NO_MEMORY; + + heap->strings[heap->num_strings] = str; + heap->num_strings += 1; + + return NT_STATUS_OK; +} + +#define NDR_OK(call) do { result = call; \ + if (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) \ + goto buffer_overflow; \ + if (!NT_STATUS_IS_OK(result)) \ + goto done; \ + } while (0) + +static NTSTATUS _rap_netshareenum(struct smbsrv_request *req, + struct rap_call *call) +{ + struct rap_NetShareEnum r; + NTSTATUS result; + + NDR_OK(rap_srv_pull_word(call, &r.in.level)); + NDR_OK(rap_srv_pull_bufsize(call, &r.in.bufsize)); + NDR_OK(rap_srv_pull_expect_multiple(call)); + + switch(r.in.level) { + case 0: + if (strcmp(call->datadesc, "B13") != 0) + return NT_STATUS_INVALID_PARAMETER; + break; + case 1: + if (strcmp(call->datadesc, "B13BWz") != 0) + return NT_STATUS_INVALID_PARAMETER; + break; + default: + return NT_STATUS_INVALID_PARAMETER; + break; + } + + result = rap_netshareenum(req, &r); + + if (!NT_STATUS_IS_OK(result)) + return result; + + for (r.out.count = 0; r.out.count < r.out.available; r.out.count++) { + + int i = r.out.count; + struct ndr_push_save data_save; + struct rap_heap_save heap_save; + + ndr_push_save(call->ndr_push_data, &data_save); + rap_heap_save(call->heap, &heap_save); + + switch(r.in.level) { + case 0: + NDR_OK(ndr_push_bytes(call->ndr_push_data, + r.out.info[i].info0.name, + sizeof(r.out.info[i].info0.name))); + break; + case 1: + NDR_OK(ndr_push_bytes(call->ndr_push_data, + r.out.info[i].info1.name, + sizeof(r.out.info[i].info1.name))); + NDR_OK(ndr_push_uint8(call->ndr_push_data, + r.out.info[i].info1.pad)); + NDR_OK(ndr_push_uint16(call->ndr_push_data, + r.out.info[i].info1.type)); + + NDR_OK(rap_push_string(call->ndr_push_data, + call->heap, + r.out.info[i].info1.comment)); + + break; + } + + if (call->ndr_push_data->offset > call->heap->offset) { + + buffer_overflow: + + ndr_push_restore(call->ndr_push_data, &data_save); + rap_heap_restore(call->heap, &heap_save); + break; + } + } + + call->status = r.out.status; + + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.count)); + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.available)); + + result = NT_STATUS_OK; + + done: + return result; +} + +static NTSTATUS _rap_netserverenum2(struct smbsrv_request *req, + struct rap_call *call) +{ + struct rap_NetServerEnum2 r; + NTSTATUS result; + + NDR_OK(rap_srv_pull_word(call, &r.in.level)); + NDR_OK(rap_srv_pull_bufsize(call, &r.in.bufsize)); + NDR_OK(rap_srv_pull_expect_multiple(call)); + NDR_OK(rap_srv_pull_dword(call, &r.in.servertype)); + NDR_OK(rap_srv_pull_string(call, &r.in.domain)); + + switch(r.in.level) { + case 0: + if (strcmp(call->datadesc, "B16") != 0) + return NT_STATUS_INVALID_PARAMETER; + break; + case 1: + if (strcmp(call->datadesc, "B16BBDz") != 0) + return NT_STATUS_INVALID_PARAMETER; + break; + default: + return NT_STATUS_INVALID_PARAMETER; + break; + } + + result = rap_netserverenum2(req, &r); + + if (!NT_STATUS_IS_OK(result)) + return result; + + for (r.out.count = 0; r.out.count < r.out.available; r.out.count++) { + + int i = r.out.count; + struct ndr_push_save data_save; + struct rap_heap_save heap_save; + + ndr_push_save(call->ndr_push_data, &data_save); + rap_heap_save(call->heap, &heap_save); + + switch(r.in.level) { + case 0: + NDR_OK(ndr_push_bytes(call->ndr_push_data, + r.out.info[i].info0.name, + sizeof(r.out.info[i].info0.name))); + break; + case 1: + NDR_OK(ndr_push_bytes(call->ndr_push_data, + r.out.info[i].info1.name, + sizeof(r.out.info[i].info1.name))); + NDR_OK(ndr_push_uint8(call->ndr_push_data, + r.out.info[i].info1.version_major)); + NDR_OK(ndr_push_uint8(call->ndr_push_data, + r.out.info[i].info1.version_minor)); + NDR_OK(ndr_push_uint32(call->ndr_push_data, + r.out.info[i].info1.servertype)); + + NDR_OK(rap_push_string(call->ndr_push_data, + call->heap, + r.out.info[i].info1.comment)); + + break; + } + + if (call->ndr_push_data->offset > call->heap->offset) { + + buffer_overflow: + + ndr_push_restore(call->ndr_push_data, &data_save); + rap_heap_restore(call->heap, &heap_save); + break; + } + } + + call->status = r.out.status; + + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.count)); + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.available)); + + result = NT_STATUS_OK; + + done: + return result; +} + +static NTSTATUS api_Unsupported(struct smbsrv_request *req, + struct rap_call *call) +{ + call->status = NERR_notsupported; + call->convert = 0; + return NT_STATUS_OK; +} + +#define RAP_NetShareEnum 0 +#define RAP_NetServerEnum2 104 + +static const struct +{ + const char *name; + int id; + NTSTATUS (*fn)(struct smbsrv_request *req, struct rap_call *call); +} api_commands[] = { + {"NetShareEnum", RAP_NetShareEnum, _rap_netshareenum }, + {"NetServerEnum2", RAP_NetServerEnum2, _rap_netserverenum2 }, + {NULL, -1, api_Unsupported} +}; + +NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) +{ + int i; + NTSTATUS result; + struct rap_call *call; + DATA_BLOB result_param, result_data; + struct ndr_push *final_param; + struct ndr_push *final_data; + + call = new_rap_srv_call(req->mem_ctx, trans); + + if (call == NULL) + return NT_STATUS_NO_MEMORY; + + NDR_CHECK(ndr_pull_uint16(call->ndr_pull_param, &call->callno)); + NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, + &call->paramdesc)); + NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, + &call->datadesc)); + + call->ndr_push_param = ndr_push_init_ctx(req->mem_ctx); + call->ndr_push_data = ndr_push_init_ctx(req->mem_ctx); + + if ((call->ndr_push_param == NULL) || (call->ndr_push_data == NULL)) + return NT_STATUS_NO_MEMORY; + + call->ndr_push_param->flags = RAPNDR_FLAGS; + call->ndr_push_data->flags = RAPNDR_FLAGS; + + result = NT_STATUS_NOT_IMPLEMENTED; + + for (i=0; api_commands[i].name != NULL; i++) { + if (api_commands[i].id == call->callno) { + DEBUG(5, ("Running RAP call %s\n", + api_commands[i].name)); + result = api_commands[i].fn(req, call); + break; + } + } + + if (!NT_STATUS_IS_OK(result)) + return result; + + result_param = ndr_push_blob(call->ndr_push_param); + result_data = ndr_push_blob(call->ndr_push_data); + + final_param = ndr_push_init_ctx(req->mem_ctx); + final_data = ndr_push_init_ctx(req->mem_ctx); + + if ((final_param == NULL) || (final_data == NULL)) + return NT_STATUS_NO_MEMORY; + + final_param->flags = RAPNDR_FLAGS; + final_data->flags = RAPNDR_FLAGS; + + NDR_CHECK(ndr_push_uint16(final_param, call->status)); + NDR_CHECK(ndr_push_uint16(final_param, + call->heap->offset - result_data.length)); + NDR_CHECK(ndr_push_bytes(final_param, result_param.data, + result_param.length)); + + NDR_CHECK(ndr_push_bytes(final_data, result_data.data, + result_data.length)); + + for (i=call->heap->num_strings-1; i>=0; i--) + NDR_CHECK(ndr_push_string(final_data, NDR_SCALARS, + call->heap->strings[i])); + + trans->out.setup_count = 0; + trans->out.setup = NULL; + trans->out.params = ndr_push_blob(final_param); + trans->out.data = ndr_push_blob(final_data); + + return result; +} diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c new file mode 100644 index 0000000000..4a7b2dd91b --- /dev/null +++ b/source4/ntvfs/ipc/rap_server.c @@ -0,0 +1,54 @@ +/* + Unix SMB/CIFS implementation. + RAP handlers + + Copyright (C) Volker Lendecke 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* At this moment these are just dummy functions, but you might get the + * idea. */ + +NTSTATUS rap_netshareenum(struct smbsrv_request *req, + struct rap_NetShareEnum *r) +{ + r->out.status = 0; + r->out.available = 2; + r->out.info = talloc_array_p(req->mem_ctx, + union rap_shareenum_info, 2); + + strncpy(r->out.info[0].info1.name, "C$", 12); + r->out.info[0].info1.pad = 0; + r->out.info[0].info1.type = 0; + r->out.info[0].info1.comment = talloc_strdup(req->mem_ctx, "Bla"); + + strncpy(r->out.info[1].info1.name, "IPC$", 12); + r->out.info[1].info1.pad = 0; + r->out.info[1].info1.type = 1; + r->out.info[1].info1.comment = talloc_strdup(req->mem_ctx, "Blub"); + + return NT_STATUS_OK; +} + +NTSTATUS rap_netserverenum2(struct smbsrv_request *req, + struct rap_NetServerEnum2 *r) +{ + r->out.status = 0; + r->out.available = 0; + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index f6a0015f1d..73b3de314d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -667,6 +667,9 @@ static NTSTATUS ipc_trans(struct smbsrv_request *req, struct smb_trans2 *trans) { NTSTATUS status; + if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) + return ipc_rap_call(req, trans); + if (trans->in.setup_count != 2) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From 45a85bdd353418828df8017a9d7eb7c14f6f0cd3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 13 Jul 2004 21:04:56 +0000 Subject: r1486: commit the start of the generic server infastructure the idea is to have services as modules (smb, dcerpc, swat, ...) the process_model don't know about the service it self anymore. TODO: - the smbsrv should use the smbsrv_send function - the service subsystem init should be done like for other modules - we need to have a generic socket subsystem, which handle stream, datagram, and virtuell other sockets( e.g. for the ntvfs_ipc module to connect to the dcerpc server , or for smb or dcerpc or whatever to connect to a server wide auth service) - and other fixes... NOTE: process model pthread seems to be broken( but also before this patch!) metze (This used to be commit bbe5e00715ca4013ff0dbc345aa97adc6b5c2458) --- source4/ntvfs/cifs/vfs_cifs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 93b9f2630e..b6d3486ad8 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -51,7 +51,7 @@ struct async_info { static void idle_func(struct cli_transport *transport, void *p_private) { struct cvfs_private *private = p_private; - if (socket_pending(private->tcon->smb_conn->socket.fd)) { + if (socket_pending(private->tcon->smb_conn->connection->socket->fde->fd)) { smbd_process_async(private->tcon->smb_conn); } } @@ -164,7 +164,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) fde.private = private; fde.handler = cifs_socket_handler; - event_add_fd(tcon->smb_conn->events, &fde); + event_add_fd(tcon->smb_conn->connection->event.ctx, &fde); /* we need to receive oplock break requests from the server */ cli_oplock_handler(private->transport, oplock_handler, private); @@ -180,7 +180,7 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) { struct cvfs_private *private = tcon->ntvfs_private; - event_remove_fd_all(tcon->smb_conn->events, private->transport->socket->fd); + event_remove_fd_all(tcon->smb_conn->connection->event.ctx, private->transport->socket->fd); smb_tree_disconnect(private->tree); cli_tree_close(private->tree); -- cgit From 5779a7da9aecb7329eb47e93000dc8b9de96d9ae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 14 Jul 2004 12:44:31 +0000 Subject: r1499: combine struct user_struct and struct smbsrv_user to a struct smbsrv_session that the same as cli_session for the client we need a gensec_security pointer there (spnego support will follow) prefix some related functions with smbsrv_ metze (This used to be commit f276378157bb9994c4c91ce46150a510de5c33f8) --- source4/ntvfs/ipc/vfs_ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 73b3de314d..2e44b00c6b 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -242,11 +242,11 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, ep_description.info.smb_pipe = p->pipe_name; /* tell the RPC layer the session_info */ - if (req->user_ctx->vuser) { + if (req->session) { /* The session info is refcount-increased in the dcesrv_endpoint_search_connect() function */ - session_info = req->user_ctx->vuser->session_info; + session_info = req->session->session_info; } status = dcesrv_endpoint_search_connect(&req->smb_conn->dcesrv, -- cgit From 5ddf678e0113f81aa2b5f99134cda4fe8c01afb7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 Jul 2004 06:40:49 +0000 Subject: r1578: the first stage of the async client rewrite. Up to now the client code has had an async API, and operated asynchronously at the packet level, but was not truly async in that it assumed that it could always write to the socket and when a partial packet came in that it could block waiting for the rest of the packet. This change makes the SMB client library full async, by adding a separate outgoing packet queue, using non-blocking socket IO and having a input buffer that can fill asynchonously until the full packet has arrived. The main complexity was in dealing with the events structure when using the CIFS proxy backend. In that case the same events structure needs to be used in both the client library and the main smbd server, so that when the client library is waiting for a reply that the main server keeps processing packets. This required some changes in the events library code. Next step is to make the generated rpc client code use these new capabilities. (This used to be commit 96bf4da3edc4d64b0f58ef520269f3b385b8da02) --- source4/ntvfs/cifs/vfs_cifs.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index b6d3486ad8..fd94a923c9 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -68,17 +68,17 @@ static BOOL oplock_handler(struct cli_transport *transport, uint16_t tid, uint16 return req_send_oplock_break(private->tcon, fnum, level); } -/* + /* a handler for read events on a connection to a backend server */ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16_t flags) { struct cvfs_private *private = fde->private; struct smbsrv_tcon *tcon = private->tcon; - + DEBUG(5,("cifs_socket_handler event on fd %d\n", fde->fd)); - - if (!cli_request_receive_next(private->transport)) { + + if (!cli_transport_process(private->transport)) { /* the connection to our server is dead */ close_cnum(tcon); } @@ -93,7 +93,6 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) NTSTATUS status; struct cvfs_private *private; const char *map_calls; - struct fd_event fde; const char *host, *user, *pass, *domain, *remote_share; /* Here we need to determine which server to connect to. @@ -157,18 +156,17 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) tcon->ntvfs_ops = ops; } - /* we need to tell the event loop that we wish to receive read events - on our SMB connection to the server */ - fde.fd = private->transport->socket->fd; - fde.flags = EVENT_FD_READ; - fde.private = private; - fde.handler = cifs_socket_handler; - - event_add_fd(tcon->smb_conn->connection->event.ctx, &fde); - /* we need to receive oplock break requests from the server */ cli_oplock_handler(private->transport, oplock_handler, private); - cli_transport_idle_handler(private->transport, idle_func, 100, private); + cli_transport_idle_handler(private->transport, idle_func, 1, private); + + private->transport->event.fde->handler = cifs_socket_handler; + private->transport->event.fde->private = private; + + event_context_merge(tcon->smb_conn->connection->event.ctx, + private->transport->event.ctx); + + private->transport->event.ctx = tcon->smb_conn->connection->event.ctx; return NT_STATUS_OK; } @@ -180,7 +178,6 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) { struct cvfs_private *private = tcon->ntvfs_private; - event_remove_fd_all(tcon->smb_conn->connection->event.ctx, private->transport->socket->fd); smb_tree_disconnect(private->tree); cli_tree_close(private->tree); -- cgit From c5fbb6f23c2d399c7510bc552cdb1a27b1ef66a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 4 Aug 2004 13:23:35 +0000 Subject: r1654: rename cli_ -> smbcli_ rename CLI_ -> SMBCLI_ metze (This used to be commit 8441750fd9427dd6fe477f27e603821b4026f038) --- source4/ntvfs/cifs/vfs_cifs.c | 72 +++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 36 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index fd94a923c9..9020ba2bba 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -29,8 +29,8 @@ /* this is stored in ntvfs_private */ struct cvfs_private { - struct cli_tree *tree; - struct cli_transport *transport; + struct smbcli_tree *tree; + struct smbcli_transport *transport; struct smbsrv_tcon *tcon; const char *map_calls; }; @@ -48,7 +48,7 @@ struct async_info { this function won't be needed once all of the cifs backend and the core of smbd is converted to use async calls */ -static void idle_func(struct cli_transport *transport, void *p_private) +static void idle_func(struct smbcli_transport *transport, void *p_private) { struct cvfs_private *private = p_private; if (socket_pending(private->tcon->smb_conn->connection->socket->fde->fd)) { @@ -60,7 +60,7 @@ static void idle_func(struct cli_transport *transport, void *p_private) a handler for oplock break events from the server - these need to be passed along to the client */ -static BOOL oplock_handler(struct cli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) +static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) { struct cvfs_private *private = p_private; @@ -78,7 +78,7 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, DEBUG(5,("cifs_socket_handler event on fd %d\n", fde->fd)); - if (!cli_transport_process(private->transport)) { + if (!smbcli_transport_process(private->transport)) { /* the connection to our server is dead */ close_cnum(tcon); } @@ -121,7 +121,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) req->tcon->ntvfs_private = (void *)private; - status = cli_tree_full_connection(&private->tree, + status = smbcli_tree_full_connection(&private->tree, "vfs_cifs", host, 0, @@ -157,8 +157,8 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) } /* we need to receive oplock break requests from the server */ - cli_oplock_handler(private->transport, oplock_handler, private); - cli_transport_idle_handler(private->transport, idle_func, 1, private); + smbcli_oplock_handler(private->transport, oplock_handler, private); + smbcli_transport_idle_handler(private->transport, idle_func, 1, private); private->transport->event.fde->handler = cifs_socket_handler; private->transport->event.fde->private = private; @@ -179,7 +179,7 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) struct cvfs_private *private = tcon->ntvfs_private; smb_tree_disconnect(private->tree); - cli_tree_close(private->tree); + smbcli_tree_close(private->tree); return NT_STATUS_OK; } @@ -189,11 +189,11 @@ static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) this handler can only be used for functions that don't return any parameters (those that just return a status code) */ -static void async_simple(struct cli_request *c_req) +static void async_simple(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = cli_request_simple_recv(c_req); + req->async.status = smbcli_request_simple_recv(c_req); req->async.send_fn(req); } @@ -223,7 +223,7 @@ static void async_simple(struct cli_request *c_req) static NTSTATUS cvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; /* see if the front end will allow us to perform this function asynchronously. */ @@ -239,7 +239,7 @@ static NTSTATUS cvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) /* a handler for async ioctl replies */ -static void async_ioctl(struct cli_request *c_req) +static void async_ioctl(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -253,7 +253,7 @@ static void async_ioctl(struct cli_request *c_req) static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; /* see if the front end will allow us to perform this function asynchronously. */ @@ -272,7 +272,7 @@ static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) static NTSTATUS cvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_chkpath(private->tree, cp); @@ -286,7 +286,7 @@ static NTSTATUS cvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) /* a handler for async qpathinfo replies */ -static void async_qpathinfo(struct cli_request *c_req) +static void async_qpathinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -300,7 +300,7 @@ static void async_qpathinfo(struct cli_request *c_req) static NTSTATUS cvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_pathinfo(private->tree, req->mem_ctx, info); @@ -314,7 +314,7 @@ static NTSTATUS cvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *i /* a handler for async qfileinfo replies */ -static void async_qfileinfo(struct cli_request *c_req) +static void async_qfileinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -328,7 +328,7 @@ static void async_qfileinfo(struct cli_request *c_req) static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_fileinfo(private->tree, req->mem_ctx, info); @@ -346,7 +346,7 @@ static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i static NTSTATUS cvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_setpathinfo(private->tree, st); @@ -361,7 +361,7 @@ static NTSTATUS cvfs_setpathinfo(struct smbsrv_request *req, union smb_setfilein /* a handler for async open replies */ -static void async_open(struct cli_request *c_req) +static void async_open(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -375,7 +375,7 @@ static void async_open(struct cli_request *c_req) static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (private->map_calls && in_list("open", private->map_calls, True) && io->generic.level != RAW_OPEN_GENERIC) { @@ -397,7 +397,7 @@ static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_mkdir(private->tree, md); @@ -414,7 +414,7 @@ static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_rmdir(private->tree, rd); @@ -430,7 +430,7 @@ static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) static NTSTATUS cvfs_rename(struct smbsrv_request *req, union smb_rename *ren) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_rename(private->tree, ren); @@ -452,7 +452,7 @@ static NTSTATUS cvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) /* a handler for async read replies */ -static void async_read(struct cli_request *c_req) +static void async_read(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -466,7 +466,7 @@ static void async_read(struct cli_request *c_req) static NTSTATUS cvfs_read(struct smbsrv_request *req, union smb_read *rd) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_read(private->tree, rd); @@ -480,7 +480,7 @@ static NTSTATUS cvfs_read(struct smbsrv_request *req, union smb_read *rd) /* a handler for async write replies */ -static void async_write(struct cli_request *c_req) +static void async_write(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -494,7 +494,7 @@ static void async_write(struct cli_request *c_req) static NTSTATUS cvfs_write(struct smbsrv_request *req, union smb_write *wr) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_write(private->tree, wr); @@ -527,7 +527,7 @@ static NTSTATUS cvfs_flush(struct smbsrv_request *req, struct smb_flush *io) static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_close(private->tree, io); @@ -552,7 +552,7 @@ static NTSTATUS cvfs_exit(struct smbsrv_request *req) static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_lock(private->tree, lck); @@ -569,7 +569,7 @@ static NTSTATUS cvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_setfileinfo(private->tree, info); @@ -583,7 +583,7 @@ static NTSTATUS cvfs_setfileinfo(struct smbsrv_request *req, /* a handler for async fsinfo replies */ -static void async_fsinfo(struct cli_request *c_req) +static void async_fsinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -597,7 +597,7 @@ static void async_fsinfo(struct cli_request *c_req) static NTSTATUS cvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_fsinfo(private->tree, req->mem_ctx, fs); @@ -649,7 +649,7 @@ static NTSTATUS cvfs_search_close(struct smbsrv_request *req, union smb_search_c /* a handler for async trans2 replies */ -static void async_trans2(struct cli_request *c_req) +static void async_trans2(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; @@ -661,7 +661,7 @@ static void async_trans2(struct cli_request *c_req) static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) { struct cvfs_private *private = req->tcon->ntvfs_private; - struct cli_request *c_req; + struct smbcli_request *c_req; if (!req->async.send_fn) { return smb_raw_trans2(private->tree, req->mem_ctx, trans2); -- cgit From ad5acba254ff7936cc959eaeaf88726095b3fe28 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Aug 2004 12:50:41 +0000 Subject: r1916: return a more clear error, we are miss configure in this case metze (This used to be commit a908f831cb9dd265f9b183512053f9e608feec3d) --- source4/ntvfs/posix/vfs_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index cfbb892d9c..93cfbd74a9 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -42,7 +42,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) DEBUGADD(0,(" all file acess is done as user 'root'\n")); DEBUGADD(0,(" Please don't use this a sensitive data!!!\n")); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_DEVICE_CONFIGURATION_ERROR; } /* -- cgit From b83ba93eaeb2dcb0bf11615591d886fda84e4162 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Aug 2004 01:54:46 +0000 Subject: r1983: a completely new implementation of talloc This version does the following: 1) talloc_free(), talloc_realloc() and talloc_steal() lose their (redundent) first arguments 2) you can use _any_ talloc pointer as a talloc context to allocate more memory. This allows you to create complex data structures where the top level structure is the logical parent of the next level down, and those are the parents of the level below that. Then destroy either the lot with a single talloc_free() or destroy any sub-part with a talloc_free() of that part 3) you can name any pointer. Use talloc_named() which is just like talloc() but takes the printf style name argument as well as the parent context and the size. The whole thing ends up being a very simple piece of code, although some of the pointer walking gets hairy. So far, I'm just using the new talloc() like the old one. The next step is to actually take advantage of the new interface properly. Expect some new commits soon that simplify some common coding styles in samba4 by using the new talloc(). (This used to be commit e35bb094c52e550b3105dd1638d8d90de71d854f) --- source4/ntvfs/ipc/ipc_rap.c | 2 +- source4/ntvfs/reference/ref_util.c | 2 +- source4/ntvfs/simple/svfs_util.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index d2cd0b38d5..347ff39d97 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -178,7 +178,7 @@ static NTSTATUS rap_push_string(struct ndr_push *data_push, NDR_CHECK(ndr_push_uint16(data_push, heap->offset)); NDR_CHECK(ndr_push_uint16(data_push, 0)); - heap->strings = talloc_realloc(heap->mem_ctx, heap->strings, + heap->strings = talloc_realloc(heap->strings, sizeof(*heap->strings) * (heap->num_strings + 1)); diff --git a/source4/ntvfs/reference/ref_util.c b/source4/ntvfs/reference/ref_util.c index e221086950..8be80183c5 100644 --- a/source4/ntvfs/reference/ref_util.c +++ b/source4/ntvfs/reference/ref_util.c @@ -104,7 +104,7 @@ struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, cons if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; - dir->files = talloc_realloc(mem_ctx, dir->files, allocated * sizeof(dir->files[0])); + dir->files = talloc_realloc(dir->files, allocated * sizeof(dir->files[0])); if (!dir->files) { closedir(odir); return NULL; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 7da9667e3c..1949ecb235 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -105,7 +105,7 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; - dir->files = talloc_realloc(mem_ctx, dir->files, allocated * sizeof(dir->files[0])); + dir->files = talloc_realloc(dir->files, allocated * sizeof(dir->files[0])); if (!dir->files) { closedir(odir); return NULL; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index ad889daf36..ae64c96c75 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -580,8 +580,8 @@ static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io) } DLIST_REMOVE(private->open_files, f); - talloc_free(req->tcon->mem_ctx, f->name); - talloc_free(req->tcon->mem_ctx, f); + talloc_free(f->name); + talloc_free(f); return NT_STATUS_OK; } @@ -766,7 +766,7 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f dir = svfs_list(mem_ctx, req, io->t2ffirst.in.pattern); if (!dir) { - talloc_destroy_pool(mem_ctx); + talloc_free(mem_ctx); return NT_STATUS_FOOBAR; } -- cgit From 53415ebf8a6affb08d65cd3b4edc0e55f68b83d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Aug 2004 23:58:00 +0000 Subject: r2030: quick hack to allow the simple NTVFS backend to handler base directories with mixed case names (This used to be commit efecc3306efb17f586b781112886d9416b355d65) --- source4/ntvfs/simple/svfs_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 1949ecb235..14ffc6d19c 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -41,7 +41,7 @@ char *svfs_unix_path(struct smbsrv_request *req, const char *name) } all_string_sub(ret, "\\", "/", 0); - strlower(ret); + strlower(ret + strlen(private->connectpath)); return ret; } -- cgit From 5e869b4eabaf428b36b5bc158ab4047d25e3eb5b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 25 Aug 2004 07:15:21 +0000 Subject: r2055: Add PRINTF_ATTRIBUTE to many more parts of the code, and a new --enable-developer warning for when they are missing. Andrew Bartlett (This used to be commit 8115e44d47bcd65edba08d10117180ae508cdbc1) --- source4/ntvfs/nbench/vfs_nbench.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index dceaa9f45b..e4e5af4171 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -38,6 +38,9 @@ struct nbench_private { /* log one request to the nbench log */ +static void nbench_log(struct nbench_private *private, + const char *format, ...) PRINTF_ATTRIBUTE(2, 3); + static void nbench_log(struct nbench_private *private, const char *format, ...) { -- cgit From 8293df91bcec574fb4a2b290cc11dd83353264ae Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 8 Sep 2004 00:00:56 +0000 Subject: r2247: talloc_destroy -> talloc_free (This used to be commit 6c1a72c5d667245b1eec94f58e68acd22dd720ce) --- source4/ntvfs/simple/vfs_simple.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index ae64c96c75..007095f44a 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -803,7 +803,7 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f /* work out if we are going to keep the search state */ if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - talloc_destroy(search->mem_ctx); + talloc_free(search->mem_ctx); } else { private->next_search_handle++; DLIST_ADD(private->search, search); @@ -893,7 +893,7 @@ found: if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { DLIST_REMOVE(private->search, search); - talloc_destroy(search->mem_ctx); + talloc_free(search->mem_ctx); } return NT_STATUS_OK; @@ -915,7 +915,7 @@ static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_c } DLIST_REMOVE(private->search, search); - talloc_destroy(search->mem_ctx); + talloc_free(search->mem_ctx); return NT_STATUS_OK; } -- cgit From 893c62d38388b20c52cf3c45069d836c46f42bd3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 8 Sep 2004 05:39:06 +0000 Subject: r2249: got rid of some more mem_ctx elements in structures (This used to be commit 21ef338cbbe96acc8594ffc550ef60c6a40fb951) --- source4/ntvfs/cifs/vfs_cifs.c | 42 +++++++++++++++++++------------------- source4/ntvfs/ipc/ipc_rap.c | 10 ++++----- source4/ntvfs/ipc/rap_server.c | 6 +++--- source4/ntvfs/ipc/vfs_ipc.c | 8 ++++---- source4/ntvfs/nbench/vfs_nbench.c | 2 +- source4/ntvfs/ntvfs_generic.c | 14 ++++++------- source4/ntvfs/posix/vfs_posix.c | 42 +++++++++++++++++++++++++++----------- source4/ntvfs/print/vfs_print.c | 2 +- source4/ntvfs/simple/svfs_util.c | 4 ++-- source4/ntvfs/simple/vfs_simple.c | 43 ++++++++++++++++++--------------------- 10 files changed, 94 insertions(+), 79 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9020ba2bba..078075a11f 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -113,7 +113,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) return NT_STATUS_INVALID_PARAMETER; } - private = talloc(req->tcon->mem_ctx, sizeof(struct cvfs_private)); + private = talloc(req->tcon, sizeof(struct cvfs_private)); if (!private) { return NT_STATUS_NO_MEMORY; } @@ -136,18 +136,18 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); private->tcon = req->tcon; - tcon->fs_type = talloc_strdup(tcon->mem_ctx, "NTFS"); - tcon->dev_type = talloc_strdup(tcon->mem_ctx, "A:"); + tcon->fs_type = talloc_strdup(tcon, "NTFS"); + tcon->dev_type = talloc_strdup(tcon, "A:"); map_calls = lp_parm_string(req->tcon->service, "cifs", "map calls"); if (map_calls) { - private->map_calls = talloc_strdup(tcon->mem_ctx, map_calls); + private->map_calls = talloc_strdup(tcon, map_calls); } /* if we are mapping trans2, then we need to give a trans2 pointer in the operations structure */ if (private->map_calls && in_list("trans2", private->map_calls, True)) { - struct ntvfs_ops *ops = talloc_memdup(tcon->mem_ctx,tcon->ntvfs_ops,sizeof(*ops)); + struct ntvfs_ops *ops = talloc_memdup(tcon, tcon->ntvfs_ops,sizeof(*ops)); static NTSTATUS cvfs_trans2(struct smbsrv_request *,struct smb_trans2 *); if (!ops) { return NT_STATUS_NO_MEMORY; @@ -203,7 +203,7 @@ static void async_simple(struct smbcli_request *c_req) if (!c_req) return NT_STATUS_UNSUCCESSFUL; \ { \ struct async_info *async; \ - async = talloc(req->mem_ctx, sizeof(*async)); \ + async = talloc_p(req, struct async_info); \ if (!async) return NT_STATUS_NO_MEMORY; \ async->parms = io; \ async->req = req; \ @@ -243,7 +243,7 @@ static void async_ioctl(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_ioctl_recv(c_req, req->mem_ctx, async->parms); + req->async.status = smb_raw_ioctl_recv(c_req, req, async->parms); req->async.send_fn(req); } @@ -258,7 +258,7 @@ static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) /* see if the front end will allow us to perform this function asynchronously. */ if (!req->async.send_fn) { - return smb_raw_ioctl(private->tree, req->mem_ctx, io); + return smb_raw_ioctl(private->tree, req, io); } c_req = smb_raw_ioctl_send(private->tree, io); @@ -290,7 +290,7 @@ static void async_qpathinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_pathinfo_recv(c_req, req->mem_ctx, async->parms); + req->async.status = smb_raw_pathinfo_recv(c_req, req, async->parms); req->async.send_fn(req); } @@ -303,7 +303,7 @@ static NTSTATUS cvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *i struct smbcli_request *c_req; if (!req->async.send_fn) { - return smb_raw_pathinfo(private->tree, req->mem_ctx, info); + return smb_raw_pathinfo(private->tree, req, info); } c_req = smb_raw_pathinfo_send(private->tree, info); @@ -318,7 +318,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_fileinfo_recv(c_req, req->mem_ctx, async->parms); + req->async.status = smb_raw_fileinfo_recv(c_req, req, async->parms); req->async.send_fn(req); } @@ -331,7 +331,7 @@ static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i struct smbcli_request *c_req; if (!req->async.send_fn) { - return smb_raw_fileinfo(private->tree, req->mem_ctx, info); + return smb_raw_fileinfo(private->tree, req, info); } c_req = smb_raw_fileinfo_send(private->tree, info); @@ -365,7 +365,7 @@ static void async_open(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_open_recv(c_req, req->mem_ctx, async->parms); + req->async.status = smb_raw_open_recv(c_req, req, async->parms); req->async.send_fn(req); } @@ -383,7 +383,7 @@ static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) } if (!req->async.send_fn) { - return smb_raw_open(private->tree, req->mem_ctx, io); + return smb_raw_open(private->tree, req, io); } c_req = smb_raw_open_send(private->tree, io); @@ -587,7 +587,7 @@ static void async_fsinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_fsinfo_recv(c_req, req->mem_ctx, async->parms); + req->async.status = smb_raw_fsinfo_recv(c_req, req, async->parms); req->async.send_fn(req); } @@ -600,10 +600,10 @@ static NTSTATUS cvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) struct smbcli_request *c_req; if (!req->async.send_fn) { - return smb_raw_fsinfo(private->tree, req->mem_ctx, fs); + return smb_raw_fsinfo(private->tree, req, fs); } - c_req = smb_raw_fsinfo_send(private->tree, req->mem_ctx, fs); + c_req = smb_raw_fsinfo_send(private->tree, req, fs); ASYNC_RECV_TAIL(fs, async_fsinfo); } @@ -625,7 +625,7 @@ static NTSTATUS cvfs_search_first(struct smbsrv_request *req, union smb_search_f { struct cvfs_private *private = req->tcon->ntvfs_private; - return smb_raw_search_first(private->tree, req->mem_ctx, io, search_private, callback); + return smb_raw_search_first(private->tree, req, io, search_private, callback); } /* continue a search */ @@ -635,7 +635,7 @@ static NTSTATUS cvfs_search_next(struct smbsrv_request *req, union smb_search_ne { struct cvfs_private *private = req->tcon->ntvfs_private; - return smb_raw_search_next(private->tree, req->mem_ctx, io, search_private, callback); + return smb_raw_search_next(private->tree, req, io, search_private, callback); } /* close a search */ @@ -653,7 +653,7 @@ static void async_trans2(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_trans2_recv(c_req, req->mem_ctx, async->parms); + req->async.status = smb_raw_trans2_recv(c_req, req, async->parms); req->async.send_fn(req); } @@ -664,7 +664,7 @@ static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans struct smbcli_request *c_req; if (!req->async.send_fn) { - return smb_raw_trans2(private->tree, req->mem_ctx, trans2); + return smb_raw_trans2(private->tree, req, trans2); } c_req = smb_raw_trans2_send(private->tree, trans2); diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 347ff39d97..32b2fa2181 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -395,7 +395,7 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) struct ndr_push *final_param; struct ndr_push *final_data; - call = new_rap_srv_call(req->mem_ctx, trans); + call = new_rap_srv_call(req, trans); if (call == NULL) return NT_STATUS_NO_MEMORY; @@ -406,8 +406,8 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, &call->datadesc)); - call->ndr_push_param = ndr_push_init_ctx(req->mem_ctx); - call->ndr_push_data = ndr_push_init_ctx(req->mem_ctx); + call->ndr_push_param = ndr_push_init_ctx(req); + call->ndr_push_data = ndr_push_init_ctx(req); if ((call->ndr_push_param == NULL) || (call->ndr_push_data == NULL)) return NT_STATUS_NO_MEMORY; @@ -432,8 +432,8 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) result_param = ndr_push_blob(call->ndr_push_param); result_data = ndr_push_blob(call->ndr_push_data); - final_param = ndr_push_init_ctx(req->mem_ctx); - final_data = ndr_push_init_ctx(req->mem_ctx); + final_param = ndr_push_init_ctx(req); + final_data = ndr_push_init_ctx(req); if ((final_param == NULL) || (final_data == NULL)) return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 4a7b2dd91b..4ab1915c81 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -29,18 +29,18 @@ NTSTATUS rap_netshareenum(struct smbsrv_request *req, { r->out.status = 0; r->out.available = 2; - r->out.info = talloc_array_p(req->mem_ctx, + r->out.info = talloc_array_p(req, union rap_shareenum_info, 2); strncpy(r->out.info[0].info1.name, "C$", 12); r->out.info[0].info1.pad = 0; r->out.info[0].info1.type = 0; - r->out.info[0].info1.comment = talloc_strdup(req->mem_ctx, "Bla"); + r->out.info[0].info1.comment = talloc_strdup(req, "Bla"); strncpy(r->out.info[1].info1.name, "IPC$", 12); r->out.info[1].info1.pad = 0; r->out.info[1].info1.type = 1; - r->out.info[1].info1.comment = talloc_strdup(req->mem_ctx, "Blub"); + r->out.info[1].info1.comment = talloc_strdup(req, "Blub"); return NT_STATUS_OK; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2e44b00c6b..053222460c 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -110,11 +110,11 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename) struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; - tcon->fs_type = talloc_strdup(tcon->mem_ctx, "IPC"); - tcon->dev_type = talloc_strdup(tcon->mem_ctx, "IPC"); + tcon->fs_type = talloc_strdup(tcon, "IPC"); + tcon->dev_type = talloc_strdup(tcon, "IPC"); /* prepare the private state for this connection */ - private = talloc(tcon->mem_ctx, sizeof(struct ipc_private)); + private = talloc_p(tcon, struct ipc_private); if (!private) { return NT_STATUS_NO_MEMORY; } @@ -604,7 +604,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *tr return NT_STATUS_INVALID_HANDLE; } - trans->out.data = data_blob_talloc(req->mem_ctx, NULL, trans->in.max_data); + trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data); if (!trans->out.data.data) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index e4e5af4171..549d1d893f 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -100,7 +100,7 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename NTSTATUS status; char *logname = NULL; - private = talloc_p(req->tcon->mem_ctx, struct nbench_private); + private = talloc_p(req->tcon, struct nbench_private); if (!private) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 36cbcabbd5..29f21b1863 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -472,7 +472,7 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info case RAW_FILEINFO_STREAM_INFORMATION: info->stream_info.out.num_streams = info2->generic.out.num_streams; if (info->stream_info.out.num_streams > 0) { - info->stream_info.out.streams = talloc(req->mem_ctx, + info->stream_info.out.streams = talloc(req, info->stream_info.out.num_streams * sizeof(struct stream_struct)); if (!info->stream_info.out.streams) { DEBUG(2,("ntvfs_map_fileinfo: no memory for %d streams\n", @@ -482,7 +482,7 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info for (i=0; i < info->stream_info.out.num_streams; i++) { info->stream_info.out.streams[i] = info2->generic.out.streams[i]; info->stream_info.out.streams[i].stream_name.s = - talloc_strdup(req->mem_ctx, info2->generic.out.streams[i].stream_name.s); + talloc_strdup(req, info2->generic.out.streams[i].stream_name.s); if (!info->stream_info.out.streams[i].stream_name.s) { DEBUG(2,("ntvfs_map_fileinfo: no memory for stream_name\n")); return NT_STATUS_NO_MEMORY; @@ -493,13 +493,13 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info case RAW_FILEINFO_NAME_INFO: case RAW_FILEINFO_NAME_INFORMATION: - info->name_info.out.fname.s = talloc_strdup(req->mem_ctx, info2->generic.out.fname.s); + info->name_info.out.fname.s = talloc_strdup(req, info2->generic.out.fname.s); info->name_info.out.fname.private_length = info2->generic.out.fname.private_length; return NT_STATUS_OK; case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: - info->alt_name_info.out.fname.s = talloc_strdup(req->mem_ctx, info2->generic.out.alt_fname.s); + info->alt_name_info.out.fname.s = talloc_strdup(req, info2->generic.out.alt_fname.s); info->alt_name_info.out.fname.private_length = info2->generic.out.alt_fname.private_length; return NT_STATUS_OK; @@ -510,7 +510,7 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info case RAW_FILEINFO_ALL_EAS: info->all_eas.out.num_eas = info2->generic.out.num_eas; if (info->all_eas.out.num_eas > 0) { - info->all_eas.out.eas = talloc(req->mem_ctx, + info->all_eas.out.eas = talloc(req, info->all_eas.out.num_eas * sizeof(struct ea_struct)); if (!info->all_eas.out.eas) { DEBUG(2,("ntvfs_map_fileinfo: no memory for %d eas\n", @@ -520,13 +520,13 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info for (i = 0; i < info->all_eas.out.num_eas; i++) { info->all_eas.out.eas[i] = info2->generic.out.eas[i]; info->all_eas.out.eas[i].name.s = - talloc_strdup(req->mem_ctx, info2->generic.out.eas[i].name.s); + talloc_strdup(req, info2->generic.out.eas[i].name.s); if (!info->all_eas.out.eas[i].name.s) { DEBUG(2,("ntvfs_map_fileinfo: no memory for stream_name\n")); return NT_STATUS_NO_MEMORY; } info->all_eas.out.eas[i].value.data = - talloc_memdup(req->mem_ctx, + talloc_memdup(req, info2->generic.out.eas[i].value.data, info2->generic.out.eas[i].value.length); if (!info->all_eas.out.eas[i].value.data) { diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 93cfbd74a9..8269f9bba7 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -1,8 +1,9 @@ /* Unix SMB/CIFS implementation. + POSIX NTVFS backend - Copyright (C) Andrew Tridgell 2003 - Copyright (C) Stefan (metze) Metzmacher 2004 + + Copyright (C) Andrew Tridgell 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,6 +25,8 @@ */ #include "include/includes.h" +#include "vfs_posix.h" + /* connect to a share - used when a tree_connect operation comes @@ -33,16 +36,31 @@ */ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) { - DEBUG(0, ("Connection to share [%s] ACCESS DENIED!\n", sharename)); - DEBUGADD(0,("This is because your using the 'ntvfs handler = default'.\n")); - DEBUGADD(0,("This backend is not functional at the moment.\n")); - DEBUGADD(0,("Please use one of the following backends:\n")); - DEBUGADD(0,("cifs - a proxy to another cifs-server\n")); - DEBUGADD(0,("simple - a very, very simple posix backend\n")); - DEBUGADD(0,(" all file acess is done as user 'root'\n")); - DEBUGADD(0,(" Please don't use this a sensitive data!!!\n")); - - return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + struct smbsrv_tcon *tcon = req->tcon; + struct pvfs_state *pvfs; + struct stat st; + + DEBUG(0,("WARNING: the posix vfs handler is incomplete - you probably want \"ntvfs handler = simple\"\n")); + + pvfs = talloc_named(tcon, sizeof(struct pvfs_state), "pvfs_connect(%s)", sharename); + if (pvfs == NULL) { + return NT_STATUS_NO_MEMORY; + } + + pvfs->base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); + + /* the directory must exist. Note that we deliberately don't + check that it is readable */ + if (stat(pvfs->base_directory, &st) != 0 || !S_ISDIR(st.st_mode)) { + DEBUG(0,("pvfs_connect: '%s' is not a directory, when connecting to [%s]\n", + pvfs->base_directory, sharename)); + return NT_STATUS_BAD_NETWORK_NAME; + } + + tcon->fs_type = talloc_strdup(tcon, "NTFS"); + tcon->dev_type = talloc_strdup(tcon, "A:"); + + return NT_STATUS_OK; } /* diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index fa5835843a..4b50e3e6e5 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -64,7 +64,7 @@ static NTSTATUS print_ioctl(struct smbsrv_request *req, union smb_ioctl *io) if (io->ioctl.in.request == IOCTL_QUERY_JOB_INFO) { /* a request for the print job id of an open print job */ - io->ioctl.out.blob = data_blob_talloc(req->mem_ctx, NULL, 32); + io->ioctl.out.blob = data_blob_talloc(req, NULL, 32); data_blob_clear(&io->ioctl.out.blob); diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 14ffc6d19c..04165cadd9 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -35,9 +35,9 @@ char *svfs_unix_path(struct smbsrv_request *req, const char *name) char *ret; if (*name != '\\') { - ret = talloc_asprintf(req->mem_ctx, "%s/%s", private->connectpath, name); + ret = talloc_asprintf(req, "%s/%s", private->connectpath, name); } else { - ret = talloc_asprintf(req->mem_ctx, "%s%s", private->connectpath, name); + ret = talloc_asprintf(req, "%s%s", private->connectpath, name); } all_string_sub(ret, "\\", "/", 0); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 007095f44a..8bce111e9c 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -67,12 +67,12 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) struct smbsrv_tcon *tcon = req->tcon; struct svfs_private *private; - tcon->ntvfs_private = talloc_p(tcon->mem_ctx, struct svfs_private); + tcon->ntvfs_private = talloc_p(tcon, struct svfs_private); private = tcon->ntvfs_private; private->next_search_handle = 0; - private->connectpath = talloc_strdup(tcon->mem_ctx, lp_pathname(tcon->service)); + private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service)); private->open_files = NULL; /* the directory must exist */ @@ -82,8 +82,8 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) return NT_STATUS_BAD_NETWORK_NAME; } - tcon->fs_type = talloc_strdup(tcon->mem_ctx, "NTFS"); - tcon->dev_type = talloc_strdup(tcon->mem_ctx, "A:"); + tcon->fs_type = talloc_strdup(tcon, "NTFS"); + tcon->dev_type = talloc_strdup(tcon, "A:"); DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); @@ -183,7 +183,7 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo asprintf(&pattern, "%s:*", unix_path); if (pattern) { - dir = svfs_list_unix(req->mem_ctx, req, pattern); + dir = svfs_list_unix(req, req, pattern); } unix_to_nt_time(&info->generic.out.create_time, st->st_ctime); @@ -201,8 +201,8 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo info->generic.out.delete_pending = 0; info->generic.out.ea_size = 0; info->generic.out.num_eas = 0; - info->generic.out.fname.s = talloc_strdup(req->mem_ctx, short_name); - info->generic.out.alt_fname.s = talloc_strdup(req->mem_ctx, short_name); + info->generic.out.fname.s = talloc_strdup(req, short_name); + info->generic.out.alt_fname.s = talloc_strdup(req, short_name); info->generic.out.ex_attrib = 0; info->generic.out.compressed_size = 0; info->generic.out.format = 0; @@ -218,7 +218,7 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo info->generic.out.num_streams = 0; /* setup a single data stream */ info->generic.out.num_streams = 1 + (dir?dir->count:0); - info->generic.out.streams = talloc_array_p(req->mem_ctx, + info->generic.out.streams = talloc_array_p(req, struct stream_struct, info->generic.out.num_streams); if (!info->generic.out.streams) { @@ -226,7 +226,7 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo } info->generic.out.streams[0].size = st->st_size; info->generic.out.streams[0].alloc_size = st->st_size; - info->generic.out.streams[0].stream_name.s = talloc_strdup(req->mem_ctx,"::$DATA"); + info->generic.out.streams[0].stream_name.s = talloc_strdup(req,"::$DATA"); for (i=0;dir && icount;i++) { s = strchr(dir->files[i].name, ':'); @@ -376,9 +376,9 @@ do_open: return map_nt_error_from_unix(errno); } - f = talloc_p(req->tcon->mem_ctx, struct svfs_file); + f = talloc_p(req->tcon, struct svfs_file); f->fd = fd; - f->name = talloc_strdup(req->tcon->mem_ctx, unix_path); + f->name = talloc_strdup(req->tcon, unix_path); DLIST_ADD(private->open_files, f); @@ -690,7 +690,7 @@ static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, lp_servicename(req->tcon->service)); + fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(req->tcon->service)); fs->generic.out.fs_type = req->tcon->fs_type; return NT_STATUS_OK; @@ -720,8 +720,8 @@ static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs) FILE_PERSISTENT_ACLS; fs->generic.out.max_file_component_length = 255; fs->generic.out.serial_number = 1; - fs->generic.out.fs_type = talloc_strdup(req->mem_ctx, "NTFS"); - fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, + fs->generic.out.fs_type = talloc_strdup(req, "NTFS"); + fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(req->tcon->service)); return NT_STATUS_OK; @@ -755,22 +755,19 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f return NT_STATUS_NOT_SUPPORTED; } - mem_ctx = talloc_init("svfs_search"); - - search = talloc_zero(mem_ctx, sizeof(struct search_state)); + search = talloc_zero(private, sizeof(struct search_state)); if (!search) { return NT_STATUS_NO_MEMORY; } max_count = io->t2ffirst.in.max_count; - dir = svfs_list(mem_ctx, req, io->t2ffirst.in.pattern); + dir = svfs_list(private, req, io->t2ffirst.in.pattern); if (!dir) { talloc_free(mem_ctx); return NT_STATUS_FOOBAR; } - search->mem_ctx = mem_ctx; search->handle = private->next_search_handle; search->dir = dir; @@ -803,7 +800,7 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f /* work out if we are going to keep the search state */ if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - talloc_free(search->mem_ctx); + talloc_free(search); } else { private->next_search_handle++; DLIST_ADD(private->search, search); @@ -893,7 +890,7 @@ found: if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { DLIST_REMOVE(private->search, search); - talloc_free(search->mem_ctx); + talloc_free(search); } return NT_STATUS_OK; @@ -915,7 +912,7 @@ static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_c } DLIST_REMOVE(private->search, search); - talloc_free(search->mem_ctx); + talloc_free(search); return NT_STATUS_OK; } @@ -970,7 +967,7 @@ NTSTATUS ntvfs_simple_init(void) ops.trans = svfs_trans; /* register ourselves with the NTVFS subsystem. We register - under names 'simple' + under names 'simple' */ ops.name = "simple"; ret = register_backend("ntvfs", &ops); -- cgit From 2cbbbe35352e2833a1acceb757538db69f5db5f0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 8 Sep 2004 07:59:52 +0000 Subject: r2251: forgot to add vfs_posix.h in my last commit note that this is just a skeleton so far. More to come soon. (This used to be commit efc8850b9aa9348f5f7c4b342aa76dab1635e7d4) --- source4/ntvfs/posix/vfs_posix.c | 236 +++++++++++++++++++++++++++++++++++++++- source4/ntvfs/posix/vfs_posix.h | 27 +++++ 2 files changed, 261 insertions(+), 2 deletions(-) create mode 100644 source4/ntvfs/posix/vfs_posix.h (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 8269f9bba7..fb53f87f27 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -71,6 +71,209 @@ static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon) return NT_STATUS_OK; } +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS pvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + ioctl interface - we don't do any +*/ +static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +{ + return NT_STATUS_INVALID_PARAMETER; +} + +/* + check if a directory exists +*/ +static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + return info on a pathname +*/ +static NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + query info on a open file +*/ +static NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + open a file +*/ +static NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + create a directory +*/ +static NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + remove a directory +*/ +static NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + rename a set of files +*/ +static NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + copy a set of files +*/ +static NTSTATUS pvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + read from a file +*/ +static NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + write to a file +*/ +static NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + seek in a file +*/ +static NTSTATUS pvfs_seek(struct smbsrv_request *req, struct smb_seek *io) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + flush a file +*/ +static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + close a file +*/ +static NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + exit - closing files? +*/ +static NTSTATUS pvfs_exit(struct smbsrv_request *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + lock a byte range +*/ +static NTSTATUS pvfs_lock(struct smbsrv_request *req, union smb_lock *lck) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + set info on a pathname +*/ +static NTSTATUS pvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + set info on a open file +*/ +static NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, + union smb_setfileinfo *info) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + + +/* + return filesystem space info +*/ +static NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* + return print queue info +*/ +static NTSTATUS pvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* continue a search */ +static NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* close a search */ +static NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* SMBtrans - not used on file shares */ +static NTSTATUS pvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) +{ + return NT_STATUS_ACCESS_DENIED; +} + /* initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem */ @@ -87,9 +290,38 @@ NTSTATUS ntvfs_posix_init(void) /* fill in all the operations */ ops.connect = pvfs_connect; ops.disconnect = pvfs_disconnect; + ops.unlink = pvfs_unlink; + ops.chkpath = pvfs_chkpath; + ops.qpathinfo = pvfs_qpathinfo; + ops.setpathinfo = pvfs_setpathinfo; + ops.open = pvfs_open; + ops.mkdir = pvfs_mkdir; + ops.rmdir = pvfs_rmdir; + ops.rename = pvfs_rename; + ops.copy = pvfs_copy; + ops.ioctl = pvfs_ioctl; + ops.read = pvfs_read; + ops.write = pvfs_write; + ops.seek = pvfs_seek; + ops.flush = pvfs_flush; + ops.close = pvfs_close; + ops.exit = pvfs_exit; + ops.lock = pvfs_lock; + ops.setfileinfo = pvfs_setfileinfo; + ops.qfileinfo = pvfs_qfileinfo; + ops.fsinfo = pvfs_fsinfo; + ops.lpq = pvfs_lpq; + ops.search_first = pvfs_search_first; + ops.search_next = pvfs_search_next; + ops.search_close = pvfs_search_close; + ops.trans = pvfs_trans; + + /* register ourselves with the NTVFS subsystem. We register + under the name 'default' as we wish to be the default + backend, and also register as 'posix' */ + ops.name = "posix"; + ret = register_backend("ntvfs", &ops); - /* register ourselves with the NTVFS subsystem. We register under the name 'default' - as we wish to be the default backend */ ret = register_backend("ntvfs", &ops); if (!NT_STATUS_IS_OK(ret)) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h new file mode 100644 index 0000000000..6b05240f43 --- /dev/null +++ b/source4/ntvfs/posix/vfs_posix.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - header + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* this is the private structure for the posix vfs backend. It is used + to hold per-connection (per tree connect) state information */ +struct pvfs_state { + const char *base_directory; +}; -- cgit From 0e6799177c5d1c0904a904d4ff705d33d74d7d56 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 8 Sep 2004 11:01:18 +0000 Subject: r2252: don't register the same name twice (This used to be commit fdb675bbad1322ddd94c646f67803b9678468a64) --- source4/ntvfs/posix/vfs_posix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index fb53f87f27..ee70e79835 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -284,7 +284,6 @@ NTSTATUS ntvfs_posix_init(void) ZERO_STRUCT(ops); - ops.name = "default"; ops.type = NTVFS_DISK; /* fill in all the operations */ @@ -319,9 +318,10 @@ NTSTATUS ntvfs_posix_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend, and also register as 'posix' */ - ops.name = "posix"; + ops.name = "default"; ret = register_backend("ntvfs", &ops); + ops.name = "posix"; ret = register_backend("ntvfs", &ops); if (!NT_STATUS_IS_OK(ret)) { -- cgit From 59b0902d0864101b9861d8ab59402b3088db7ff7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Sep 2004 10:15:55 +0000 Subject: r2319: let event_merge_contexts() return a pointer to the final context metze (This used to be commit 71aa5eeea73ea42e04ae224914b6815d72c1690a) --- source4/ntvfs/cifs/vfs_cifs.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 078075a11f..c9073b04cf 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -163,10 +163,8 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) private->transport->event.fde->handler = cifs_socket_handler; private->transport->event.fde->private = private; - event_context_merge(tcon->smb_conn->connection->event.ctx, - private->transport->event.ctx); - - private->transport->event.ctx = tcon->smb_conn->connection->event.ctx; + private->transport->event.ctx = event_context_merge(tcon->smb_conn->connection->event.ctx, + private->transport->event.ctx); return NT_STATUS_OK; } -- cgit From 360f125f255fd7d5a172d012c00b3cfbff5a6989 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 13 Sep 2004 13:13:21 +0000 Subject: r2326: remove definition and usage of struct socket_context metze (This used to be commit 1854907da8d577db41de9aa14573d5c8c0092f47) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c9073b04cf..ecc2c7ebcb 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -51,7 +51,7 @@ struct async_info { static void idle_func(struct smbcli_transport *transport, void *p_private) { struct cvfs_private *private = p_private; - if (socket_pending(private->tcon->smb_conn->connection->socket->fde->fd)) { + if (socket_pending(private->tcon->smb_conn->connection->event.fde->fd)) { smbd_process_async(private->tcon->smb_conn); } } -- cgit From 046380c56c35177ccf49d0a40e3771242b134277 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Sep 2004 08:14:10 +0000 Subject: r2403: got rid of a unnecessary mem_ctx in the simple backend (This used to be commit a4dcf005f30afcb2edd57d450ff9b90341c318a2) --- source4/ntvfs/simple/svfs.h | 1 - source4/ntvfs/simple/vfs_simple.c | 2 -- 2 files changed, 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index 373e6dc126..98ce6469a2 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -29,7 +29,6 @@ struct svfs_file { struct search_state { struct search_state *next, *prev; - TALLOC_CTX *mem_ctx; uint16_t handle; uint_t current_index; struct svfs_dir *dir; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 8bce111e9c..11840c8980 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -748,7 +748,6 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f struct svfs_private *private = req->tcon->ntvfs_private; struct search_state *search; union smb_search_data file; - TALLOC_CTX *mem_ctx; uint_t max_count; if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { @@ -764,7 +763,6 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f dir = svfs_list(private, req, io->t2ffirst.in.pattern); if (!dir) { - talloc_free(mem_ctx); return NT_STATUS_FOOBAR; } -- cgit From 03cb4367d67ba9cdedf22df743d25d81093941d7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Sep 2004 08:16:14 +0000 Subject: r2404: the first large lump of posix vfs stuff. this is still very much a skeleton (with many limbs missing too!). I am committing this early to get some feedback on the approach taken. (This used to be commit 40d5cae5ebbfe328e193eadb685df6a370730299) --- source4/ntvfs/config.mk | 8 + source4/ntvfs/posix/pvfs_dirlist.c | 126 +++++++++++++++ source4/ntvfs/posix/pvfs_fileinfo.c | 128 +++++++++++++++ source4/ntvfs/posix/pvfs_resolve.c | 303 +++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_search.c | 250 +++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_shortname.c | 34 ++++ source4/ntvfs/posix/pvfs_unlink.c | 111 +++++++++++++ source4/ntvfs/posix/pvfs_util.c | 56 +++++++ source4/ntvfs/posix/vfs_posix.c | 81 +++++----- source4/ntvfs/posix/vfs_posix.h | 85 +++++++++- 10 files changed, 1145 insertions(+), 37 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_dirlist.c create mode 100644 source4/ntvfs/posix/pvfs_fileinfo.c create mode 100644 source4/ntvfs/posix/pvfs_resolve.c create mode 100644 source4/ntvfs/posix/pvfs_search.c create mode 100644 source4/ntvfs/posix/pvfs_shortname.c create mode 100644 source4/ntvfs/posix/pvfs_unlink.c create mode 100644 source4/ntvfs/posix/pvfs_util.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 25dd51b487..2298fcd554 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -44,6 +44,14 @@ INIT_OBJ_FILES = \ [MODULE::ntvfs_posix] INIT_OBJ_FILES = \ ntvfs/posix/vfs_posix.o +ADD_OBJ_FILES = \ + ntvfs/posix/pvfs_util.o \ + ntvfs/posix/pvfs_search.o \ + ntvfs/posix/pvfs_dirlist.o \ + ntvfs/posix/pvfs_fileinfo.o \ + ntvfs/posix/pvfs_unlink.o \ + ntvfs/posix/pvfs_resolve.o \ + ntvfs/posix/pvfs_shortname.o # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c new file mode 100644 index 0000000000..1b4d01c197 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -0,0 +1,126 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + directory listing functions for posix backend +*/ + +#include "includes.h" +#include "vfs_posix.h" + +/* + a special directory listing case where the pattern has no wildcard. We can just do a single stat() + thus avoiding the more expensive directory scan +*/ +static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filename *name, + const char *pattern, struct pvfs_dir *dir) +{ + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + dir->count = 0; + dir->unix_path = name->full_name; + + dir->names = talloc_array_p(dir, const char *, 1); + if (!dir->names) { + return NT_STATUS_NO_MEMORY; + } + + dir->names[0] = talloc_strdup(dir, pattern); + if (!dir->names[0]) { + return NT_STATUS_NO_MEMORY; + } + + dir->count = 1; + + return NT_STATUS_OK; +} + +/* + read a directory and find all matching file names, returning them in + the structure *dir. The returned names are relative to the directory + + if the pattern matches no files then we return NT_STATUS_OK, with dir->count = 0 +*/ +NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct pvfs_dir *dir) +{ + DIR *odir; + struct dirent *dent; + uint_t allocated = 0; + char *pattern; + + /* split the unix path into a directory + pattern */ + pattern = strrchr(name->full_name, '/'); + if (!pattern) { + /* this should not happen, as pvfs_unix_path is supposed to + return an absolute path */ + return NT_STATUS_UNSUCCESSFUL; + } + + *pattern++ = 0; + + if (!name->has_wildcard) { + return pvfs_list_no_wildcard(pvfs, name, pattern, dir); + } + + dir->count = 0; + dir->unix_path = name->full_name; + dir->names = talloc(dir, 0); + if (!dir->names) { + return NT_STATUS_NO_MEMORY; + } + + odir = opendir(name->full_name); + if (!odir) { + return pvfs_map_errno(pvfs, errno); + } + + while ((dent = readdir(odir))) { + uint_t i = dir->count; + const char *dname = dent->d_name; + + /* check it matches the wildcard pattern */ + if (ms_fnmatch(pattern, dname, PROTOCOL_NT1) != 0) { + continue; + } + + if (dir->count >= allocated) { + allocated = (allocated + 100) * 1.2; + dir->names = talloc_realloc_p(dir->names, const char *, allocated); + if (!dir->names) { + closedir(odir); + return NT_STATUS_NO_MEMORY; + } + } + + dir->names[i] = talloc_strdup(dir, dname); + if (!dir->names[i]) { + closedir(odir); + return NT_STATUS_NO_MEMORY; + } + + dir->count++; + } + + closedir(odir); + + return NT_STATUS_OK; +} + diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c new file mode 100644 index 0000000000..83a577d092 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -0,0 +1,128 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* UNIX filetype mappings. */ +#define UNIX_TYPE_FILE 0 +#define UNIX_TYPE_DIR 1 +#define UNIX_TYPE_SYMLINK 2 +#define UNIX_TYPE_CHARDEV 3 +#define UNIX_TYPE_BLKDEV 4 +#define UNIX_TYPE_FIFO 5 +#define UNIX_TYPE_SOCKET 6 +#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF + + +/* + Return the major devicenumber for UNIX extensions. +*/ +static uint32_t unix_dev_major(dev_t dev) +{ +#if defined(HAVE_DEVICE_MAJOR_FN) + return (uint32)major(dev); +#else + return (uint32)(dev >> 8); +#endif +} + +/* + Return the minor devicenumber for UNIX extensions. +*/ +static uint32_t unix_dev_minor(dev_t dev) +{ +#if defined(HAVE_DEVICE_MINOR_FN) + return (uint32)minor(dev); +#else + return (uint32)(dev & 0xff); +#endif +} + +/* + Return the filetype for UNIX extensions +*/ +static uint32_t unix_filetype(mode_t mode) +{ + if (S_ISREG(mode)) return UNIX_TYPE_FILE; + if (S_ISDIR(mode)) return UNIX_TYPE_DIR; +#ifdef S_ISLNK + if (S_ISLNK(mode)) return UNIX_TYPE_SYMLINK; +#endif +#ifdef S_ISCHR + if (S_ISCHR(mode)) return UNIX_TYPE_CHARDEV; +#endif +#ifdef S_ISBLK + if (S_ISBLK(mode)) return UNIX_TYPE_BLKDEV; +#endif +#ifdef S_ISFIFO + if (S_ISFIFO(mode)) return UNIX_TYPE_FIFO; +#endif +#ifdef S_ISSOCK + if (S_ISSOCK(mode)) return UNIX_TYPE_SOCKET; +#endif + + DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode)); + return UNIX_TYPE_UNKNOWN; +} + + +/* + return all basic information about a file. This call is case-sensitive (it assumes that the + pathnames given have already had case conversion) +*/ +NTSTATUS pvfs_relative_file_info_cs(struct pvfs_state *pvfs, const char *dir_path, + const char *name, struct pvfs_file_info *finfo) +{ + char *full_name = NULL; + struct stat st; + + asprintf(&full_name, "%s/%s", dir_path, name); + if (full_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (stat(full_name, &st) == -1) { + free(full_name); + return pvfs_map_errno(pvfs, errno); + } + + unix_to_nt_time(&finfo->create_time, st.st_ctime); + unix_to_nt_time(&finfo->access_time, st.st_atime); + unix_to_nt_time(&finfo->write_time, st.st_mtime); + unix_to_nt_time(&finfo->change_time, st.st_mtime); + finfo->attrib = 0; + finfo->alloc_size = st.st_size; + finfo->size = st.st_size; + finfo->nlink = st.st_nlink; + finfo->ea_size = 0; + finfo->file_id = st.st_ino; + finfo->unix_uid = st.st_uid; + finfo->unix_gid = st.st_gid; + finfo->unix_file_type = unix_filetype(st.st_mode); + finfo->unix_dev_major = unix_dev_major(st.st_rdev); + finfo->unix_dev_minor = unix_dev_minor(st.st_rdev); + finfo->unix_permissions = unix_perms_to_wire(st.st_mode); + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c new file mode 100644 index 0000000000..66e7a5d103 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -0,0 +1,303 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - filename resolution + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + this is the core code for converting a filename from the format as + given by a client to a posix filename, including any case-matching + required, and checks for legal characters +*/ + + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + compare two filename components. This is where the name mangling hook will go +*/ +static int component_compare(const char *c1, const char *c2) +{ + return StrCaseCmp(c1, c2); +} + +/* + search for a filename in a case insensitive fashion + + TODO: add a cache for previously resolved case-insensitive names + TODO: add mangled name support +*/ +static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename *name) +{ + /* break into a series of components */ + int num_components; + char **components; + char *p, *partial_name; + int i; + + /* break up the full name info pathname components */ + num_components=2; + p = name->full_name + strlen(pvfs->base_directory) + 1; + + for (;*p;p++) { + if (*p == '/') { + num_components++; + } + } + + components = talloc_array_p(name, char *, num_components); + p = name->full_name + strlen(pvfs->base_directory); + *p++ = 0; + + components[0] = name->full_name; + + for (i=1;ist) == 0) { + if (ist.st_mode)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + talloc_free(partial_name); + partial_name = test_name; + if (i == num_components - 1) { + name->exists = True; + } + continue; + } + + dir = opendir(partial_name); + if (!dir) { + return pvfs_map_errno(pvfs, errno); + } + + while ((de = readdir(dir))) { + if (component_compare(components[i], de->d_name) == 0) { + break; + } + } + + if (!de) { + closedir(dir); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + components[i] = talloc_strdup(name, de->d_name); + test_name = talloc_asprintf(name, "%s/%s", partial_name, components[i]); + talloc_free(partial_name); + partial_name = test_name; + + closedir(dir); + } + + if (!name->exists) { + if (stat(partial_name, &name->st) == 0) { + name->exists = True; + } + } + + talloc_free(name->full_name); + name->full_name = partial_name; + + return NT_STATUS_OK; +} + + +/* + convert a CIFS pathname to a unix pathname. Note that this does NOT + take into account case insensitivity, and in fact does not access + the filesystem at all. It is merely a reformatting and charset + checking routine. + + errors are returned if the filename is illegal given the flags +*/ +static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, + uint_t flags, struct pvfs_filename *name) +{ + char *ret, *p; + + name->original_name = cifs_name; + name->stream_name = NULL; + name->has_wildcard = False; + + if (*cifs_name == '\\') { + cifs_name++; + } + + ret = talloc_asprintf(name, "%s/%s", pvfs->base_directory, cifs_name); + if (ret == NULL) { + return NT_STATUS_NO_MEMORY; + } + + p = ret + strlen(pvfs->base_directory) + 1; + + /* now do an in-place conversion of '\' to '/', checking + for legal characters */ + for (;*p;p++) { + switch (*p) { + case '\\': + if (name->has_wildcard) { + /* wildcards are only allowed in the last part + of a name */ + return NT_STATUS_ILLEGAL_CHARACTER; + } + *p = '/'; + break; + case ':': + if (!(flags & PVFS_RESOLVE_STREAMS)) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + name->stream_name = talloc_strdup(name, p+1); + if (name->stream_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + *p-- = 0; + break; + case '*': + case '>': + case '<': + case '?': + case '"': + if (flags & PVFS_RESOLVE_NO_WILDCARD) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + name->has_wildcard = True; + break; + case '/': + case '|': + return NT_STATUS_ILLEGAL_CHARACTER; + } + } + + name->full_name = ret; + + return NT_STATUS_OK; +} + + +/* + resolve a name from relative client format to a struct pvfs_filename + the memory for the filename is made as a talloc child of 'name' + + flags include: + PVFS_RESOLVE_NO_WILDCARD = wildcards are considered illegal characters + PVFS_RESOLVE_STREAMS = stream names are allowed + + TODO: add reserved name checking (for things like LPT1) + TODO: ../ collapsing, and outside share checking +*/ +NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + const char *cifs_name, + uint_t flags, struct pvfs_filename **name) +{ + NTSTATUS status; + + *name = talloc_p(mem_ctx, struct pvfs_filename); + if (*name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + (*name)->exists = False; + + /* do the basic conversion to a unix formatted path, + also checking for allowable characters */ + status = pvfs_unix_path(pvfs, cifs_name, flags, *name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* if it has a wildcard then no point doing a stat() */ + if ((*name)->has_wildcard) { + return NT_STATUS_OK; + } + + /* if we can stat() the full name now then we are done */ + if (stat((*name)->full_name, &(*name)->st) == 0) { + (*name)->exists = True; + return NT_STATUS_OK; + } + + /* the filesystem might be case insensitive, in which + case a search is pointless */ + if (pvfs->flags & PVFS_FLAG_CI_FILESYSTEM) { + return NT_STATUS_OK; + } + + /* search for a matching filename */ + status = pvfs_case_search(pvfs, *name); + + return status; +} + + +/* + do a partial resolve, returning a pvfs_filename structure given a + base path and a relative component. It is an error if the file does + not exist. No case-insensitive matching is done. + + this is used in places like directory searching where we need a pvfs_filename + to pass to a function, but already know the unix base directory and component +*/ +NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + const char *unix_dir, const char *fname, + struct pvfs_filename **name) +{ + *name = talloc_p(mem_ctx, struct pvfs_filename); + if (*name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + (*name)->full_name = talloc_asprintf(mem_ctx, "%s/%s", unix_dir, fname); + if ((*name)->full_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + if (stat((*name)->full_name, &(*name)->st) == -1) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + (*name)->exists = True; + (*name)->has_wildcard = False; + (*name)->original_name = fname; + (*name)->stream_name = NULL; + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c new file mode 100644 index 0000000000..da47bba75a --- /dev/null +++ b/source4/ntvfs/posix/pvfs_search.c @@ -0,0 +1,250 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - directory search functions + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + fill in a single search result for a given info level +*/ +static NTSTATUS fill_search_info(struct pvfs_state *pvfs, + enum smb_search_level level, + const char *unix_path, + const char *name, + uint16_t search_attrib, + uint32_t dir_index, + union smb_search_data *file) +{ + struct pvfs_file_info *finfo; + NTSTATUS status; + + finfo = talloc_p((TALLOC_CTX *)file, struct pvfs_file_info); + if (!finfo) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_relative_file_info_cs(pvfs, unix_path, name, finfo); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(finfo); + return status; + } + + switch (level) { + + case RAW_SEARCH_BOTH_DIRECTORY_INFO: + file->both_directory_info.file_index = dir_index; + file->both_directory_info.create_time = finfo->create_time; + file->both_directory_info.access_time = finfo->access_time; + file->both_directory_info.write_time = finfo->write_time; + file->both_directory_info.change_time = finfo->change_time; + file->both_directory_info.size = finfo->size; + file->both_directory_info.alloc_size = finfo->alloc_size; + file->both_directory_info.attrib = finfo->attrib; + file->both_directory_info.ea_size = finfo->ea_size; + file->both_directory_info.short_name.s = pvfs_short_name(pvfs, (TALLOC_CTX *)file, + unix_path, name); + file->both_directory_info.name.s = name; + break; + } + + talloc_free(finfo); + + return NT_STATUS_OK; +} + +/* + return the next available search handle +*/ +static NTSTATUS pvfs_next_search_handle(struct pvfs_state *pvfs, uint16_t *handle) +{ + struct pvfs_search_state *search; + + if (pvfs->search.num_active_searches >= 0x10000) { + return NT_STATUS_INSUFFICIENT_RESOURCES; + } + + (*handle) = pvfs->search.next_search_handle; + for (search=pvfs->search.open_searches;search;search=search->next) { + if (*handle == search->handle) { + *handle = ((*handle)+1) & 0xFFFF; + continue; + } + } + pvfs->search.next_search_handle = ((*handle)+1) & 0xFFFF; + + return NT_STATUS_OK; +} + +/* + list files in a directory matching a wildcard pattern +*/ +NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct pvfs_dir *dir; + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_search_state *search; + union smb_search_data *file; + uint16_t max_count, reply_count; + uint16_t search_attrib; + const char *pattern; + int i; + NTSTATUS status; + struct pvfs_filename *name; + + switch (io->generic.level) { + case RAW_SEARCH_SEARCH: + max_count = io->search_first.in.max_count; + search_attrib = io->search_first.in.search_attrib; + pattern = io->search_first.in.pattern; + break; + + case RAW_SEARCH_STANDARD: + case RAW_SEARCH_EA_SIZE: + case RAW_SEARCH_DIRECTORY_INFO: + case RAW_SEARCH_FULL_DIRECTORY_INFO: + case RAW_SEARCH_NAME_INFO: + case RAW_SEARCH_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: + case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_UNIX_INFO: + max_count = io->t2ffirst.in.max_count; + search_attrib = io->t2ffirst.in.search_attrib; + pattern = io->t2ffirst.in.pattern; + break; + + case RAW_SEARCH_FCLOSE: + case RAW_SEARCH_GENERIC: + DEBUG(0,("WARNING: Invalid search class %d in pvfs_search_first\n", io->generic.level)); + return NT_STATUS_INVALID_INFO_CLASS; + } + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, pattern, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->has_wildcard && !name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* we initially make search a child of the request, then if we + need to keep it long term we steal it for the private + structure */ + search = talloc_p(req, struct pvfs_search_state); + if (!search) { + return NT_STATUS_NO_MEMORY; + } + + dir = talloc_p(search, struct pvfs_dir); + if (!dir) { + return NT_STATUS_NO_MEMORY; + } + + /* do the actual directory listing */ + status = pvfs_list(pvfs, name, dir); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* we need to give a handle back to the client so it + can continue a search */ + status = pvfs_next_search_handle(pvfs, &search->handle); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + search->dir = dir; + search->current_index = 0; + search->search_attrib = search_attrib; + + if (dir->count < max_count) { + max_count = dir->count; + } + + file = talloc_p(req, union smb_search_data); + if (!file) { + return NT_STATUS_NO_MEMORY; + } + + /* note that fill_search_info() can fail, if for example a + file disappears during a search or we don't have sufficient + permissions to stat() it, or the search_attrib does not + match the files attribute. In that case the name is ignored + and the search continues. */ + for (i=reply_count=0; i < dir->count && reply_count < max_count;i++) { + status = fill_search_info(pvfs, io->generic.level, dir->unix_path, dir->names[i], + search_attrib, i, file); + if (NT_STATUS_IS_OK(status)) { + if (!callback(search_private, file)) { + break; + } + reply_count++; + } + } + + /* not matching any entries is an error */ + if (reply_count == 0) { + return NT_STATUS_NO_MORE_ENTRIES; + } + + search->current_index = i; + + if (io->generic.level == RAW_SEARCH_SEARCH) { + io->search_first.out.count = reply_count; + DEBUG(0,("TODO: handle RAW_SEARCH_SEARCH continue\n")); + } else { + io->t2ffirst.out.count = reply_count; + io->t2ffirst.out.handle = search->handle; + io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; + /* work out if we are going to keep the search state + and allow for a search continue */ + if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + talloc_free(search); + } else { + pvfs->search.num_active_searches++; + pvfs->search.next_search_handle++; + talloc_steal(pvfs, search); + DLIST_ADD(pvfs->search.open_searches, search); + } + } + + return NT_STATUS_OK; +} + +/* continue a search */ +NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* close a search */ +NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c new file mode 100644 index 0000000000..b68f60d5e7 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -0,0 +1,34 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - 8.3 name routines + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* + return the short name for a given entry in a directory +*/ +char *pvfs_short_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + const char *unix_path, const char *name) +{ + return talloc_strndup(mem_ctx, name, 12); +} diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c new file mode 100644 index 0000000000..d93c15f19e --- /dev/null +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -0,0 +1,111 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - unlink + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* + unlink one file +*/ +static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + const char *unix_path, + const char *fname, uint32_t attrib) +{ + struct pvfs_filename *name; + NTSTATUS status; + + /* get a pvfs_filename object */ + status = pvfs_resolve_partial(pvfs, mem_ctx, + unix_path, fname, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* make sure its matches the given attributes */ + if (!pvfs_match_attrib(pvfs, name, attrib)) { + talloc_free(name); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* finally try the actual unlink */ + if (unlink(name->full_name) == -1) { + status = pvfs_map_errno(pvfs, errno); + } + + talloc_free(name); + + return status; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +NTSTATUS pvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +{ + struct pvfs_dir *dir; + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTSTATUS status; + uint32_t i, total_deleted=0; + struct pvfs_filename *name; + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->exists && !name->has_wildcard) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + dir = talloc_p(req, struct pvfs_dir); + if (dir == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* get list of matching files */ + status = pvfs_list(pvfs, name, dir); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (dir->count == 0) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + for (i=0;icount;i++) { + status = pvfs_unlink_one(pvfs, req, dir->unix_path, dir->names[i], unl->in.attrib); + if (NT_STATUS_IS_OK(status)) { + total_deleted++; + } + } + + if (total_deleted == 0) { + return status; + } + + return NT_STATUS_OK; +} + + diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c new file mode 100644 index 0000000000..2524261245 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_util.c @@ -0,0 +1,56 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + utility functions for posix backend +*/ + +#include "includes.h" +#include "vfs_posix.h" + +/* + return True if a string contains one of the CIFS wildcard characters +*/ +BOOL pvfs_has_wildcard(const char *str) +{ + if (strpbrk(str, "*?<>\"")) { + return True; + } + return False; +} + +/* + map a unix errno to a NTSTATUS +*/ +NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno) +{ + return map_nt_error_from_unix(unix_errno); +} + + +/* + check if a filename has an attribute matching the given attribute search value + this is used by calls like unlink and search which take an attribute + and only include special files if they match the given attribute +*/ +BOOL pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, uint32_t attrib) +{ + /* TODO: add attribute conversion */ + return True; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ee70e79835..86179debc5 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -39,6 +39,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) struct smbsrv_tcon *tcon = req->tcon; struct pvfs_state *pvfs; struct stat st; + char *base_directory; DEBUG(0,("WARNING: the posix vfs handler is incomplete - you probably want \"ntvfs handler = simple\"\n")); @@ -46,8 +47,13 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) if (pvfs == NULL) { return NT_STATUS_NO_MEMORY; } + ZERO_STRUCTP(pvfs); - pvfs->base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); + /* for simplicity of path construction, remove any trailing slash now */ + base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); + trim_string(base_directory, NULL, "/"); + + pvfs->base_directory = base_directory; /* the directory must exist. Note that we deliberately don't check that it is readable */ @@ -59,6 +65,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); + tcon->ntvfs_private = pvfs; return NT_STATUS_OK; } @@ -71,21 +78,12 @@ static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon) return NT_STATUS_OK; } -/* - delete a file - the dirtype specifies the file types to include in the search. - The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) -*/ -static NTSTATUS pvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - - /* ioctl interface - we don't do any */ static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { + DEBUG(0,("pvfs_ioctl not implemented\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -94,7 +92,25 @@ static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) */ static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { - return NT_STATUS_NOT_IMPLEMENTED; + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_filename *name; + NTSTATUS status; + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (!S_ISDIR(name->st.st_mode)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + return NT_STATUS_OK; } /* @@ -102,6 +118,7 @@ static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) */ static NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { + DEBUG(0,("pvfs_qpathinfo not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -110,6 +127,7 @@ static NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *i */ static NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { + DEBUG(0,("pvfs_qfileinfo not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -119,6 +137,7 @@ static NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i */ static NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) { + DEBUG(0,("pvfs_open not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -127,6 +146,7 @@ static NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) */ static NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { + DEBUG(0,("pvfs_mkdir not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -135,6 +155,7 @@ static NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) */ static NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { + DEBUG(0,("pvfs_rmdir not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -143,6 +164,7 @@ static NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) */ static NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) { + DEBUG(0,("pvfs_rename not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -151,6 +173,7 @@ static NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) */ static NTSTATUS pvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) { + DEBUG(0,("pvfs_copy not implemented\n")); return NT_STATUS_NOT_SUPPORTED; } @@ -159,6 +182,7 @@ static NTSTATUS pvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) */ static NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) { + DEBUG(0,("pvfs_read not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -167,6 +191,7 @@ static NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) */ static NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) { + DEBUG(0,("pvfs_write not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -175,6 +200,7 @@ static NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) */ static NTSTATUS pvfs_seek(struct smbsrv_request *req, struct smb_seek *io) { + DEBUG(0,("pvfs_seek not implemented\n")); return NT_STATUS_NOT_SUPPORTED; } @@ -183,6 +209,7 @@ static NTSTATUS pvfs_seek(struct smbsrv_request *req, struct smb_seek *io) */ static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io) { + DEBUG(0,("pvfs_flush not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -191,6 +218,7 @@ static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io) */ static NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) { + DEBUG(0,("pvfs_close not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -199,6 +227,7 @@ static NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) */ static NTSTATUS pvfs_exit(struct smbsrv_request *req) { + DEBUG(0,("pvfs_exit not implemented\n")); return NT_STATUS_NOT_SUPPORTED; } @@ -207,6 +236,7 @@ static NTSTATUS pvfs_exit(struct smbsrv_request *req) */ static NTSTATUS pvfs_lock(struct smbsrv_request *req, union smb_lock *lck) { + DEBUG(0,("pvfs_lock not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -215,6 +245,7 @@ static NTSTATUS pvfs_lock(struct smbsrv_request *req, union smb_lock *lck) */ static NTSTATUS pvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { + DEBUG(0,("pvfs_setpathinfo not implemented\n")); return NT_STATUS_NOT_SUPPORTED; } @@ -224,6 +255,7 @@ static NTSTATUS pvfs_setpathinfo(struct smbsrv_request *req, union smb_setfilein static NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { + DEBUG(0,("pvfs_setfileinfo not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -233,6 +265,7 @@ static NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, */ static NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { + DEBUG(0,("pvfs_fsinfo not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; } @@ -244,30 +277,6 @@ static NTSTATUS pvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) return NT_STATUS_NOT_SUPPORTED; } -/* - list files in a directory matching a wildcard pattern -*/ -static NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* continue a search */ -static NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* close a search */ -static NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - /* SMBtrans - not used on file shares */ static NTSTATUS pvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 6b05240f43..1e6d763fc1 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. - POSIX NTVFS backend - header + POSIX NTVFS backend - structure definitions Copyright (C) Andrew Tridgell 2004 @@ -20,8 +20,91 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef _VFS_POSIX_H_ +#define _VFS_POSIX_H_ + /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ struct pvfs_state { const char *base_directory; + + uint_t flags; + + struct { + /* a linked list of open searches */ + struct pvfs_search_state *open_searches; + + /* search handles are returned to the clients so they + can continue searches */ + uint16_t next_search_handle; + + /* count of active searches */ + uint_t num_active_searches; + + /* during trans2 search continuations we need to use + the initial search attributes */ + uint16_t search_attrib; + } search; +}; + +/* + this is the structure returned by pvfs_resolve_name(). It holds the posix details of + a filename passed by the client to any function +*/ +struct pvfs_filename { + const char *original_name; + char *full_name; + const char *stream_name; + BOOL has_wildcard; + BOOL exists; + struct stat st; +}; + + +/* this holds a list of file names for a search. We deliberately do + not hold the file stat information here to minimise the memory + overhead of idle searches */ +struct pvfs_dir { + uint_t count; + const char *unix_path; + const char **names; +}; + +/* the state of a search started with pvfs_search_first() */ +struct pvfs_search_state { + struct pvfs_search_state *next, *prev; + uint16_t search_attrib; + uint16_t handle; + uint_t current_index; + struct pvfs_dir *dir; +}; + + +/* this is the basic information needed about a file from the filesystem */ +struct pvfs_file_info { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t attrib; + uint64_t alloc_size; + uint64_t size; + uint32_t nlink; + uint32_t ea_size; + uint64_t file_id; + uint64_t unix_uid; + uint64_t unix_gid; + uint32_t unix_file_type; + uint64_t unix_dev_major; + uint64_t unix_dev_minor; + uint64_t unix_permissions; }; + +/* flags to pvfs_resolve_name() */ +#define PVFS_RESOLVE_NO_WILDCARD (1<<0) +#define PVFS_RESOLVE_STREAMS (1<<1) + +/* flags in pvfs->flags */ +#define PVFS_FLAG_CI_FILESYSTEM (1<<0) /* the filesystem is case insensitive */ + +#endif /* _VFS_POSIX_H_ */ -- cgit From 677d1bc487c345b899ed0e7ec2cd00a281051a50 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Sep 2004 07:26:01 +0000 Subject: r2434: separate "attrib" and "ex_attrib" elements for DOS attributes is pointless (This used to be commit 5fcad57128e47d4d6c0f387d5563d9de2fc08351) --- source4/ntvfs/simple/vfs_simple.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 11840c8980..34a9c27f34 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -203,7 +203,6 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo info->generic.out.num_eas = 0; info->generic.out.fname.s = talloc_strdup(req, short_name); info->generic.out.alt_fname.s = talloc_strdup(req, short_name); - info->generic.out.ex_attrib = 0; info->generic.out.compressed_size = 0; info->generic.out.format = 0; info->generic.out.unit_shift = 0; -- cgit From 8a1c3ddd947039bf3b62efd94d3429359b593e15 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Sep 2004 07:28:43 +0000 Subject: r2436: the second big lump of posix vfs code. this is still just a skeleton, and many of the functions are just based on the simple vfs backend, they are there to allow me to run smbtorture tests against the real parts of the posix backend. (This used to be commit f2fa7fe565e89360dba3bb5434d3a6a36f398348) --- source4/ntvfs/config.mk | 7 ++ source4/ntvfs/posix/pvfs_fileinfo.c | 76 ++++++++------ source4/ntvfs/posix/pvfs_fsinfo.c | 65 ++++++++++++ source4/ntvfs/posix/pvfs_mkdir.c | 85 ++++++++++++++++ source4/ntvfs/posix/pvfs_open.c | 175 +++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_qfileinfo.c | 129 ++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_read.c | 57 +++++++++++ source4/ntvfs/posix/pvfs_resolve.c | 46 +++++++-- source4/ntvfs/posix/pvfs_search.c | 51 +++++----- source4/ntvfs/posix/pvfs_setfileinfo.c | 69 +++++++++++++ source4/ntvfs/posix/pvfs_shortname.c | 7 +- source4/ntvfs/posix/pvfs_unlink.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 79 +++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 112 ++++----------------- source4/ntvfs/posix/vfs_posix.h | 50 ++++++---- 15 files changed, 824 insertions(+), 186 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_fsinfo.c create mode 100644 source4/ntvfs/posix/pvfs_mkdir.c create mode 100644 source4/ntvfs/posix/pvfs_open.c create mode 100644 source4/ntvfs/posix/pvfs_qfileinfo.c create mode 100644 source4/ntvfs/posix/pvfs_read.c create mode 100644 source4/ntvfs/posix/pvfs_setfileinfo.c create mode 100644 source4/ntvfs/posix/pvfs_write.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 2298fcd554..416b14a3b3 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -50,6 +50,13 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_dirlist.o \ ntvfs/posix/pvfs_fileinfo.o \ ntvfs/posix/pvfs_unlink.o \ + ntvfs/posix/pvfs_mkdir.o \ + ntvfs/posix/pvfs_open.o \ + ntvfs/posix/pvfs_read.o \ + ntvfs/posix/pvfs_write.o \ + ntvfs/posix/pvfs_fsinfo.o \ + ntvfs/posix/pvfs_qfileinfo.o \ + ntvfs/posix/pvfs_setfileinfo.o \ ntvfs/posix/pvfs_resolve.o \ ntvfs/posix/pvfs_shortname.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 83a577d092..c5a3a1c666 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -87,42 +87,54 @@ static uint32_t unix_filetype(mode_t mode) } -/* - return all basic information about a file. This call is case-sensitive (it assumes that the - pathnames given have already had case conversion) -*/ -NTSTATUS pvfs_relative_file_info_cs(struct pvfs_state *pvfs, const char *dir_path, - const char *name, struct pvfs_file_info *finfo) +/**************************************************************************** + Change a unix mode to a dos mode. +****************************************************************************/ +static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) { - char *full_name = NULL; - struct stat st; - - asprintf(&full_name, "%s/%s", dir_path, name); - if (full_name == NULL) { - return NT_STATUS_NO_MEMORY; + int result = 0; + + if ((st->st_mode & S_IWUSR) == 0) + result |= FILE_ATTRIBUTE_READONLY; + + if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0)) + result |= FILE_ATTRIBUTE_ARCHIVE; + + if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0)) + result |= FILE_ATTRIBUTE_SYSTEM; + + if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0)) + result |= FILE_ATTRIBUTE_HIDDEN; + + if (S_ISDIR(st->st_mode)) + result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY); + +#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE) + if (st->st_size > st->st_blocks * (off_t)st->st_blksize) { + result |= FILE_ATTRIBUTE_SPARSE; } +#endif + + return result; +} + - if (stat(full_name, &st) == -1) { - free(full_name); - return pvfs_map_errno(pvfs, errno); - } - unix_to_nt_time(&finfo->create_time, st.st_ctime); - unix_to_nt_time(&finfo->access_time, st.st_atime); - unix_to_nt_time(&finfo->write_time, st.st_mtime); - unix_to_nt_time(&finfo->change_time, st.st_mtime); - finfo->attrib = 0; - finfo->alloc_size = st.st_size; - finfo->size = st.st_size; - finfo->nlink = st.st_nlink; - finfo->ea_size = 0; - finfo->file_id = st.st_ino; - finfo->unix_uid = st.st_uid; - finfo->unix_gid = st.st_gid; - finfo->unix_file_type = unix_filetype(st.st_mode); - finfo->unix_dev_major = unix_dev_major(st.st_rdev); - finfo->unix_dev_minor = unix_dev_minor(st.st_rdev); - finfo->unix_permissions = unix_perms_to_wire(st.st_mode); +/* + fill in the dos file attributes for a file +*/ +NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) +{ + /* for now just use the simple samba mapping */ + unix_to_nt_time(&name->dos.create_time, name->st.st_ctime); + unix_to_nt_time(&name->dos.access_time, name->st.st_atime); + unix_to_nt_time(&name->dos.write_time, name->st.st_mtime); + unix_to_nt_time(&name->dos.change_time, name->st.st_mtime); + name->dos.attrib = dos_mode_from_stat(pvfs, &name->st); + name->dos.alloc_size = name->st.st_size; + name->dos.nlink = name->st.st_nlink; + name->dos.ea_size = 0; + name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c new file mode 100644 index 0000000000..826e331b84 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -0,0 +1,65 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - fsinfo + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* + return filesystem space info +*/ +NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct stat st; + + if (fs->generic.level != RAW_QFS_GENERIC) { + return ntvfs_map_fsinfo(req, fs); + } + + if (sys_fsusage(pvfs->base_directory, + &fs->generic.out.blocks_free, + &fs->generic.out.blocks_total) == -1) { + return pvfs_map_errno(pvfs, errno); + } + + fs->generic.out.block_size = 512; + + if (stat(pvfs->base_directory, &st) != 0) { + return NT_STATUS_DISK_CORRUPT_ERROR; + } + + fs->generic.out.fs_id = st.st_ino; + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.serial_number = st.st_ino; + fs->generic.out.fs_attr = 0; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.device_type = 0; + fs->generic.out.device_characteristics = 0; + fs->generic.out.quota_soft = 0; + fs->generic.out.quota_hard = 0; + fs->generic.out.quota_flags = 0; + fs->generic.out.volume_name = talloc_strdup(req, pvfs->share_name); + fs->generic.out.fs_type = req->tcon->fs_type; + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c new file mode 100644 index 0000000000..4881326ecb --- /dev/null +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -0,0 +1,85 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - mkdir and rmdir + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + create a directory +*/ +NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTSTATUS status; + struct pvfs_filename *name; + + if (md->generic.level != RAW_MKDIR_MKDIR) { + return NT_STATUS_INVALID_LEVEL; + } + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (name->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + /* TODO: this is a temporary implementation to allow other + tests to run */ + + if (mkdir(name->full_name, 0777) == -1) { + return pvfs_map_errno(pvfs, errno); + } + + return NT_STATUS_OK; +} + +/* + remove a directory +*/ +NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTSTATUS status; + struct pvfs_filename *name; + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, rd->in.path, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (rmdir(name->full_name) == -1) { + return pvfs_map_errno(pvfs, errno); + } + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c new file mode 100644 index 0000000000..74badb2443 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_open.c @@ -0,0 +1,175 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - open and close + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* + find open file handle given fnum +*/ +struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum) +{ + struct pvfs_file *f; + for (f=pvfs->open_files;f;f=f->next) { + if (f->fnum == fnum) { + return f; + } + } + return NULL; +} + +/* + open a file + TODO: this is a temporary implementation derived from the simple backend + its purpose is to allow other tests to run +*/ +NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + int fd, flags; + struct pvfs_filename *name; + struct pvfs_file *f; + NTSTATUS status; + + if (io->generic.level != RAW_OPEN_GENERIC) { + return ntvfs_map_open(req, io); + } + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_SUPERSEDE: + case NTCREATEX_DISP_OVERWRITE_IF: + flags = O_CREAT | O_TRUNC; + break; + case NTCREATEX_DISP_OPEN: + case NTCREATEX_DISP_OVERWRITE: + flags = 0; + break; + case NTCREATEX_DISP_CREATE: + flags = O_CREAT | O_EXCL; + break; + case NTCREATEX_DISP_OPEN_IF: + flags = O_CREAT; + break; + default: + flags = 0; + break; + } + + flags |= O_RDWR; + + if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { + flags = O_RDONLY | O_DIRECTORY; + if (pvfs->flags & PVFS_FLAG_READONLY) { + goto do_open; + } + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_CREATE: + if (mkdir(name->full_name, 0755) == -1) { + return pvfs_map_errno(pvfs,errno); + } + break; + case NTCREATEX_DISP_OPEN_IF: + if (mkdir(name->full_name, 0755) == -1 && errno != EEXIST) { + return pvfs_map_errno(pvfs,errno); + } + break; + } + } + +do_open: + fd = open(name->full_name, flags, 0644); + if (fd == -1) { + if (errno == 0) + errno = ENOENT; + return pvfs_map_errno(pvfs,errno); + } + + f = talloc_p(pvfs, struct pvfs_file); + if (f == NULL) { + close(fd); + return NT_STATUS_NO_MEMORY; + } + + /* re-resolve the open fd */ + status = pvfs_resolve_name_fd(pvfs, fd, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + f->fnum = fd; + f->fd = fd; + f->name = talloc_steal(f, name); + + DLIST_ADD(pvfs->open_files, f); + + ZERO_STRUCT(io->generic.out); + + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.fnum = f->fnum; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.is_directory = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)?1:0; + + return NT_STATUS_OK; +} + + +/* + close a file +*/ +NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_file *f; + + if (io->generic.level != RAW_CLOSE_CLOSE) { + /* we need a mapping function */ + return NT_STATUS_INVALID_LEVEL; + } + + f = pvfs_find_fd(pvfs, io->close.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + if (close(f->fd) != 0) { + return pvfs_map_errno(pvfs, errno); + } + + DLIST_REMOVE(pvfs->open_files, f); + talloc_free(f); + + return NT_STATUS_OK; +} + diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c new file mode 100644 index 0000000000..691ba91532 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -0,0 +1,129 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - read + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* + approximately map a struct pvfs_filename to a generic fileinfo struct +*/ +static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + struct pvfs_filename *name, union smb_fileinfo *info) +{ + info->generic.out.create_time = name->dos.create_time; + info->generic.out.access_time = name->dos.access_time; + info->generic.out.write_time = name->dos.write_time; + info->generic.out.change_time = name->dos.change_time; + + info->generic.out.alloc_size = name->dos.alloc_size; + info->generic.out.size = name->st.st_size; + info->generic.out.attrib = name->dos.attrib; + info->generic.out.nlink = name->dos.nlink; + info->generic.out.directory = (name->dos.attrib&FILE_ATTRIBUTE_DIRECTORY)?1:0; + info->generic.out.file_id = name->dos.file_id; + + /* REWRITE: TODO stuff in here */ + info->generic.out.delete_pending = 0; + info->generic.out.ea_size = 0; + info->generic.out.num_eas = 0; + info->generic.out.fname.s = name->original_name; + info->generic.out.alt_fname.s = pvfs_short_name(pvfs, name); + info->generic.out.compressed_size = name->st.st_size; + info->generic.out.format = 0; + info->generic.out.unit_shift = 0; + info->generic.out.chunk_shift = 0; + info->generic.out.cluster_shift = 0; + + info->generic.out.access_flags = 0; + info->generic.out.position = 0; + info->generic.out.mode = 0; + info->generic.out.alignment_requirement = 0; + info->generic.out.reparse_tag = 0; + + /* setup a single data stream */ + info->generic.out.num_streams = 1; + info->generic.out.streams = talloc_array_p(mem_ctx, + struct stream_struct, + info->generic.out.num_streams); + if (!info->generic.out.streams) { + return NT_STATUS_NO_MEMORY; + } + info->generic.out.streams[0].size = name->st.st_size; + info->generic.out.streams[0].alloc_size = name->st.st_size; + info->generic.out.streams[0].stream_name.s = talloc_strdup(mem_ctx, "::$DATA"); + + return NT_STATUS_OK; +} + +/* + return info on a pathname +*/ +NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_filename *name; + NTSTATUS status; + + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qpathinfo(req, info); + } + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + return pvfs_map_fileinfo(pvfs, req, name, info); +} + +/* + query info on a open file +*/ +NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_file *f; + NTSTATUS status; + + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qfileinfo(req, info); + } + + f = pvfs_find_fd(pvfs, info->generic.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + /* update the file information */ + status = pvfs_resolve_name_fd(pvfs, f->fd, f->name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return pvfs_map_fileinfo(pvfs, req, f->name, info); +} diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c new file mode 100644 index 0000000000..d30645e76d --- /dev/null +++ b/source4/ntvfs/posix/pvfs_read.c @@ -0,0 +1,57 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - read + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + read from a file +*/ +NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) +{ + struct pvfs_private *pvfs = req->tcon->ntvfs_private; + ssize_t ret; + struct pvfs_file *f; + + if (rd->generic.level != RAW_READ_READX) { + return NT_STATUS_NOT_SUPPORTED; + } + + f = pvfs_find_fd(pvfs, rd->readx.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + ret = pread(f->fd, + rd->readx.out.data, + rd->readx.in.maxcnt, + rd->readx.in.offset); + if (ret == -1) { + return pvfs_map_errno(pvfs, errno); + } + + rd->readx.out.nread = ret; + rd->readx.out.remaining = 0; /* should fill this in? */ + rd->readx.out.compaction_mode = 0; + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 66e7a5d103..5c535c9880 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -116,11 +116,13 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * } if (!de) { - closedir(dir); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + if (i < num_components-1) { + closedir(dir); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + } else { + components[i] = talloc_strdup(name, de->d_name); } - - components[i] = talloc_strdup(name, de->d_name); test_name = talloc_asprintf(name, "%s/%s", partial_name, components[i]); talloc_free(partial_name); partial_name = test_name; @@ -137,6 +139,10 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * talloc_free(name->full_name); name->full_name = partial_name; + if (name->exists) { + return pvfs_fill_dos_info(pvfs, name); + } + return NT_STATUS_OK; } @@ -154,7 +160,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, { char *ret, *p; - name->original_name = cifs_name; + name->original_name = talloc_strdup(name, cifs_name); name->stream_name = NULL; name->has_wildcard = False; @@ -252,7 +258,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* if we can stat() the full name now then we are done */ if (stat((*name)->full_name, &(*name)->st) == 0) { (*name)->exists = True; - return NT_STATUS_OK; + return pvfs_fill_dos_info(pvfs, *name); } /* the filesystem might be case insensitive, in which @@ -280,12 +286,14 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, const char *unix_dir, const char *fname, struct pvfs_filename **name) { + NTSTATUS status; + *name = talloc_p(mem_ctx, struct pvfs_filename); if (*name == NULL) { return NT_STATUS_NO_MEMORY; } - (*name)->full_name = talloc_asprintf(mem_ctx, "%s/%s", unix_dir, fname); + (*name)->full_name = talloc_asprintf(*name, "%s/%s", unix_dir, fname); if ((*name)->full_name == NULL) { return NT_STATUS_NO_MEMORY; } @@ -296,8 +304,28 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, (*name)->exists = True; (*name)->has_wildcard = False; - (*name)->original_name = fname; + (*name)->original_name = talloc_strdup(*name, fname); (*name)->stream_name = NULL; - return NT_STATUS_OK; + status = pvfs_fill_dos_info(pvfs, *name); + + return status; +} + + +/* + fill in the pvfs_filename info for an open file, given the current + info for a (possibly) non-open file. This is used by places that need + to update the pvfs_filename stat information, and by pvfs_open() +*/ +NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, + struct pvfs_filename *name) +{ + if (fstat(fd, &name->st) == -1) { + return NT_STATUS_INVALID_HANDLE; + } + + name->exists = True; + + return pvfs_fill_dos_info(pvfs, name); } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index da47bba75a..548d7ad77e 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -29,45 +29,36 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, enum smb_search_level level, const char *unix_path, - const char *name, + const char *fname, uint16_t search_attrib, uint32_t dir_index, union smb_search_data *file) { - struct pvfs_file_info *finfo; + struct pvfs_filename *name; NTSTATUS status; - finfo = talloc_p((TALLOC_CTX *)file, struct pvfs_file_info); - if (!finfo) { - return NT_STATUS_NO_MEMORY; - } - - status = pvfs_relative_file_info_cs(pvfs, unix_path, name, finfo); + status = pvfs_resolve_partial(pvfs, file, unix_path, fname, &name); if (!NT_STATUS_IS_OK(status)) { - talloc_free(finfo); return status; } - + switch (level) { case RAW_SEARCH_BOTH_DIRECTORY_INFO: file->both_directory_info.file_index = dir_index; - file->both_directory_info.create_time = finfo->create_time; - file->both_directory_info.access_time = finfo->access_time; - file->both_directory_info.write_time = finfo->write_time; - file->both_directory_info.change_time = finfo->change_time; - file->both_directory_info.size = finfo->size; - file->both_directory_info.alloc_size = finfo->alloc_size; - file->both_directory_info.attrib = finfo->attrib; - file->both_directory_info.ea_size = finfo->ea_size; - file->both_directory_info.short_name.s = pvfs_short_name(pvfs, (TALLOC_CTX *)file, - unix_path, name); - file->both_directory_info.name.s = name; + file->both_directory_info.create_time = name->dos.create_time; + file->both_directory_info.access_time = name->dos.access_time; + file->both_directory_info.write_time = name->dos.write_time; + file->both_directory_info.change_time = name->dos.change_time; + file->both_directory_info.size = name->st.st_size; + file->both_directory_info.alloc_size = name->dos.alloc_size; + file->both_directory_info.attrib = name->dos.attrib; + file->both_directory_info.ea_size = name->dos.ea_size; + file->both_directory_info.short_name.s = pvfs_short_name(pvfs, name); + file->both_directory_info.name.s = fname; break; } - talloc_free(finfo); - return NT_STATUS_OK; } @@ -104,7 +95,6 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i struct pvfs_dir *dir; struct pvfs_state *pvfs = req->tcon->ntvfs_private; struct pvfs_search_state *search; - union smb_search_data *file; uint16_t max_count, reply_count; uint16_t search_attrib; const char *pattern; @@ -183,17 +173,19 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i max_count = dir->count; } - file = talloc_p(req, union smb_search_data); - if (!file) { - return NT_STATUS_NO_MEMORY; - } - /* note that fill_search_info() can fail, if for example a file disappears during a search or we don't have sufficient permissions to stat() it, or the search_attrib does not match the files attribute. In that case the name is ignored and the search continues. */ for (i=reply_count=0; i < dir->count && reply_count < max_count;i++) { + union smb_search_data *file; + + file = talloc_p(req, union smb_search_data); + if (!file) { + return NT_STATUS_NO_MEMORY; + } + status = fill_search_info(pvfs, io->generic.level, dir->unix_path, dir->names[i], search_attrib, i, file); if (NT_STATUS_IS_OK(status)) { @@ -202,6 +194,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i } reply_count++; } + talloc_free(file); } /* not matching any entries is an error */ diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c new file mode 100644 index 0000000000..a271b43d38 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -0,0 +1,69 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - setfileinfo + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + set info on a open file +*/ +NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, + union smb_setfileinfo *info) +{ + struct pvfs_private *pvfs = req->tcon->ntvfs_private; + struct utimbuf unix_times; + struct pvfs_file *f; + + f = pvfs_find_fd(pvfs, info->generic.file.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + switch (info->generic.level) { + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + if (ftruncate(f->fd, + info->end_of_file_info.in.size) != 0) { + return pvfs_map_errno(pvfs, errno); + } + break; + case RAW_SFILEINFO_SETATTRE: + unix_times.actime = info->setattre.in.access_time; + unix_times.modtime = info->setattre.in.write_time; + + if (unix_times.actime == 0 && unix_times.modtime == 0) { + break; + } + + /* set modify time = to access time if modify time was 0 */ + if (unix_times.actime != 0 && unix_times.modtime == 0) { + unix_times.modtime = unix_times.actime; + } + + /* Set the date on this file */ + if (utime(f->name->full_name, &unix_times) == -1) { + return NT_STATUS_ACCESS_DENIED; + } + break; + } + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index b68f60d5e7..fe6fd8e030 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -26,9 +26,10 @@ /* return the short name for a given entry in a directory + TODO: this is obviously not very useful in its current form ! */ -char *pvfs_short_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, - const char *unix_path, const char *name) +char *pvfs_short_name(struct pvfs_state *pvfs, struct pvfs_filename *name) { - return talloc_strndup(mem_ctx, name, 12); + char *p = strrchr(name->full_name, '/'); + return talloc_strndup(name, p+1, 12); } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index d93c15f19e..98151d4e75 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -63,8 +63,8 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, */ NTSTATUS pvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { - struct pvfs_dir *dir; struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_dir *dir; NTSTATUS status; uint32_t i, total_deleted=0; struct pvfs_filename *name; diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c new file mode 100644 index 0000000000..4194ced431 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_write.c @@ -0,0 +1,79 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - write + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* + write to a file +*/ +NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) +{ + struct pvfs_private *pvfs = req->tcon->ntvfs_private; + ssize_t ret; + struct pvfs_file *f; + + switch (wr->generic.level) { + case RAW_WRITE_WRITEX: + f = pvfs_find_fd(pvfs, wr->writex.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + ret = pwrite(f->fd, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; + + case RAW_WRITE_WRITE: + f = pvfs_find_fd(pvfs, wr->write.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + if (wr->write.in.count == 0) { + /* a truncate! */ + ret = ftruncate(f->fd, wr->write.in.offset); + } else { + ret = pwrite(f->fd, + wr->write.in.data, + wr->write.in.count, + wr->write.in.offset); + } + if (ret == -1) { + return pvfs_map_errno(pvfs, errno); + } + + wr->write.out.nwritten = ret; + + return NT_STATUS_OK; + } + + return NT_STATUS_NOT_SUPPORTED; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 86179debc5..b2c9d81086 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -28,6 +28,22 @@ #include "vfs_posix.h" +/* + setup config options for a posix share +*/ +static void pvfs_setup_options(struct pvfs_state *pvfs) +{ + int snum = pvfs->tcon->service; + + if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; + if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; + if (lp_map_system(snum)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; + if (lp_readonly(snum)) pvfs->flags |= PVFS_FLAG_READONLY; + + pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); +} + + /* connect to a share - used when a tree_connect operation comes in. For a disk based backend we needs to ensure that the base @@ -53,6 +69,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); trim_string(base_directory, NULL, "/"); + pvfs->tcon = tcon; pvfs->base_directory = base_directory; /* the directory must exist. Note that we deliberately don't @@ -67,6 +84,8 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) tcon->dev_type = talloc_strdup(tcon, "A:"); tcon->ntvfs_private = pvfs; + pvfs_setup_options(pvfs); + return NT_STATUS_OK; } @@ -113,52 +132,6 @@ static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) return NT_STATUS_OK; } -/* - return info on a pathname -*/ -static NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) -{ - DEBUG(0,("pvfs_qpathinfo not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* - query info on a open file -*/ -static NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) -{ - DEBUG(0,("pvfs_qfileinfo not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - - -/* - open a file -*/ -static NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) -{ - DEBUG(0,("pvfs_open not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* - create a directory -*/ -static NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) -{ - DEBUG(0,("pvfs_mkdir not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* - remove a directory -*/ -static NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) -{ - DEBUG(0,("pvfs_rmdir not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - /* rename a set of files */ @@ -177,24 +150,6 @@ static NTSTATUS pvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) return NT_STATUS_NOT_SUPPORTED; } -/* - read from a file -*/ -static NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) -{ - DEBUG(0,("pvfs_read not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* - write to a file -*/ -static NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) -{ - DEBUG(0,("pvfs_write not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - /* seek in a file */ @@ -213,15 +168,6 @@ static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io) return NT_STATUS_NOT_IMPLEMENTED; } -/* - close a file -*/ -static NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) -{ - DEBUG(0,("pvfs_close not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - /* exit - closing files? */ @@ -249,26 +195,6 @@ static NTSTATUS pvfs_setpathinfo(struct smbsrv_request *req, union smb_setfilein return NT_STATUS_NOT_SUPPORTED; } -/* - set info on a open file -*/ -static NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, - union smb_setfileinfo *info) -{ - DEBUG(0,("pvfs_setfileinfo not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - - -/* - return filesystem space info -*/ -static NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) -{ - DEBUG(0,("pvfs_fsinfo not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - /* return print queue info */ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 1e6d763fc1..12955ced5c 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -26,8 +26,10 @@ /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ struct pvfs_state { + struct smbsrv_tcon *tcon; const char *base_directory; + const char *share_name; uint_t flags; struct { @@ -45,6 +47,22 @@ struct pvfs_state { the initial search attributes */ uint16_t search_attrib; } search; + + struct pvfs_file *open_files; +}; + + +/* this is the basic information needed about a file from the filesystem */ +struct pvfs_dos_fileinfo { + NTTIME create_time; + NTTIME access_time; + NTTIME write_time; + NTTIME change_time; + uint32_t attrib; + uint64_t alloc_size; + uint32_t nlink; + uint32_t ea_size; + uint64_t file_id; }; /* @@ -58,6 +76,7 @@ struct pvfs_filename { BOOL has_wildcard; BOOL exists; struct stat st; + struct pvfs_dos_fileinfo dos; }; @@ -79,32 +98,25 @@ struct pvfs_search_state { struct pvfs_dir *dir; }; - -/* this is the basic information needed about a file from the filesystem */ -struct pvfs_file_info { - NTTIME create_time; - NTTIME access_time; - NTTIME write_time; - NTTIME change_time; - uint32_t attrib; - uint64_t alloc_size; - uint64_t size; - uint32_t nlink; - uint32_t ea_size; - uint64_t file_id; - uint64_t unix_uid; - uint64_t unix_gid; - uint32_t unix_file_type; - uint64_t unix_dev_major; - uint64_t unix_dev_minor; - uint64_t unix_permissions; +/* open file state - this is a temporary implementation + to allow some tests to work */ +struct pvfs_file { + struct pvfs_file *next, *prev; + int fd; + uint16_t fnum; + struct pvfs_filename *name; }; + /* flags to pvfs_resolve_name() */ #define PVFS_RESOLVE_NO_WILDCARD (1<<0) #define PVFS_RESOLVE_STREAMS (1<<1) /* flags in pvfs->flags */ #define PVFS_FLAG_CI_FILESYSTEM (1<<0) /* the filesystem is case insensitive */ +#define PVFS_FLAG_MAP_ARCHIVE (1<<1) +#define PVFS_FLAG_MAP_SYSTEM (1<<2) +#define PVFS_FLAG_MAP_HIDDEN (1<<3) +#define PVFS_FLAG_READONLY (1<<4) #endif /* _VFS_POSIX_H_ */ -- cgit From 635f5fa942c2ecd82a2a787b96bf2ce2a587c616 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Sep 2004 08:53:45 +0000 Subject: r2438: compile on systems without O_DIRECTORY (probably won't work, but I'll get to that later) (This used to be commit 5e2027f8ec7248e48d1dfb94c3688c78c64a85c5) --- source4/ntvfs/posix/pvfs_open.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 74badb2443..26fd444984 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -84,6 +84,11 @@ NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) flags |= O_RDWR; +/* we need to do this differently to support systems without O_DIRECTORY */ +#ifndef O_DIRECTORY +#define O_DIRECTORY 0 +#endif + if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { flags = O_RDONLY | O_DIRECTORY; if (pvfs->flags & PVFS_FLAG_READONLY) { -- cgit From 7d06a06584e5163b69f712e38dc46afc2668389c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 20 Sep 2004 12:31:07 +0000 Subject: r2447: let the server code use the new lib/socket/ stuff metze (This used to be commit 2fd577d2417e117a7e8c1a56feb147eae805df34) --- source4/ntvfs/cifs/vfs_cifs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index ecc2c7ebcb..f0fa5dc85b 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -51,7 +51,9 @@ struct async_info { static void idle_func(struct smbcli_transport *transport, void *p_private) { struct cvfs_private *private = p_private; - if (socket_pending(private->tcon->smb_conn->connection->event.fde->fd)) { + int fd = socket_get_fd(private->tcon->smb_conn->connection->socket); + + if (socket_pending(fd)) { smbd_process_async(private->tcon->smb_conn); } } -- cgit From 23ba434b017d61f397befe9808fa3214c3964355 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Sep 2004 08:46:47 +0000 Subject: r2469: complete overhaul of the old-style RAW_SEARCH_ calls (the OS/2 and original core level calls). The old code was completely wrong in many respects. also fixed the EA_SIZE level in the server extended the RAW-SEARCH test suite to test the new code properly (This used to be commit 71480271ad84b57fcdde264a54bb2408cf783255) --- source4/ntvfs/posix/pvfs_search.c | 110 +++++++++++++++++++++++++++++++------- source4/ntvfs/posix/vfs_posix.h | 2 +- 2 files changed, 91 insertions(+), 21 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 548d7ad77e..3004e92d51 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -102,31 +102,14 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i NTSTATUS status; struct pvfs_filename *name; - switch (io->generic.level) { - case RAW_SEARCH_SEARCH: + if (io->generic.level == RAW_SEARCH_SEARCH) { max_count = io->search_first.in.max_count; search_attrib = io->search_first.in.search_attrib; pattern = io->search_first.in.pattern; - break; - - case RAW_SEARCH_STANDARD: - case RAW_SEARCH_EA_SIZE: - case RAW_SEARCH_DIRECTORY_INFO: - case RAW_SEARCH_FULL_DIRECTORY_INFO: - case RAW_SEARCH_NAME_INFO: - case RAW_SEARCH_BOTH_DIRECTORY_INFO: - case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: - case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: - case RAW_SEARCH_UNIX_INFO: + } else { max_count = io->t2ffirst.in.max_count; search_attrib = io->t2ffirst.in.search_attrib; pattern = io->t2ffirst.in.pattern; - break; - - case RAW_SEARCH_FCLOSE: - case RAW_SEARCH_GENERIC: - DEBUG(0,("WARNING: Invalid search class %d in pvfs_search_first\n", io->generic.level)); - return NT_STATUS_INVALID_INFO_CLASS; } /* resolve the cifs name to a posix name */ @@ -232,7 +215,94 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - return NT_STATUS_NOT_IMPLEMENTED; +#if 0 + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct search_state *search; + union smb_search_data file; + uint_t max_count; + uint16_t handle; + int i; + + if (io->generic.level == RAW_SEARCH_SEARCH) { + max_count = io->search_next.in.max_count; + search_attrib = io->search_next.in.search_attrib; + } else { + handle = io->t2fnext.in.handle; + } + + if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { + return NT_STATUS_NOT_SUPPORTED; + } + + for (search=private->search; search; search = search->next) { + if (search->handle == io->t2fnext.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + dir = search->dir; + + /* the client might be asking for something other than just continuing + with the search */ + if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && + (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && + io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { + /* look backwards first */ + for (i=search->current_index; i > 0; i--) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + + /* then look forwards */ + for (i=search->current_index+1; i <= dir->count; i++) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + } + +found: + max_count = search->current_index + io->t2fnext.in.max_count; + + if (max_count > dir->count) { + max_count = dir->count; + } + + for (i = search->current_index; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); + file.both_directory_info.name.s = dir->files[i].name; + file.both_directory_info.short_name.s = dir->files[i].name; + file.both_directory_info.size = dir->files[i].st.st_size; + file.both_directory_info.attrib = pvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + + if (!callback(search_private, &file)) { + break; + } + } + + io->t2fnext.out.count = i - search->current_index; + io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; + + search->current_index = i; + + /* work out if we are going to keep the search state */ + if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + DLIST_REMOVE(private->search, search); + talloc_free(search); + } +#endif + return NT_STATUS_OK; } /* close a search */ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 12955ced5c..8b7ddfad88 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -92,9 +92,9 @@ struct pvfs_dir { /* the state of a search started with pvfs_search_first() */ struct pvfs_search_state { struct pvfs_search_state *next, *prev; - uint16_t search_attrib; uint16_t handle; uint_t current_index; + uint16_t search_attrib; struct pvfs_dir *dir; }; -- cgit From dd7862cb6aaef40b848eb96fb4020c492a313ec8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 08:17:26 +0000 Subject: r2503: the RAW-SEARCH test now mostly passes against the posix backend (This used to be commit 9710f24b1fd103d5656c9585cdfed96449cf9f97) --- source4/ntvfs/posix/pvfs_dirlist.c | 11 +- source4/ntvfs/posix/pvfs_fileinfo.c | 9 + source4/ntvfs/posix/pvfs_search.c | 342 +++++++++++++++++++++++++----------- source4/ntvfs/posix/pvfs_util.c | 5 +- 4 files changed, 264 insertions(+), 103 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 1b4d01c197..0137424dc4 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -36,7 +36,10 @@ static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filen } dir->count = 0; - dir->unix_path = name->full_name; + dir->unix_path = talloc_strdup(dir, name->full_name); + if (!dir->unix_path) { + return NT_STATUS_NO_MEMORY; + } dir->names = talloc_array_p(dir, const char *, 1); if (!dir->names) { @@ -81,7 +84,11 @@ NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct p } dir->count = 0; - dir->unix_path = name->full_name; + dir->unix_path = talloc_strdup(dir, name->full_name); + if (!dir->unix_path) { + return NT_STATUS_NO_MEMORY; + } + dir->names = talloc(dir, 0); if (!dir->names) { return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index c5a3a1c666..be559cf179 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -114,6 +114,15 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) result |= FILE_ATTRIBUTE_SPARSE; } #endif + + if (!(result & + (FILE_ATTRIBUTE_READONLY| + FILE_ATTRIBUTE_ARCHIVE| + FILE_ATTRIBUTE_SYSTEM| + FILE_ATTRIBUTE_HIDDEN| + FILE_ATTRIBUTE_DIRECTORY))) { + result |= FILE_ATTRIBUTE_NORMAL; + } return result; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 3004e92d51..e51c7477f2 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -23,6 +23,31 @@ #include "include/includes.h" #include "vfs_posix.h" + +/* + list files in a directory matching a wildcard pattern - old SMBsearch interface +*/ +static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* continue a old style search */ +static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + +/* close a old style search */ +static NTSTATUS pvfs_search_close_old(struct smbsrv_request *req, union smb_search_close *io) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + /* fill in a single search result for a given info level */ @@ -42,7 +67,63 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return status; } + if (!pvfs_match_attrib(pvfs, name, search_attrib)) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + switch (level) { + case RAW_SEARCH_STANDARD: + file->standard.resume_key = dir_index; + file->standard.create_time = nt_time_to_unix(name->dos.create_time); + file->standard.access_time = nt_time_to_unix(name->dos.access_time); + file->standard.write_time = nt_time_to_unix(name->dos.write_time); + file->standard.size = name->st.st_size; + file->standard.alloc_size = name->dos.alloc_size; + file->standard.attrib = name->dos.attrib; + file->standard.name.s = fname; + break; + + case RAW_SEARCH_EA_SIZE: + file->ea_size.resume_key = dir_index; + file->ea_size.create_time = nt_time_to_unix(name->dos.create_time); + file->ea_size.access_time = nt_time_to_unix(name->dos.access_time); + file->ea_size.write_time = nt_time_to_unix(name->dos.write_time); + file->ea_size.size = name->st.st_size; + file->ea_size.alloc_size = name->dos.alloc_size; + file->ea_size.attrib = name->dos.attrib; + file->ea_size.ea_size = name->dos.ea_size; + file->ea_size.name.s = fname; + break; + + case RAW_SEARCH_DIRECTORY_INFO: + file->directory_info.file_index = dir_index; + file->directory_info.create_time = name->dos.create_time; + file->directory_info.access_time = name->dos.access_time; + file->directory_info.write_time = name->dos.write_time; + file->directory_info.change_time = name->dos.change_time; + file->directory_info.size = name->st.st_size; + file->directory_info.alloc_size = name->dos.alloc_size; + file->directory_info.attrib = name->dos.attrib; + file->directory_info.name.s = fname; + break; + + case RAW_SEARCH_FULL_DIRECTORY_INFO: + file->full_directory_info.file_index = dir_index; + file->full_directory_info.create_time = name->dos.create_time; + file->full_directory_info.access_time = name->dos.access_time; + file->full_directory_info.write_time = name->dos.write_time; + file->full_directory_info.change_time = name->dos.change_time; + file->full_directory_info.size = name->st.st_size; + file->full_directory_info.alloc_size = name->dos.alloc_size; + file->full_directory_info.attrib = name->dos.attrib; + file->full_directory_info.ea_size = name->dos.ea_size; + file->full_directory_info.name.s = fname; + break; + + case RAW_SEARCH_NAME_INFO: + file->name_info.file_index = dir_index; + file->name_info.name.s = fname; + break; case RAW_SEARCH_BOTH_DIRECTORY_INFO: file->both_directory_info.file_index = dir_index; @@ -57,6 +138,38 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->both_directory_info.short_name.s = pvfs_short_name(pvfs, name); file->both_directory_info.name.s = fname; break; + + case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: + file->id_full_directory_info.file_index = dir_index; + file->id_full_directory_info.create_time = name->dos.create_time; + file->id_full_directory_info.access_time = name->dos.access_time; + file->id_full_directory_info.write_time = name->dos.write_time; + file->id_full_directory_info.change_time = name->dos.change_time; + file->id_full_directory_info.size = name->st.st_size; + file->id_full_directory_info.alloc_size = name->dos.alloc_size; + file->id_full_directory_info.attrib = name->dos.attrib; + file->id_full_directory_info.ea_size = name->dos.ea_size; + file->id_full_directory_info.file_id = name->dos.file_id; + file->id_full_directory_info.name.s = fname; + break; + + case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: + file->id_both_directory_info.file_index = dir_index; + file->id_both_directory_info.create_time = name->dos.create_time; + file->id_both_directory_info.access_time = name->dos.access_time; + file->id_both_directory_info.write_time = name->dos.write_time; + file->id_both_directory_info.change_time = name->dos.change_time; + file->id_both_directory_info.size = name->st.st_size; + file->id_both_directory_info.alloc_size = name->dos.alloc_size; + file->id_both_directory_info.attrib = name->dos.attrib; + file->id_both_directory_info.ea_size = name->dos.ea_size; + file->id_both_directory_info.file_id = name->dos.file_id; + file->id_both_directory_info.short_name.s = pvfs_short_name(pvfs, name); + file->id_both_directory_info.name.s = fname; + break; + + default: + return NT_STATUS_INVALID_LEVEL; } return NT_STATUS_OK; @@ -85,6 +198,62 @@ static NTSTATUS pvfs_next_search_handle(struct pvfs_state *pvfs, uint16_t *handl return NT_STATUS_OK; } + +/* + the search fill loop +*/ +static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + uint_t max_count, + struct pvfs_search_state *search, + enum smb_search_level level, + uint_t *reply_count, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + int i; + struct pvfs_dir *dir = search->dir; + NTSTATUS status; + + *reply_count = 0; + + for (i = search->current_index; i < dir->count;i++) { + union smb_search_data *file; + + file = talloc_p(mem_ctx, union smb_search_data); + if (!file) { + return NT_STATUS_NO_MEMORY; + } + + status = fill_search_info(pvfs, level, dir->unix_path, dir->names[i], + search->search_attrib, i, file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + talloc_free(file); + continue; + } + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(file); + search->current_index = i; + return status; + } + + if (!callback(search_private, file)) { + talloc_free(file); + break; + } + (*reply_count)++; + talloc_free(file); + + /* note that this deliberately allows a reply_count of + 1 for a max_count of 0. w2k3 allows this too. */ + if (*reply_count >= max_count) break; + } + + search->current_index = i; + + return NT_STATUS_OK; +} + /* list files in a directory matching a wildcard pattern */ @@ -95,23 +264,19 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i struct pvfs_dir *dir; struct pvfs_state *pvfs = req->tcon->ntvfs_private; struct pvfs_search_state *search; - uint16_t max_count, reply_count; + uint_t reply_count; uint16_t search_attrib; const char *pattern; - int i; NTSTATUS status; struct pvfs_filename *name; - if (io->generic.level == RAW_SEARCH_SEARCH) { - max_count = io->search_first.in.max_count; - search_attrib = io->search_first.in.search_attrib; - pattern = io->search_first.in.pattern; - } else { - max_count = io->t2ffirst.in.max_count; - search_attrib = io->t2ffirst.in.search_attrib; - pattern = io->t2ffirst.in.pattern; + if (io->generic.level >= RAW_SEARCH_SEARCH) { + return pvfs_search_first_old(req, io, search_private, callback); } + search_attrib = io->t2ffirst.in.search_attrib; + pattern = io->t2ffirst.in.pattern; + /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, pattern, 0, &name); if (!NT_STATUS_IS_OK(status)) { @@ -119,7 +284,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i } if (!name->has_wildcard && !name->exists) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + return NT_STATUS_NO_SUCH_FILE; } /* we initially make search a child of the request, then if we @@ -152,59 +317,32 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i search->current_index = 0; search->search_attrib = search_attrib; - if (dir->count < max_count) { - max_count = dir->count; - } - - /* note that fill_search_info() can fail, if for example a - file disappears during a search or we don't have sufficient - permissions to stat() it, or the search_attrib does not - match the files attribute. In that case the name is ignored - and the search continues. */ - for (i=reply_count=0; i < dir->count && reply_count < max_count;i++) { - union smb_search_data *file; - - file = talloc_p(req, union smb_search_data); - if (!file) { - return NT_STATUS_NO_MEMORY; - } - - status = fill_search_info(pvfs, io->generic.level, dir->unix_path, dir->names[i], - search_attrib, i, file); - if (NT_STATUS_IS_OK(status)) { - if (!callback(search_private, file)) { - break; - } - reply_count++; - } - talloc_free(file); + status = pvfs_search_fill(pvfs, req, io->t2ffirst.in.max_count, search, io->generic.level, + &reply_count, search_private, callback); + if (!NT_STATUS_IS_OK(status)) { + return status; } /* not matching any entries is an error */ if (reply_count == 0) { - return NT_STATUS_NO_MORE_ENTRIES; + return NT_STATUS_NO_SUCH_FILE; } - search->current_index = i; + io->t2ffirst.out.count = reply_count; + io->t2ffirst.out.handle = search->handle; + io->t2ffirst.out.end_of_search = (search->current_index == dir->count) ? 1 : 0; - if (io->generic.level == RAW_SEARCH_SEARCH) { - io->search_first.out.count = reply_count; - DEBUG(0,("TODO: handle RAW_SEARCH_SEARCH continue\n")); + /* work out if we are going to keep the search state + and allow for a search continue */ + if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && + io->t2ffirst.out.end_of_search)) { + talloc_free(search); } else { - io->t2ffirst.out.count = reply_count; - io->t2ffirst.out.handle = search->handle; - io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; - /* work out if we are going to keep the search state - and allow for a search continue */ - if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || - ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - talloc_free(search); - } else { - pvfs->search.num_active_searches++; - pvfs->search.next_search_handle++; - talloc_steal(pvfs, search); - DLIST_ADD(pvfs->search.open_searches, search); - } + pvfs->search.num_active_searches++; + pvfs->search.next_search_handle++; + talloc_steal(pvfs, search); + DLIST_ADD(pvfs->search.open_searches, search); } return NT_STATUS_OK; @@ -215,32 +353,27 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { -#if 0 struct pvfs_state *pvfs = req->tcon->ntvfs_private; - struct search_state *search; - union smb_search_data file; - uint_t max_count; + struct pvfs_search_state *search; + struct pvfs_dir *dir; + uint_t reply_count; uint16_t handle; + NTSTATUS status; int i; - if (io->generic.level == RAW_SEARCH_SEARCH) { - max_count = io->search_next.in.max_count; - search_attrib = io->search_next.in.search_attrib; - } else { - handle = io->t2fnext.in.handle; + if (io->generic.level >= RAW_SEARCH_SEARCH) { + return pvfs_search_next_old(req, io, search_private, callback); } - if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { - return NT_STATUS_NOT_SUPPORTED; - } + handle = io->t2fnext.in.handle; - for (search=private->search; search; search = search->next) { - if (search->handle == io->t2fnext.in.handle) break; + for (search=pvfs->search.open_searches; search; search = search->next) { + if (search->handle == handle) break; } if (!search) { /* we didn't find the search handle */ - return NT_STATUS_FOOBAR; + return NT_STATUS_INVALID_HANDLE; } dir = search->dir; @@ -248,11 +381,10 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, /* the client might be asking for something other than just continuing with the search */ if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && - (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { /* look backwards first */ for (i=search->current_index; i > 0; i--) { - if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + if (strcmp(io->t2fnext.in.last_name, dir->names[i-1]) == 0) { search->current_index = i; goto found; } @@ -260,7 +392,7 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, /* then look forwards */ for (i=search->current_index+1; i <= dir->count; i++) { - if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + if (strcmp(io->t2fnext.in.last_name, dir->names[i-1]) == 0) { search->current_index = i; goto found; } @@ -268,46 +400,56 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, } found: - max_count = search->current_index + io->t2fnext.in.max_count; - - if (max_count > dir->count) { - max_count = dir->count; + status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.level, + &reply_count, search_private, callback); + if (!NT_STATUS_IS_OK(status)) { + return status; } - for (i = search->current_index; i < max_count;i++) { - ZERO_STRUCT(file); - unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); - unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); - unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); - unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); - file.both_directory_info.name.s = dir->files[i].name; - file.both_directory_info.short_name.s = dir->files[i].name; - file.both_directory_info.size = dir->files[i].st.st_size; - file.both_directory_info.attrib = pvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); - - if (!callback(search_private, &file)) { - break; - } + /* not matching any entries is an error */ + if (reply_count == 0) { + return NT_STATUS_NO_MORE_ENTRIES; } - io->t2fnext.out.count = i - search->current_index; - io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; - - search->current_index = i; + io->t2fnext.out.count = reply_count; + io->t2fnext.out.end_of_search = (search->current_index == dir->count) ? 1 : 0; /* work out if we are going to keep the search state */ if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || - ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - DLIST_REMOVE(private->search, search); + ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && + io->t2fnext.out.end_of_search)) { + DLIST_REMOVE(pvfs->search.open_searches, search); talloc_free(search); } -#endif + return NT_STATUS_OK; } /* close a search */ NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { - return NT_STATUS_NOT_IMPLEMENTED; + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_search_state *search; + uint16_t handle; + + if (io->generic.level >= RAW_SEARCH_SEARCH) { + return pvfs_search_close_old(req, io); + } + + handle = io->findclose.in.handle; + + for (search=pvfs->search.open_searches; search; search = search->next) { + if (search->handle == handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_INVALID_HANDLE; + } + + DLIST_REMOVE(pvfs->search.open_searches, search); + talloc_free(search); + + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 2524261245..3c65453798 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -51,6 +51,9 @@ NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno) */ BOOL pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, uint32_t attrib) { - /* TODO: add attribute conversion */ + if ((name->dos.attrib & ~attrib) & + (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM)) { + return False; + } return True; } -- cgit From ca60193f24bb2540e65c8c272ca2bead3850b456 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 12:38:19 +0000 Subject: r2520: - finished implementing the server side of the old style search requests (This used to be commit 4e4859c06b9de5fe60ebd17cfb09eed480b79ec1) --- source4/ntvfs/posix/pvfs_search.c | 281 +++++++++++++++++++++++++++----------- 1 file changed, 200 insertions(+), 81 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index e51c7477f2..1d1d973d3f 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -23,31 +23,6 @@ #include "include/includes.h" #include "vfs_posix.h" - -/* - list files in a directory matching a wildcard pattern - old SMBsearch interface -*/ -static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* continue a old style search */ -static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_search_next *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - -/* close a old style search */ -static NTSTATUS pvfs_search_close_old(struct smbsrv_request *req, union smb_search_close *io) -{ - return NT_STATUS_NOT_IMPLEMENTED; -} - /* fill in a single search result for a given info level */ @@ -55,7 +30,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, enum smb_search_level level, const char *unix_path, const char *fname, - uint16_t search_attrib, + struct pvfs_search_state *search, uint32_t dir_index, union smb_search_data *file) { @@ -67,13 +42,28 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return status; } - if (!pvfs_match_attrib(pvfs, name, search_attrib)) { + if (!pvfs_match_attrib(pvfs, name, search->search_attrib)) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } switch (level) { + case RAW_SEARCH_SEARCH: + case RAW_SEARCH_FFIRST: + case RAW_SEARCH_FUNIQUE: + file->search.attrib = name->dos.attrib; + file->search.write_time = nt_time_to_unix(name->dos.write_time); + file->search.size = name->st.st_size; + file->search.name = fname; + file->search.id.reserved = 8; + memset(file->search.id.name, ' ', sizeof(file->search.id.name)); + memcpy(file->search.id.name, fname, MIN(strlen(fname)+1, sizeof(file->search.id.name))); + file->search.id.handle = search->handle; + file->search.id.server_cookie = dir_index+1; + file->search.id.client_cookie = 0; + return NT_STATUS_OK; + case RAW_SEARCH_STANDARD: - file->standard.resume_key = dir_index; + file->standard.resume_key = dir_index+1; file->standard.create_time = nt_time_to_unix(name->dos.create_time); file->standard.access_time = nt_time_to_unix(name->dos.access_time); file->standard.write_time = nt_time_to_unix(name->dos.write_time); @@ -81,10 +71,10 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->standard.alloc_size = name->dos.alloc_size; file->standard.attrib = name->dos.attrib; file->standard.name.s = fname; - break; + return NT_STATUS_OK; case RAW_SEARCH_EA_SIZE: - file->ea_size.resume_key = dir_index; + file->ea_size.resume_key = dir_index+1; file->ea_size.create_time = nt_time_to_unix(name->dos.create_time); file->ea_size.access_time = nt_time_to_unix(name->dos.access_time); file->ea_size.write_time = nt_time_to_unix(name->dos.write_time); @@ -93,10 +83,10 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->ea_size.attrib = name->dos.attrib; file->ea_size.ea_size = name->dos.ea_size; file->ea_size.name.s = fname; - break; + return NT_STATUS_OK; case RAW_SEARCH_DIRECTORY_INFO: - file->directory_info.file_index = dir_index; + file->directory_info.file_index = dir_index+1; file->directory_info.create_time = name->dos.create_time; file->directory_info.access_time = name->dos.access_time; file->directory_info.write_time = name->dos.write_time; @@ -105,10 +95,10 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->directory_info.alloc_size = name->dos.alloc_size; file->directory_info.attrib = name->dos.attrib; file->directory_info.name.s = fname; - break; + return NT_STATUS_OK; case RAW_SEARCH_FULL_DIRECTORY_INFO: - file->full_directory_info.file_index = dir_index; + file->full_directory_info.file_index = dir_index+1; file->full_directory_info.create_time = name->dos.create_time; file->full_directory_info.access_time = name->dos.access_time; file->full_directory_info.write_time = name->dos.write_time; @@ -118,15 +108,15 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->full_directory_info.attrib = name->dos.attrib; file->full_directory_info.ea_size = name->dos.ea_size; file->full_directory_info.name.s = fname; - break; + return NT_STATUS_OK; case RAW_SEARCH_NAME_INFO: file->name_info.file_index = dir_index; file->name_info.name.s = fname; - break; + return NT_STATUS_OK; case RAW_SEARCH_BOTH_DIRECTORY_INFO: - file->both_directory_info.file_index = dir_index; + file->both_directory_info.file_index = dir_index+1; file->both_directory_info.create_time = name->dos.create_time; file->both_directory_info.access_time = name->dos.access_time; file->both_directory_info.write_time = name->dos.write_time; @@ -137,10 +127,10 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->both_directory_info.ea_size = name->dos.ea_size; file->both_directory_info.short_name.s = pvfs_short_name(pvfs, name); file->both_directory_info.name.s = fname; - break; + return NT_STATUS_OK; case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: - file->id_full_directory_info.file_index = dir_index; + file->id_full_directory_info.file_index = dir_index+1; file->id_full_directory_info.create_time = name->dos.create_time; file->id_full_directory_info.access_time = name->dos.access_time; file->id_full_directory_info.write_time = name->dos.write_time; @@ -151,10 +141,10 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->id_full_directory_info.ea_size = name->dos.ea_size; file->id_full_directory_info.file_id = name->dos.file_id; file->id_full_directory_info.name.s = fname; - break; + return NT_STATUS_OK; case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: - file->id_both_directory_info.file_index = dir_index; + file->id_both_directory_info.file_index = dir_index+1; file->id_both_directory_info.create_time = name->dos.create_time; file->id_both_directory_info.access_time = name->dos.access_time; file->id_both_directory_info.write_time = name->dos.write_time; @@ -166,36 +156,13 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->id_both_directory_info.file_id = name->dos.file_id; file->id_both_directory_info.short_name.s = pvfs_short_name(pvfs, name); file->id_both_directory_info.name.s = fname; - break; - - default: - return NT_STATUS_INVALID_LEVEL; - } - - return NT_STATUS_OK; -} + return NT_STATUS_OK; -/* - return the next available search handle -*/ -static NTSTATUS pvfs_next_search_handle(struct pvfs_state *pvfs, uint16_t *handle) -{ - struct pvfs_search_state *search; - - if (pvfs->search.num_active_searches >= 0x10000) { - return NT_STATUS_INSUFFICIENT_RESOURCES; - } - - (*handle) = pvfs->search.next_search_handle; - for (search=pvfs->search.open_searches;search;search=search->next) { - if (*handle == search->handle) { - *handle = ((*handle)+1) & 0xFFFF; - continue; - } + case RAW_SEARCH_GENERIC: + break; } - pvfs->search.next_search_handle = ((*handle)+1) & 0xFFFF; - return NT_STATUS_OK; + return NT_STATUS_INVALID_LEVEL; } @@ -225,7 +192,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, } status = fill_search_info(pvfs, level, dir->unix_path, dir->names[i], - search->search_attrib, i, file); + search, i, file); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { talloc_free(file); continue; @@ -254,6 +221,156 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +/* + return the next available search handle +*/ +static NTSTATUS pvfs_next_search_handle(struct pvfs_state *pvfs, uint16_t *handle, + uint_t max_handles) +{ + struct pvfs_search_state *search; + + if (pvfs->search.num_active_searches >= max_handles) { + return NT_STATUS_INSUFFICIENT_RESOURCES; + } + + (*handle) = (pvfs->search.next_search_handle) & (max_handles-1); +again: + for (search=pvfs->search.open_searches;search;search=search->next) { + if (*handle == search->handle) { + *handle = ((*handle)+1) & (max_handles-1); + goto again; + } + } + pvfs->search.next_search_handle = ((*handle)+1) & (max_handles-1); + + return NT_STATUS_OK; +} + + +/* + list files in a directory matching a wildcard pattern - old SMBsearch interface +*/ +static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct pvfs_dir *dir; + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_search_state *search; + uint_t reply_count; + uint16_t search_attrib; + const char *pattern; + NTSTATUS status; + struct pvfs_filename *name; + + search_attrib = io->search_first.in.search_attrib; + pattern = io->search_first.in.pattern; + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, pattern, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->has_wildcard && !name->exists) { + return STATUS_NO_MORE_FILES; + } + + /* we initially make search a child of the request, then if we + need to keep it long term we steal it for the private + structure */ + search = talloc_p(req, struct pvfs_search_state); + if (!search) { + return NT_STATUS_NO_MEMORY; + } + + dir = talloc_p(search, struct pvfs_dir); + if (!dir) { + return NT_STATUS_NO_MEMORY; + } + + /* do the actual directory listing */ + status = pvfs_list(pvfs, name, dir); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* we need to give a handle back to the client so it + can continue a search */ + status = pvfs_next_search_handle(pvfs, &search->handle, 0x100); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + search->dir = dir; + search->current_index = 0; + search->search_attrib = search_attrib; + + status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.level, + &reply_count, search_private, callback); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + io->search_first.out.count = reply_count; + + /* not matching any entries is an error */ + if (reply_count == 0) { + return STATUS_NO_MORE_FILES; + } + + pvfs->search.num_active_searches++; + talloc_steal(pvfs, search); + DLIST_ADD(pvfs->search.open_searches, search); + + return NT_STATUS_OK; +} + +/* continue a old style search */ +static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + struct pvfs_search_state *search; + struct pvfs_dir *dir; + uint_t reply_count, max_count; + uint16_t handle; + NTSTATUS status; + + handle = io->search_next.in.id.handle; + max_count = io->search_next.in.max_count; + + for (search=pvfs->search.open_searches; search; search = search->next) { + if (search->handle == handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_INVALID_HANDLE; + } + + search->current_index = io->search_next.in.id.server_cookie; + + dir = search->dir; + + status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, + &reply_count, search_private, callback); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + io->search_next.out.count = reply_count; + + /* not matching any entries means end of search */ + if (reply_count == 0) { + DLIST_REMOVE(pvfs->search.open_searches, search); + talloc_free(search); + } + + return NT_STATUS_OK; +} + /* list files in a directory matching a wildcard pattern */ @@ -265,7 +382,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i struct pvfs_state *pvfs = req->tcon->ntvfs_private; struct pvfs_search_state *search; uint_t reply_count; - uint16_t search_attrib; + uint16_t search_attrib, max_count; const char *pattern; NTSTATUS status; struct pvfs_filename *name; @@ -276,6 +393,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i search_attrib = io->t2ffirst.in.search_attrib; pattern = io->t2ffirst.in.pattern; + max_count = io->t2ffirst.in.max_count; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, pattern, 0, &name); @@ -308,7 +426,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i /* we need to give a handle back to the client so it can continue a search */ - status = pvfs_next_search_handle(pvfs, &search->handle); + status = pvfs_next_search_handle(pvfs, &search->handle, 0x10000); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -317,7 +435,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i search->current_index = 0; search->search_attrib = search_attrib; - status = pvfs_search_fill(pvfs, req, io->t2ffirst.in.max_count, search, io->generic.level, + status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { return status; @@ -340,7 +458,6 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i talloc_free(search); } else { pvfs->search.num_active_searches++; - pvfs->search.next_search_handle++; talloc_steal(pvfs, search); DLIST_ADD(pvfs->search.open_searches, search); } @@ -378,10 +495,8 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, dir = search->dir; - /* the client might be asking for something other than just continuing - with the search */ - if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && - io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { + /* work out what type of continuation is being used */ + if (io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { /* look backwards first */ for (i=search->current_index; i > 0; i--) { if (strcmp(io->t2fnext.in.last_name, dir->names[i-1]) == 0) { @@ -397,6 +512,10 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, goto found; } } + } else if (io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) { + /* plain continue - nothing to do */ + } else { + search->current_index = io->t2fnext.in.resume_key; } found: @@ -432,12 +551,12 @@ NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *i struct pvfs_search_state *search; uint16_t handle; - if (io->generic.level >= RAW_SEARCH_SEARCH) { - return pvfs_search_close_old(req, io); + if (io->generic.level == RAW_FINDCLOSE_FCLOSE) { + handle = io->fclose.in.id.handle; + } else { + handle = io->findclose.in.handle; } - handle = io->findclose.in.handle; - for (search=pvfs->search.open_searches; search; search = search->next) { if (search->handle == handle) break; } -- cgit From d3fc90eaa185a15f2bd7fca11663e898feb2c81c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Sep 2004 13:01:55 +0000 Subject: r2524: a simple pvfs rename implementation to make testing easier (This used to be commit 98c1c75076fdb0df3a7c616f8c2e1ed138a6ff9a) --- source4/ntvfs/config.mk | 1 + source4/ntvfs/posix/pvfs_rename.c | 69 +++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 10 ------ 3 files changed, 70 insertions(+), 10 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_rename.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 416b14a3b3..cf48cc61c2 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -57,6 +57,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_fsinfo.o \ ntvfs/posix/pvfs_qfileinfo.o \ ntvfs/posix/pvfs_setfileinfo.o \ + ntvfs/posix/pvfs_rename.o \ ntvfs/posix/pvfs_resolve.o \ ntvfs/posix/pvfs_shortname.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c new file mode 100644 index 0000000000..40b84f7628 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -0,0 +1,69 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - rename + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + rename a set of files +*/ +NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) +{ + struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTSTATUS status; + struct pvfs_filename *name1, *name2; + + if (ren->generic.level != RAW_RENAME_RENAME) { + return NT_STATUS_INVALID_LEVEL; + } + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, 0, &name1); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2, 0, &name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (name1->has_wildcard || name2->has_wildcard) { + DEBUG(3,("Rejecting wildcard rename '%s' -> '%s'\n", + ren->rename.in.pattern1, ren->rename.in.pattern2)); + return NT_STATUS_NOT_SUPPORTED; + } + + if (!name1->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (name2->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + if (rename(name1->full_name, name2->full_name) != 0) { + return pvfs_map_errno(pvfs, errno); + } + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index b2c9d81086..84a5647075 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -102,7 +102,6 @@ static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon) */ static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { - DEBUG(0,("pvfs_ioctl not implemented\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -132,15 +131,6 @@ static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) return NT_STATUS_OK; } -/* - rename a set of files -*/ -static NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) -{ - DEBUG(0,("pvfs_rename not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - /* copy a set of files */ -- cgit From 9a9dcc7250ccd4544cb797c15b3bc3dfbb760be0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 23 Sep 2004 00:51:45 +0000 Subject: r2552: Character set conversion and string handling updates. The intial motivation for this commit was to merge in some of the bugfixes present in Samba3's chrcnv and string handling code into Samba4. However, along the way I found a lot of unused functions, and decided to do a bit more... The strlen_m code now does not use a fixed buffer, but more work is needed to finish off other functions in str_util.c. These fixed length buffers hav caused very nasty, hard to chase down bugs at some sites. The strupper_m() function has a strupper_talloc() to replace it (we need to go around and fix more uses, but it's a start). Use of these new functions will avoid bugs where the upper or lowercase version of a string is a different length. I have removed the push_*_allocate functions, which are replaced by calls to push_*_talloc. Likewise, pstring and other 'fixed length' wrappers are removed, where possible. I have removed the first ('base pointer') argument, used by push_ucs2, as the Samba4 way of doing things ensures that this is always on an even boundary anyway. (It was used in only one place, in any case). (This used to be commit dfecb0150627b500cb026b8a4932fe87902ca392) --- source4/ntvfs/print/vfs_print.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 4b50e3e6e5..7405697bb9 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -70,8 +70,8 @@ static NTSTATUS print_ioctl(struct smbsrv_request *req, union smb_ioctl *io) p = io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); - push_string(NULL, p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); - push_string(NULL, p+18, lp_servicename(req->tcon->service), 13, STR_TERMINATE|STR_ASCII); + push_string(p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); + push_string(p+18, lp_servicename(req->tcon->service), 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } -- cgit From a3cec511bbef2cc7768906f3af947ce2f900bde6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 23 Sep 2004 07:44:42 +0000 Subject: r2561: completely redid the ntvfs module chaining code, You can now do something like: ntvfs handler = nbench posix and the nbench pass-thru module will be called before the posix module. The chaining logic is now much saner, and less racy, with each level in the chain getting its own private pointer rather than relying on save/restore logic in the pass-thru module. The only pass-thru module we have at the moment is the nbench one (which records all traffic in a nbench compatibe format), but I plan on soon writing a "unixuid" pass-thru module that will implement the setegid()/setgroups()/seteuid() logic for standard posix uid handling. This separation of the posix backend from the uid handling should simplify the code, and make development easier. I also modified the nbench module so it can do multiple chaining, so if you want to you can do: ntvfs module = nbench nbench posix and it will save 2 copies of the log file in /tmp. This is really only useful for testing at the moment until we have more than one pass-thru module. (This used to be commit f84c0af35cb54c8fdc4933afefc18fa4c062aae4) --- source4/ntvfs/cifs/vfs_cifs.c | 79 ++++++++++----------------- source4/ntvfs/ipc/vfs_ipc.c | 20 +++---- source4/ntvfs/nbench/vfs_nbench.c | 97 ++++++++++++++-------------------- source4/ntvfs/ntvfs.h | 8 ++- source4/ntvfs/ntvfs_base.c | 21 ++++++-- source4/ntvfs/ntvfs_generic.c | 22 ++++---- source4/ntvfs/posix/pvfs_fsinfo.c | 4 +- source4/ntvfs/posix/pvfs_mkdir.c | 4 +- source4/ntvfs/posix/pvfs_open.c | 6 +-- source4/ntvfs/posix/pvfs_qfileinfo.c | 8 +-- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_resolve.c | 14 ++++- source4/ntvfs/posix/pvfs_search.c | 10 ++-- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_unlink.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 10 ++-- source4/ntvfs/posix/vfs_posix.h | 2 + source4/ntvfs/simple/svfs.h | 2 + source4/ntvfs/simple/svfs_util.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 40 +++++++------- 22 files changed, 182 insertions(+), 177 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index f0fa5dc85b..2ae41a674c 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,7 +32,7 @@ struct cvfs_private { struct smbcli_tree *tree; struct smbcli_transport *transport; struct smbsrv_tcon *tcon; - const char *map_calls; + const struct ntvfs_ops *ops; }; @@ -89,12 +89,11 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, /* connect to a share - used when a tree_connect operation comes in. */ -static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) +static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename, int depth) { struct smbsrv_tcon *tcon = req->tcon; NTSTATUS status; struct cvfs_private *private; - const char *map_calls; const char *host, *user, *pass, *domain, *remote_share; /* Here we need to determine which server to connect to. @@ -121,7 +120,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) } ZERO_STRUCTP(private); - req->tcon->ntvfs_private = (void *)private; + ntvfs_set_private(req->tcon, depth, private); status = smbcli_tree_full_connection(&private->tree, "vfs_cifs", @@ -137,27 +136,11 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) private->transport = private->tree->session->transport; private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); private->tcon = req->tcon; + private->ops = ntvfs_backend_byname("cifs", NTVFS_DISK); tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); - map_calls = lp_parm_string(req->tcon->service, "cifs", "map calls"); - if (map_calls) { - private->map_calls = talloc_strdup(tcon, map_calls); - } - - /* if we are mapping trans2, then we need to give a trans2 - pointer in the operations structure */ - if (private->map_calls && in_list("trans2", private->map_calls, True)) { - struct ntvfs_ops *ops = talloc_memdup(tcon, tcon->ntvfs_ops,sizeof(*ops)); - static NTSTATUS cvfs_trans2(struct smbsrv_request *,struct smb_trans2 *); - if (!ops) { - return NT_STATUS_NO_MEMORY; - } - ops->trans2 = cvfs_trans2; - tcon->ntvfs_ops = ops; - } - /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); smbcli_transport_idle_handler(private->transport, idle_func, 1, private); @@ -174,9 +157,9 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon) +static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon, int depth) { - struct cvfs_private *private = tcon->ntvfs_private; + struct cvfs_private *private = tcon->ntvfs_private_list[depth]; smb_tree_disconnect(private->tree); smbcli_tree_close(private->tree); @@ -222,7 +205,7 @@ static void async_simple(struct smbcli_request *c_req) */ static NTSTATUS cvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; /* see if the front end will allow us to perform this @@ -252,7 +235,7 @@ static void async_ioctl(struct smbcli_request *c_req) */ static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; /* see if the front end will allow us to perform this @@ -271,7 +254,7 @@ static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) */ static NTSTATUS cvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -299,7 +282,7 @@ static void async_qpathinfo(struct smbcli_request *c_req) */ static NTSTATUS cvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -327,7 +310,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) */ static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -345,7 +328,7 @@ static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i */ static NTSTATUS cvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -374,14 +357,9 @@ static void async_open(struct smbcli_request *c_req) */ static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; - if (private->map_calls && in_list("open", private->map_calls, True) && - io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(req, io); - } - if (!req->async.send_fn) { return smb_raw_open(private->tree, req, io); } @@ -396,7 +374,7 @@ static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) */ static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -413,7 +391,7 @@ static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) */ static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -429,7 +407,7 @@ static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) */ static NTSTATUS cvfs_rename(struct smbsrv_request *req, union smb_rename *ren) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -465,7 +443,7 @@ static void async_read(struct smbcli_request *c_req) */ static NTSTATUS cvfs_read(struct smbsrv_request *req, union smb_read *rd) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -493,7 +471,7 @@ static void async_write(struct smbcli_request *c_req) */ static NTSTATUS cvfs_write(struct smbsrv_request *req, union smb_write *wr) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -526,7 +504,7 @@ static NTSTATUS cvfs_flush(struct smbsrv_request *req, struct smb_flush *io) */ static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -551,7 +529,7 @@ static NTSTATUS cvfs_exit(struct smbsrv_request *req) */ static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -568,7 +546,7 @@ static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck) static NTSTATUS cvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -596,7 +574,7 @@ static void async_fsinfo(struct smbcli_request *c_req) */ static NTSTATUS cvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -623,7 +601,7 @@ static NTSTATUS cvfs_search_first(struct smbsrv_request *req, union smb_search_f void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); return smb_raw_search_first(private->tree, req, io, search_private, callback); } @@ -633,7 +611,7 @@ static NTSTATUS cvfs_search_next(struct smbsrv_request *req, union smb_search_ne void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); return smb_raw_search_next(private->tree, req, io, search_private, callback); } @@ -641,7 +619,7 @@ static NTSTATUS cvfs_search_next(struct smbsrv_request *req, union smb_search_ne /* close a search */ static NTSTATUS cvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); return smb_raw_search_close(private->tree, io); } @@ -660,7 +638,7 @@ static void async_trans2(struct smbcli_request *c_req) /* raw trans2 */ static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) { - struct cvfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(cvfs_private, private, req); struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -722,8 +700,9 @@ NTSTATUS ntvfs_cifs_init(void) ops.search_close = cvfs_search_close; ops.trans = cvfs_trans; - /* only define this one for trans2 testing */ - ops.trans2 = NULL; + if (lp_parm_bool(-1, "cifs", "maptrans2", False)) { + ops.trans2 = cvfs_trans2; + } /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 053222460c..96e7820be5 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -105,7 +105,7 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t /* connect to a share - always works */ -static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename) +static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename, int depth) { struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; @@ -118,7 +118,7 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename) if (!private) { return NT_STATUS_NO_MEMORY; } - tcon->ntvfs_private = (void *)private; + ntvfs_set_private(tcon, depth, private); private->pipe_list = NULL; private->next_fnum = 1; @@ -130,9 +130,9 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon) +static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon, int depth) { - struct ipc_private *private = tcon->ntvfs_private; + struct ipc_private *private = tcon->ntvfs_private_list[depth]; /* close any pipes that are open. Discard any unread data */ while (private->pipe_list) { @@ -196,7 +196,7 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, NTSTATUS status; struct dcesrv_ep_description ep_description; struct auth_session_info *session_info = NULL; - struct ipc_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(ipc_private, private, req); mem_ctx = talloc_init("ipc_open '%s'", fname); if (!mem_ctx) { @@ -374,7 +374,7 @@ static NTSTATUS ipc_copy(struct smbsrv_request *req, struct smb_copy *cp) */ static NTSTATUS ipc_read(struct smbsrv_request *req, union smb_read *rd) { - struct ipc_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(ipc_private, private, req); DATA_BLOB data; uint16_t fnum; struct pipe_state *p; @@ -426,7 +426,7 @@ static NTSTATUS ipc_read(struct smbsrv_request *req, union smb_read *rd) */ static NTSTATUS ipc_write(struct smbsrv_request *req, union smb_write *wr) { - struct ipc_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(ipc_private, private, req); DATA_BLOB data; uint16_t fnum; struct pipe_state *p; @@ -495,7 +495,7 @@ static NTSTATUS ipc_flush(struct smbsrv_request *req, struct smb_flush *io) */ static NTSTATUS ipc_close(struct smbsrv_request *req, union smb_close *io) { - struct ipc_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(ipc_private, private, req); struct pipe_state *p; if (io->generic.level != RAW_CLOSE_CLOSE) { @@ -595,7 +595,7 @@ NTSTATUS ipc_search_close(struct smbsrv_request *req, union smb_search_close *io static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *trans) { struct pipe_state *p; - struct ipc_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(ipc_private, private, req); NTSTATUS status; /* the fnum is in setup[1] */ @@ -639,8 +639,8 @@ static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *tr /* SMBtrans - set named pipe state */ static NTSTATUS ipc_set_nm_pipe_state(struct smbsrv_request *req, struct smb_trans2 *trans) { + NTVFS_GET_PRIVATE(ipc_private, private, req); struct pipe_state *p; - struct ipc_private *private = req->tcon->ntvfs_private; /* the fnum is in setup[1] */ p = pipe_state_find(private, trans->in.setup[1]); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 549d1d893f..b88c65d5db 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -29,8 +29,6 @@ /* this is stored in ntvfs_private */ struct nbench_private { const struct ntvfs_ops *passthru_ops; - void *passthru_private; - const struct ntvfs_ops *nbench_ops; int log_fd; }; @@ -57,23 +55,9 @@ static void nbench_log(struct nbench_private *private, /* - when we call the next stacked level of NTVFS module we need - to give it its own private pointer, plus its own NTVFS operations structure. - Then we need to restore both of these after the call, as the next level could - modify either of these + this is used to call the next module in the ntvfs chain */ -#define PASS_THRU(tcon, op, args) do { \ - tcon->ntvfs_private = private->passthru_private; \ - tcon->ntvfs_ops = private->passthru_ops; \ -\ - status = private->passthru_ops->op args; \ -\ - private->passthru_private = tcon->ntvfs_private; \ - private->passthru_ops = tcon->ntvfs_ops; \ -\ - tcon->ntvfs_private = private; \ - tcon->ntvfs_ops = private->nbench_ops; \ -} while (0) +#define PASS_THRU(tcon, op, args) private->passthru_ops->op args; /* this pass through macro operates on request contexts, and disables @@ -85,7 +69,9 @@ static void nbench_log(struct nbench_private *private, #define PASS_THRU_REQ(req, op, args) do { \ void *send_fn_saved = req->async.send_fn; \ req->async.send_fn = NULL; \ - PASS_THRU(req->tcon, op, args); \ + req->ntvfs_depth++; \ + status = PASS_THRU(req->tcon, op, args); \ + req->ntvfs_depth--; \ req->async.send_fn = send_fn_saved; \ } while (0) @@ -93,19 +79,20 @@ static void nbench_log(struct nbench_private *private, /* connect to a share - used when a tree_connect operation comes in. */ -static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename) +static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename, int depth) { struct nbench_private *private; const char *passthru; NTSTATUS status; char *logname = NULL; + const char **handlers = lp_ntvfs_handler(req->tcon->service); private = talloc_p(req->tcon, struct nbench_private); if (!private) { return NT_STATUS_NO_MEMORY; } - asprintf(&logname, "/tmp/nbenchlog.%u", getpid()); + asprintf(&logname, "/tmp/nbenchlog%d.%u", depth, getpid()); private->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); free(logname); @@ -114,18 +101,16 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename return NT_STATUS_UNSUCCESSFUL; } - passthru = lp_parm_string(req->tcon->service, "nbench", "passthru"); - - private->passthru_private = NULL; - private->nbench_ops = req->tcon->ntvfs_ops; - private->passthru_ops = ntvfs_backend_byname(passthru, NTVFS_DISK); + private->passthru_ops = ntvfs_backend_byname(handlers[depth+1], NTVFS_DISK); if (!private->passthru_ops) { DEBUG(0,("Unable to connect to '%s' pass through backend\n", passthru)); return NT_STATUS_UNSUCCESSFUL; } + + ntvfs_set_private(req->tcon, depth, private); - PASS_THRU(req->tcon, connect, (req, sharename)); + PASS_THRU(req->tcon, connect, (req, sharename, depth+1)); return status; } @@ -133,15 +118,15 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename /* disconnect from a share */ -static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon) +static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon, int depth) { - struct nbench_private *private = tcon->ntvfs_private; + struct nbench_private *private = tcon->ntvfs_private_list[depth]; NTSTATUS status; - PASS_THRU(tcon, disconnect, (tcon)); - close(private->log_fd); + PASS_THRU(tcon, disconnect, (tcon, depth+1)); + return status; } @@ -151,7 +136,7 @@ static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon) */ static NTSTATUS nbench_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, unlink, (req, unl)); @@ -168,7 +153,7 @@ static NTSTATUS nbench_unlink(struct smbsrv_request *req, struct smb_unlink *unl */ static NTSTATUS nbench_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, ioctl, (req, io)); @@ -183,7 +168,7 @@ static NTSTATUS nbench_ioctl(struct smbsrv_request *req, union smb_ioctl *io) */ static NTSTATUS nbench_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, chkpath, (req, cp)); @@ -200,7 +185,7 @@ static NTSTATUS nbench_chkpath(struct smbsrv_request *req, struct smb_chkpath *c */ static NTSTATUS nbench_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, qpathinfo, (req, info)); @@ -218,7 +203,7 @@ static NTSTATUS nbench_qpathinfo(struct smbsrv_request *req, union smb_fileinfo */ static NTSTATUS nbench_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, qfileinfo, (req, info)); @@ -237,7 +222,7 @@ static NTSTATUS nbench_qfileinfo(struct smbsrv_request *req, union smb_fileinfo */ static NTSTATUS nbench_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, setpathinfo, (req, st)); @@ -255,7 +240,7 @@ static NTSTATUS nbench_setpathinfo(struct smbsrv_request *req, union smb_setfile */ static NTSTATUS nbench_open(struct smbsrv_request *req, union smb_open *io) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, open, (req, io)); @@ -284,7 +269,7 @@ static NTSTATUS nbench_open(struct smbsrv_request *req, union smb_open *io) */ static NTSTATUS nbench_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, mkdir, (req, md)); @@ -299,7 +284,7 @@ static NTSTATUS nbench_mkdir(struct smbsrv_request *req, union smb_mkdir *md) */ static NTSTATUS nbench_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, rmdir, (req, rd)); @@ -316,7 +301,7 @@ static NTSTATUS nbench_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) */ static NTSTATUS nbench_rename(struct smbsrv_request *req, union smb_rename *ren) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, rename, (req, ren)); @@ -343,7 +328,7 @@ static NTSTATUS nbench_rename(struct smbsrv_request *req, union smb_rename *ren) */ static NTSTATUS nbench_copy(struct smbsrv_request *req, struct smb_copy *cp) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, copy, (req, cp)); @@ -358,7 +343,7 @@ static NTSTATUS nbench_copy(struct smbsrv_request *req, struct smb_copy *cp) */ static NTSTATUS nbench_read(struct smbsrv_request *req, union smb_read *rd) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, read, (req, rd)); @@ -386,7 +371,7 @@ static NTSTATUS nbench_read(struct smbsrv_request *req, union smb_read *rd) */ static NTSTATUS nbench_write(struct smbsrv_request *req, union smb_write *wr) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, write, (req, wr)); @@ -424,7 +409,7 @@ static NTSTATUS nbench_write(struct smbsrv_request *req, union smb_write *wr) */ static NTSTATUS nbench_seek(struct smbsrv_request *req, struct smb_seek *io) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, seek, (req, io)); @@ -439,7 +424,7 @@ static NTSTATUS nbench_seek(struct smbsrv_request *req, struct smb_seek *io) */ static NTSTATUS nbench_flush(struct smbsrv_request *req, struct smb_flush *io) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, flush, (req, io)); @@ -456,7 +441,7 @@ static NTSTATUS nbench_flush(struct smbsrv_request *req, struct smb_flush *io) */ static NTSTATUS nbench_close(struct smbsrv_request *req, union smb_close *io) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, close, (req, io)); @@ -482,7 +467,7 @@ static NTSTATUS nbench_close(struct smbsrv_request *req, union smb_close *io) */ static NTSTATUS nbench_exit(struct smbsrv_request *req) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, exit, (req)); @@ -495,7 +480,7 @@ static NTSTATUS nbench_exit(struct smbsrv_request *req) */ static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, lock, (req, lck)); @@ -528,7 +513,7 @@ static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck) static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, setfileinfo, (req, info)); @@ -547,7 +532,7 @@ static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req, */ static NTSTATUS nbench_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, fsinfo, (req, fs)); @@ -564,7 +549,7 @@ static NTSTATUS nbench_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) */ static NTSTATUS nbench_lpq(struct smbsrv_request *req, union smb_lpq *lpq) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, lpq, (req, lpq)); @@ -581,7 +566,7 @@ static NTSTATUS nbench_search_first(struct smbsrv_request *req, union smb_search void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, search_first, (req, io, search_private, callback)); @@ -609,7 +594,7 @@ static NTSTATUS nbench_search_next(struct smbsrv_request *req, union smb_search_ void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, search_next, (req, io, search_private, callback)); @@ -622,7 +607,7 @@ static NTSTATUS nbench_search_next(struct smbsrv_request *req, union smb_search_ /* close a search */ static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search_close *io) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, search_close, (req, io)); @@ -635,7 +620,7 @@ static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search /* SMBtrans - not used on file shares */ static NTSTATUS nbench_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) { - struct nbench_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; PASS_THRU_REQ(req, trans, (req,trans2)); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index b7c110ebdb..c9cf6de1e0 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -30,8 +30,8 @@ struct ntvfs_ops { enum ntvfs_type type; /* initial setup */ - NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename); - NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon); + NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename, int depth); + NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon, int depth); /* path operations */ NTSTATUS (*unlink)(struct smbsrv_request *req, struct smb_unlink *unl); @@ -85,3 +85,7 @@ struct ntvfs_critical_sizes { int sizeof_smbsrv_tcon; int sizeof_smbsrv_request; }; + +/* useful macro for backends */ +#define NTVFS_GET_PRIVATE(struct_name, name, req) \ + struct struct_name *name = req->tcon->ntvfs_private_list[req->ntvfs_depth] diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 923a131d5e..03873ce697 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -135,14 +135,29 @@ BOOL ntvfs_init(void) */ NTSTATUS ntvfs_init_connection(struct smbsrv_request *req) { - const char *handler = lp_ntvfs_handler(req->tcon->service); + const char **handlers = lp_ntvfs_handler(req->tcon->service); - req->tcon->ntvfs_ops = ntvfs_backend_byname(handler, req->tcon->type); + req->tcon->ntvfs_ops = ntvfs_backend_byname(handlers[0], req->tcon->type); if (!req->tcon->ntvfs_ops) { - DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handler, req->tcon->type)); + DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handlers[0], req->tcon->type)); return NT_STATUS_UNSUCCESSFUL; } return NT_STATUS_OK; } + + +/* + set the private pointer for a backend +*/ +void ntvfs_set_private(struct smbsrv_tcon *tcon, int depth, void *value) +{ + if (!tcon->ntvfs_private_list) { + tcon->ntvfs_private_list = talloc_array_p(tcon, void *, depth+1); + } else { + tcon->ntvfs_private_list = talloc_realloc_p(tcon->ntvfs_private_list, + void *, depth+1); + } + tcon->ntvfs_private_list[depth] = value; +} diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 29f21b1863..731e91f5c9 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -57,7 +57,8 @@ static BOOL is_exe_file(const char *fname) /* NTVFS open generic to any mapper */ -NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io) +NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, + const struct ntvfs_ops *ops) { NTSTATUS status; union smb_open io2; @@ -145,7 +146,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io) io2.generic.in.file_attr = io->openx.in.file_attrs; io2.generic.in.fname = io->openx.in.fname; - status = req->tcon->ntvfs_ops->open(req, &io2); + status = ops->open(req, &io2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -227,7 +228,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io) DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", io->open.in.flags, io2.generic.in.access_mask, io2.generic.in.share_access)); - status = req->tcon->ntvfs_ops->open(req, &io2); + status = ops->open(req, &io2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -249,7 +250,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io) /* NTVFS fsinfo generic to any mapper */ -NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, + const struct ntvfs_ops *ops) { NTSTATUS status; union smb_fsinfo fs2; @@ -261,7 +263,7 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) /* ask the backend for the generic info */ fs2.generic.level = RAW_QFS_GENERIC; - status = req->tcon->ntvfs_ops->fsinfo(req, &fs2); + status = ops->fsinfo(req, &fs2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -590,7 +592,8 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info /* NTVFS fileinfo generic to any mapper */ -NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info, + const struct ntvfs_ops *ops) { NTSTATUS status; union smb_fileinfo info2; @@ -603,7 +606,7 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf info2.generic.level = RAW_FILEINFO_GENERIC; info2.generic.in.fnum = info->generic.in.fnum; - status = req->tcon->ntvfs_ops->qfileinfo(req, &info2); + status = ops->qfileinfo(req, &info2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -613,7 +616,8 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf /* NTVFS pathinfo generic to any mapper */ -NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info, + const struct ntvfs_ops *ops) { NTSTATUS status; union smb_fileinfo info2; @@ -626,7 +630,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf info2.generic.level = RAW_FILEINFO_GENERIC; info2.generic.in.fname = info->generic.in.fname; - status = req->tcon->ntvfs_ops->qpathinfo(req, &info2); + status = ops->qpathinfo(req, &info2); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 826e331b84..f1c42e8920 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -29,11 +29,11 @@ */ NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { - return ntvfs_map_fsinfo(req, fs); + return ntvfs_map_fsinfo(req, fs, pvfs->ops); } if (sys_fsusage(pvfs->base_directory, diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 4881326ecb..de51d2e8fd 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -28,7 +28,7 @@ */ NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); NTSTATUS status; struct pvfs_filename *name; @@ -62,7 +62,7 @@ NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) */ NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); NTSTATUS status; struct pvfs_filename *name; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 26fd444984..1c6ecc1eb2 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -45,14 +45,14 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum) */ NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); int fd, flags; struct pvfs_filename *name; struct pvfs_file *f; NTSTATUS status; if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(req, io); + return ntvfs_map_open(req, io, pvfs->ops); } /* resolve the cifs name to a posix name */ @@ -155,7 +155,7 @@ do_open: */ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_file *f; if (io->generic.level != RAW_CLOSE_CLOSE) { diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 691ba91532..649036b09a 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -80,12 +80,12 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, */ NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_filename *name; NTSTATUS status; if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qpathinfo(req, info); + return ntvfs_map_qpathinfo(req, info, pvfs->ops); } /* resolve the cifs name to a posix name */ @@ -106,12 +106,12 @@ NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) */ NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_file *f; NTSTATUS status; if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qfileinfo(req, info); + return ntvfs_map_qfileinfo(req, info, pvfs->ops); } f = pvfs_find_fd(pvfs, info->generic.in.fnum); diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index d30645e76d..cbb0317638 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -28,7 +28,7 @@ */ NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) { - struct pvfs_private *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); ssize_t ret; struct pvfs_file *f; diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 40b84f7628..a58a1e9c6e 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -28,7 +28,7 @@ */ NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); NTSTATUS status; struct pvfs_filename *name1, *name2; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 5c535c9880..dfd6744eff 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -164,10 +164,18 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, name->stream_name = NULL; name->has_wildcard = False; - if (*cifs_name == '\\') { + while (*cifs_name == '\\') { cifs_name++; } + if (*cifs_name == 0) { + name->full_name = talloc_asprintf(name, "%s/.", pvfs->base_directory); + if (name->full_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; + } + ret = talloc_asprintf(name, "%s/%s", pvfs->base_directory, cifs_name); if (ret == NULL) { return NT_STATUS_NO_MEMORY; @@ -175,6 +183,10 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, p = ret + strlen(pvfs->base_directory) + 1; + if (p[strlen(cifs_name)-1] == '\\') { + p[strlen(cifs_name)-1] = 0; + } + /* now do an in-place conversion of '\' to '/', checking for legal characters */ for (;*p;p++) { diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 1d1d973d3f..414b010263 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -255,7 +255,7 @@ static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_sear BOOL (*callback)(void *, union smb_search_data *)) { struct pvfs_dir *dir; - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_search_state *search; uint_t reply_count; uint16_t search_attrib; @@ -331,7 +331,7 @@ static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_searc void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_search_state *search; struct pvfs_dir *dir; uint_t reply_count, max_count; @@ -379,7 +379,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i BOOL (*callback)(void *, union smb_search_data *)) { struct pvfs_dir *dir; - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_search_state *search; uint_t reply_count; uint16_t search_attrib, max_count; @@ -470,7 +470,7 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_search_state *search; struct pvfs_dir *dir; uint_t reply_count; @@ -547,7 +547,7 @@ found: /* close a search */ NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_search_state *search; uint16_t handle; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index a271b43d38..c2c58415be 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -29,7 +29,7 @@ NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { - struct pvfs_private *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_private, pvfs, req); struct utimbuf unix_times; struct pvfs_file *f; diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 98151d4e75..9e0353c041 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -63,7 +63,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, */ NTSTATUS pvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_dir *dir; NTSTATUS status; uint32_t i, total_deleted=0; diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 4194ced431..ac9d23b88f 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -29,7 +29,7 @@ */ NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) { - struct pvfs_private *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); ssize_t ret; struct pvfs_file *f; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 84a5647075..9bd060c639 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -50,7 +50,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) +static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename, int depth) { struct smbsrv_tcon *tcon = req->tcon; struct pvfs_state *pvfs; @@ -71,6 +71,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) pvfs->tcon = tcon; pvfs->base_directory = base_directory; + pvfs->ops = ntvfs_backend_byname("posix", NTVFS_DISK); /* the directory must exist. Note that we deliberately don't check that it is readable */ @@ -82,7 +83,8 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); - tcon->ntvfs_private = pvfs; + + ntvfs_set_private(tcon, depth, pvfs); pvfs_setup_options(pvfs); @@ -92,7 +94,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon) +static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon, int depth) { return NT_STATUS_OK; } @@ -110,7 +112,7 @@ static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) */ static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { - struct pvfs_state *pvfs = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_filename *name; NTSTATUS status; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 8b7ddfad88..bfb1fbf7ca 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -49,6 +49,8 @@ struct pvfs_state { } search; struct pvfs_file *open_files; + + const struct ntvfs_ops *ops; }; diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index 98ce6469a2..33b7cb7011 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -10,6 +10,8 @@ struct svfs_private { uint16_t next_search_handle; struct svfs_file *open_files; + + const struct ntvfs_ops *ops; }; struct svfs_dir { diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 04165cadd9..2e64920fc8 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -31,7 +31,7 @@ */ char *svfs_unix_path(struct smbsrv_request *req, const char *name) { - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); char *ret; if (*name != '\\') { diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 34a9c27f34..5bdec64f2b 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -61,15 +61,13 @@ static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offs directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) +static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename, int depth) { struct stat st; struct smbsrv_tcon *tcon = req->tcon; struct svfs_private *private; - tcon->ntvfs_private = talloc_p(tcon, struct svfs_private); - - private = tcon->ntvfs_private; + private = talloc_p(tcon, struct svfs_private); private->next_search_handle = 0; private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service)); @@ -85,6 +83,8 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); + ntvfs_set_private(tcon, depth, private); + DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); return NT_STATUS_OK; @@ -93,7 +93,7 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS svfs_disconnect(struct smbsrv_tcon *tcon) +static NTSTATUS svfs_disconnect(struct smbsrv_tcon *tcon, int depth) { return NT_STATUS_OK; } @@ -242,12 +242,13 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo */ static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) { + NTVFS_GET_PRIVATE(svfs_private, private, req); char *unix_path; struct stat st; DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level)); if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qpathinfo(req, info); + return ntvfs_map_qpathinfo(req, info, private->ops); } unix_path = svfs_unix_path(req, info->generic.in.fname); @@ -267,12 +268,12 @@ static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *i */ static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); struct svfs_file *f; struct stat st; if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qfileinfo(req, info); + return ntvfs_map_qfileinfo(req, info, private->ops); } f = find_fd(private, info->generic.in.fnum); @@ -295,7 +296,7 @@ static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i */ static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) { - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); char *unix_path; struct stat st; int fd, flags; @@ -303,7 +304,7 @@ static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) int create_flags, rdwr_flags; if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(req, io); + return ntvfs_map_open(req, io, private->ops); } if (lp_readonly(req->tcon->service)) { @@ -561,7 +562,7 @@ static NTSTATUS svfs_flush(struct smbsrv_request *req, struct smb_flush *io) */ static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io) { - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); struct svfs_file *f; if (io->generic.level != RAW_CLOSE_CLOSE) { @@ -660,11 +661,11 @@ static NTSTATUS svfs_setfileinfo(struct smbsrv_request *req, */ static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { - return ntvfs_map_fsinfo(req, fs); + return ntvfs_map_fsinfo(req, fs, private->ops); } if (sys_fsusage(private->connectpath, @@ -702,7 +703,7 @@ static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs) { struct stat st; - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); if (fs->generic.level != RAW_FSATTR_GENERIC) { return ntvfs_map_fsattr(req, fs); @@ -744,7 +745,7 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f { struct svfs_dir *dir; int i; - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); struct search_state *search; union smb_search_data file; uint_t max_count; @@ -813,7 +814,7 @@ static NTSTATUS svfs_search_next(struct smbsrv_request *req, union smb_search_ne { struct svfs_dir *dir; int i; - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); struct search_state *search; union smb_search_data file; uint_t max_count; @@ -896,7 +897,7 @@ found: /* close a search */ static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { - struct svfs_private *private = req->tcon->ntvfs_private; + NTVFS_GET_PRIVATE(svfs_private, private, req); struct search_state *search; for (search=private->search; search; search = search->next) { @@ -931,9 +932,6 @@ NTSTATUS ntvfs_simple_init(void) ZERO_STRUCT(ops); - /* fill in the name and type */ - ops.type = NTVFS_DISK; - /* fill in all the operations */ ops.connect = svfs_connect; ops.disconnect = svfs_disconnect; @@ -966,6 +964,8 @@ NTSTATUS ntvfs_simple_init(void) /* register ourselves with the NTVFS subsystem. We register under names 'simple' */ + + ops.type = NTVFS_DISK; ops.name = "simple"; ret = register_backend("ntvfs", &ops); -- cgit From 5401105ddfce91fd2fe479b442ea071b74c48467 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 23 Sep 2004 07:55:43 +0000 Subject: r2562: got rid of the "reference" backend that never happened - the code is too stale to be of any use as a reference. (This used to be commit 8d455a6f091d7aa528e86ae3b3712170b5fc6c2c) --- source4/ntvfs/reference/ref.h | 36 -- source4/ntvfs/reference/ref_util.c | 142 ------- source4/ntvfs/reference/vfs_ref.c | 843 ------------------------------------- 3 files changed, 1021 deletions(-) delete mode 100644 source4/ntvfs/reference/ref.h delete mode 100644 source4/ntvfs/reference/ref_util.c delete mode 100644 source4/ntvfs/reference/vfs_ref.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/reference/ref.h b/source4/ntvfs/reference/ref.h deleted file mode 100644 index 8ac4556420..0000000000 --- a/source4/ntvfs/reference/ref.h +++ /dev/null @@ -1,36 +0,0 @@ - -struct rvfs_private { - /* the meta-data database */ - TDB_CONTEXT *tdb; - - /* the base directory */ - char *connectpath; - - /* a linked list of open searches */ - struct search_state *search; - - /* next available search handle */ - uint16_t next_search_handle; -}; - -struct rvfs_dir { - uint_t count; - char *unix_dir; - struct { - char *name; - } *files; -}; - -struct search_state { - struct search_state *next, *prev; - TALLOC_CTX *mem_ctx; - uint16_t handle; - uint_t current_index; - struct rvfs_dir *dir; -}; - - -struct ref_struct { - NTTIME mtime, ctime, atime, wtime; - char *; -}; diff --git a/source4/ntvfs/reference/ref_util.c b/source4/ntvfs/reference/ref_util.c deleted file mode 100644 index 8be80183c5..0000000000 --- a/source4/ntvfs/reference/ref_util.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - simple NTVFS filesystem backend - - Copyright (C) Andrew Tridgell 2003 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* - utility functions for simple backend -*/ - -#include "includes.h" -#include "svfs.h" - -/* - convert a windows path to a unix path - don't do any manging or case sensitive handling -*/ -char *svfs_unix_path(struct smbsrv_request *req, const char *name) -{ - struct svfs_private *private = req->conn->ntvfs_private; - char *ret; - - if (*name != '\\') { - ret = talloc_asprintf(req->mem_ctx, "%s/%s", private->connectpath, name); - } else { - ret = talloc_asprintf(req->mem_ctx, "%s%s", private->connectpath, name); - } - all_string_sub(ret, "\\", "/", 0); - - strlower(ret); - - return ret; -} - - -/* - read a directory and find all matching file names and stat info - returned names are separate unix and DOS names. The returned names - are relative to the directory -*/ -struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, const char *pattern) -{ - char *unix_path; - char *p, *mask; - struct svfs_dir *dir; - DIR *odir; - struct dirent *dent; - uint_t allocated = 0; - char *low_mask; - - unix_path = svfs_unix_path(req, pattern); - if (!unix_path) { return NULL; } - - dir = talloc(mem_ctx, sizeof(struct svfs_dir)); - if (!dir) { return NULL; } - - dir->count = 0; - dir->files = 0; - - /* find the base directory */ - p = strrchr(unix_path, '/'); - if (!p) { return NULL; } - - dir->unix_dir = talloc_strndup(mem_ctx, unix_path, PTR_DIFF(p, unix_path)); - if (!dir->unix_dir) { return NULL; } - - /* the wildcard pattern is the last part */ - mask = p+1; - - low_mask = talloc_strdup(mem_ctx, mask); - if (!low_mask) { return NULL; } - strlower(low_mask); - - odir = opendir(dir->unix_dir); - if (!odir) { return NULL; } - - while ((dent = readdir(odir))) { - uint_t i = dir->count; - char *full_name; - char *low_name; - - low_name = talloc_strdup(mem_ctx, dent->d_name); - if (!low_name) { continue; } - strlower(low_name); - - /* check it matches the wildcard pattern */ - if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) { - continue; - } - - if (dir->count >= allocated) { - allocated = (allocated + 100) * 1.2; - dir->files = talloc_realloc(dir->files, allocated * sizeof(dir->files[0])); - if (!dir->files) { - closedir(odir); - return NULL; - } - } - - dir->files[i].name = low_name; - if (!dir->files[i].name) { continue; } - - asprintf(&full_name, "%s/%s", dir->unix_dir, dir->files[i].name); - if (!full_name) { continue; } - - if (stat(full_name, &dir->files[i].st) == 0) { - dir->count++; - } - - free(full_name); - } - - closedir(odir); - - return dir; -} - - -/* - convert a unix stat struct to a dos attrib -*/ -uint32_t svfs_file_attrib(struct stat *st) -{ - if (S_ISDIR(st->st_mode)) { - return FILE_ATTRIBUTE_DIRECTORY; - } - return 0; -} diff --git a/source4/ntvfs/reference/vfs_ref.c b/source4/ntvfs/reference/vfs_ref.c deleted file mode 100644 index 7a85afa4bb..0000000000 --- a/source4/ntvfs/reference/vfs_ref.c +++ /dev/null @@ -1,843 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - simple NTVFS filesystem backend - - Copyright (C) Andrew Tridgell 2003 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* - this implements a very simple NTVFS filesystem backend. - - this backend largely ignores the POSIX -> CIFS mappings, just doing absolutely - minimal work to give a working backend. -*/ - -#include "includes.h" -#include "svfs.h" - -/* - connect to a share - used when a tree_connect operation comes - in. For a disk based backend we needs to ensure that the base - directory exists (tho it doesn't need to be accessible by the user, - that comes later) -*/ -static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename) -{ - struct stat st; - struct tcon_context *conn = req->conn; - struct svfs_private *private; - - conn->ntvfs_private = talloc(conn->mem_ctx, sizeof(struct svfs_private)); - - private = conn->ntvfs_private; - - private->connectpath = talloc_strdup(conn->mem_ctx, lp_pathname(conn->service)); - - /* the directory must exist */ - if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { - DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", - private->connectpath, sharename)); - return NT_STATUS_BAD_NETWORK_NAME; - } - - conn->fs_type = talloc_strdup(conn->mem_ctx, "NTFS"); - conn->dev_type = talloc_strdup(conn->mem_ctx, "A:"); - - return NT_STATUS_OK; -} - -/* - disconnect from a share -*/ -static NTSTATUS svfs_disconnect(struct smbsrv_request *req) -{ - return NT_STATUS_OK; -} - -/* - delete a file - the dirtype specifies the file types to include in the search. - The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) -*/ -static NTSTATUS svfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) -{ - char *unix_path; - - unix_path = svfs_unix_path(req, unl->in.pattern); - - /* ignoring wildcards ... */ - if (unlink(unix_path) == -1) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - - -/* - ioctl interface - we don't do any -*/ -static NTSTATUS svfs_ioctl(struct smbsrv_request *req, struct smb_ioctl *io) -{ - return NT_STATUS_INVALID_PARAMETER; -} - -/* - check if a directory exists -*/ -static NTSTATUS svfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) -{ - char *unix_path; - struct stat st; - - unix_path = svfs_unix_path(req, cp->in.path); - - if (stat(unix_path, &st) == -1) { - return map_nt_error_from_unix(errno); - } - - if (!S_ISDIR(st.st_mode)) { - return NT_STATUS_NOT_A_DIRECTORY; - } - - return NT_STATUS_OK; -} - -/* - approximately map a struct stat to a fileinfo struct -*/ -static NTSTATUS map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, struct stat *st) -{ - switch (info->generic.level) { - case SMB_FILEINFO_NETWORK_OPEN_INFORMATION: - unix_to_nt_time(&info->netopen.out.create_time, st->st_ctime); - unix_to_nt_time(&info->netopen.out.access_time, st->st_atime); - unix_to_nt_time(&info->netopen.out.write_time, st->st_mtime); - unix_to_nt_time(&info->netopen.out.change_time, st->st_mtime); - info->netopen.out.alloc_size = st->st_size; - info->netopen.out.size = st->st_size; - info->netopen.out.attrib = svfs_file_attrib(st); - info->netopen.out.unknown = 0; - return NT_STATUS_OK; - - case SMB_FILEINFO_ALL_INFO: - unix_to_nt_time(&info->all_info.out.create_time, st->st_ctime); - unix_to_nt_time(&info->all_info.out.access_time, st->st_atime); - unix_to_nt_time(&info->all_info.out.write_time, st->st_mtime); - unix_to_nt_time(&info->all_info.out.change_time, st->st_mtime); - info->all_info.out.attrib = svfs_file_attrib(st); - info->all_info.out.alloc_size = st->st_size; - info->all_info.out.size = st->st_size; - info->all_info.out.nlink = st->st_nlink; - info->all_info.out.delete_pending = 0; - info->all_info.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; - info->all_info.out.index_number = st->st_ino; - info->all_info.out.ea_size = 0; - info->all_info.out.access_flags = 0xd01BF; /* what is this!? */ - info->all_info.out.current_offset = 0; - info->all_info.out.open_mode = 0; /* what do do put here!? */ - info->all_info.out.alignment_requirement = 0; /* what do do put here!? */ - info->all_info.out.fname = talloc_strdup(req->mem_ctx, "TODO - STORE FILENAME"); - return NT_STATUS_OK; - - case SMB_FILEINFO_BASIC: - unix_to_nt_time(&info->basic.out.create_time, st->st_ctime); - unix_to_nt_time(&info->basic.out.access_time, st->st_atime); - unix_to_nt_time(&info->basic.out.write_time, st->st_mtime); - unix_to_nt_time(&info->basic.out.change_time, st->st_mtime); - info->basic.out.attrib = svfs_file_attrib(st); - return NT_STATUS_OK; - - case SMB_FILEINFO_INFO_STANDARD: - info->info_standard.out.create_time = st->st_ctime; - info->info_standard.out.access_time = st->st_atime; - info->info_standard.out.write_time = st->st_mtime; - info->info_standard.out.size = st->st_size; - info->info_standard.out.alloc_size = st->st_size; - info->info_standard.out.attrib = svfs_file_attrib(st); - return NT_STATUS_OK; - - case SMB_FILEINFO_INFO_STANDARD_EA: - info->info_standard_ea.out.create_time = st->st_ctime; - info->info_standard_ea.out.access_time = st->st_atime; - info->info_standard_ea.out.write_time = st->st_mtime; - info->info_standard_ea.out.size = st->st_size; - info->info_standard_ea.out.alloc_size = st->st_size; - info->info_standard_ea.out.attrib = svfs_file_attrib(st); - info->info_standard_ea.out.ea_size = 0; - return NT_STATUS_OK; - - case SMB_FILEINFO_STANDARD_INFO: - info->standard_info.out.alloc_size = st->st_size; - info->standard_info.out.size = st->st_size; - info->standard_info.out.nlink = st->st_nlink; - info->standard_info.out.delete_pending = 0; - info->standard_info.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; - info->standard_info.out.unknown = 0; - return NT_STATUS_OK; - - case SMB_FILEINFO_INTERNAL: - info->internal.out.device = st->st_dev; - info->internal.out.device = st->st_ino; - return NT_STATUS_OK; - - case SMB_FILEINFO_EA: - info->ea.out.unknown = 0; - return NT_STATUS_OK; - - case SMB_FILEINFO_ATTRIB_TAGINFO: - info->tag.out.attrib = svfs_file_attrib(st); - info->tag.out.reparse_tag = 0; - return NT_STATUS_OK; - - case SMB_FILEINFO_STREAM: - /* setup a single data stream */ - info->stream.out.num_streams = 1; - info->stream.out.streams = talloc(req->mem_ctx, sizeof(info->stream.out.streams[0])); - if (!info->stream.out.streams) { - return NT_STATUS_NO_MEMORY; - } - info->stream.out.streams[0].size = st->st_size; - info->stream.out.streams[0].alloc_size = st->st_size; - info->stream.out.streams[0].stream_name = talloc_strdup(req->mem_ctx,"::$DATA"); - return NT_STATUS_OK; - } - - return NT_STATUS_INVALID_LEVEL; -} - -/* - return info on a pathname -*/ -static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) -{ - char *unix_path; - struct stat st; - - unix_path = svfs_unix_path(req, info->basic.in.fname); - - if (stat(unix_path, &st) == -1) { - return map_nt_error_from_unix(errno); - } - - return map_fileinfo(req, info, &st); -} - -/* - query info on a open file -*/ -static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) -{ - struct stat st; - - if (fstat(info->generic.in.fnum, &st) == -1) { - return map_nt_error_from_unix(errno); - } - - return map_fileinfo(req, info, &st); -} - - -/* - set info on a pathname -*/ -static NTSTATUS svfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - open a file -*/ -static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) -{ - char *unix_path; - struct stat st; - int fd, flags; - - if (io->generic.level != SMB_OPEN_GENERIC) { - return ntvfs_map_open(req, io); - } - - unix_path = svfs_unix_path(req, io->ntcreatex.in.fname); - - switch (io->generic.in.open_disposition) { - case FILE_SUPERSEDE: - flags = O_RDWR | O_CREAT | O_TRUNC; - break; - case FILE_OPEN: - flags = O_RDWR; - break; - case FILE_CREATE: - flags = O_RDWR | O_CREAT | O_EXCL; - break; - case FILE_OPEN_IF: - flags = O_RDWR | O_CREAT; - break; - case FILE_OVERWRITE: - flags = O_RDWR; - break; - case FILE_OVERWRITE_IF: - flags = O_RDWR | O_CREAT | O_TRUNC; - break; - default: - flags = O_RDWR; - break; - } - - if (io->generic.in.create_options & FILE_DIRECTORY_FILE) { - flags = O_RDONLY | O_DIRECTORY; - switch (io->generic.in.open_disposition) { - case FILE_CREATE: - if (mkdir(unix_path, 0755) == -1) { - return map_nt_error_from_unix(errno); - } - break; - case FILE_OPEN_IF: - if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { - return map_nt_error_from_unix(errno); - } - break; - } - } - - fd = open(unix_path, flags, 0644); - if (fd == -1) { - return map_nt_error_from_unix(errno); - } - - if (fstat(fd, &st) == -1) { - close(fd); - return map_nt_error_from_unix(errno); - } - - ZERO_STRUCT(io->generic.out); - - unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); - unix_to_nt_time(&io->generic.out.access_time, st.st_atime); - unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); - unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); - io->generic.out.fnum = fd; - io->generic.out.alloc_size = st.st_size; - io->generic.out.size = st.st_size; - io->generic.out.file_attr = svfs_file_attrib(&st); - io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; - - return NT_STATUS_OK; -} - -/* - create a directory -*/ -static NTSTATUS svfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) -{ - char *unix_path; - - if (md->generic.level != RAW_MKDIR_MKDIR) { - return NT_STATUS_INVALID_LEVEL; - } - - unix_path = svfs_unix_path(req, md->mkdir.in.path); - - if (mkdir(unix_path, 0777) == -1) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -/* - remove a directory -*/ -static NTSTATUS svfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) -{ - char *unix_path; - - unix_path = svfs_unix_path(req, rd->in.path); - - if (rmdir(unix_path) == -1) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -/* - rename a set of files -*/ -static NTSTATUS svfs_rename(struct smbsrv_request *req, union smb_rename *ren) -{ - char *unix_path1, *unix_path2; - - unix_path1 = svfs_unix_path(req, ren->in.pattern1); - unix_path2 = svfs_unix_path(req, ren->in.pattern2); - - if (rename(unix_path1, unix_path2) != 0) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -/* - copy a set of files -*/ -static NTSTATUS svfs_copy(struct smbsrv_request *req, struct smb_copy *cp) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - read from a file -*/ -static NTSTATUS svfs_read(struct smbsrv_request *req, union smb_read *rd) -{ - ssize_t ret; - - if (rd->generic.level != SMB_READ_READX) { - return NT_STATUS_NOT_SUPPORTED; - } - - ret = pread(rd->readx.in.fnum, - rd->readx.out.data, - rd->readx.in.maxcnt, - rd->readx.in.offset); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - rd->readx.out.nread = ret; - rd->readx.out.remaining = 0; /* should fill this in? */ - - return NT_STATUS_OK; -} - -/* - write to a file -*/ -static NTSTATUS svfs_write(struct smbsrv_request *req, union smb_write *wr) -{ - ssize_t ret; - - switch (wr->generic.level) { - case SMB_WRITE_WRITEX: - ret = pwrite(wr->writex.in.fnum, - wr->writex.in.data, - wr->writex.in.count, - wr->writex.in.offset); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - wr->writex.out.nwritten = ret; - wr->writex.out.remaining = 0; /* should fill this in? */ - - return NT_STATUS_OK; - - case SMB_WRITE_WRITE: - if (wr->write.in.count == 0) { - /* a truncate! */ - ret = ftruncate(wr->write.in.fnum, wr->write.in.offset); - } else { - ret = pwrite(wr->write.in.fnum, - wr->write.in.data, - wr->write.in.count, - wr->write.in.offset); - } - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - wr->write.out.nwritten = ret; - - return NT_STATUS_OK; - } - - return NT_STATUS_NOT_SUPPORTED; -} - -/* - seek in a file -*/ -static NTSTATUS svfs_seek(struct smbsrv_request *req, struct smb_seek *io) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - flush a file -*/ -static NTSTATUS svfs_flush(struct smbsrv_request *req, struct smb_flush *io) -{ - fsync(io->in.fnum); - return NT_STATUS_OK; -} - -/* - close a file -*/ -static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io) -{ - if (io->generic.level != SMB_CLOSE_CLOSE) { - /* we need a mapping function */ - return NT_STATUS_INVALID_LEVEL; - } - - if (close(io->close.in.fnum) != 0) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -/* - exit - closing files? -*/ -static NTSTATUS svfs_exit(struct smbsrv_request *req) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - lock a byte range -*/ -static NTSTATUS svfs_lock(struct smbsrv_request *req, union smb_lock *lck) -{ - DEBUG(0,("REWRITE: not doing byte range locking!\n")); - return NT_STATUS_OK; -} - -/* - set info on a open file -*/ -static NTSTATUS svfs_setfileinfo(struct smbsrv_request *req, - union smb_setfileinfo *info) -{ - DEBUG(0,("REWRITE: svfs_setfileinfo: not doing setfileinfo level %d\n", - info->generic.level)); - switch (info->generic.level) { - case SMB_SETFILEINFO_BASIC: - info->basic.out.ea_error_offset = 0; - break; - case SMB_SETFILEINFO_END_OF_FILE: - if (ftruncate(info->eof.in.fnum, info->eof.in.size) != 0) { - return map_nt_error_from_unix(errno); - } - info->eof.out.ea_error_offset = 0; - break; - case SMB_SETFILEINFO_ALLOCATION: - info->eof.out.ea_error_offset = 0; - break; - } - return NT_STATUS_OK; -} - - -/* - return filesystem space info -*/ -static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) -{ - struct svfs_private *private = req->conn->ntvfs_private; - - if (fs->generic.level != SMB_FSINFO_GENERIC) { - return ntvfs_map_fsinfo(req, fs); - } - - if (sys_fsusage(private->connectpath, - &fs->generic.out.blocks_free, - &fs->generic.out.blocks_total) == -1) { - return map_nt_error_from_unix(errno); - } - - fs->generic.out.block_size = 512; - - return NT_STATUS_OK; -} - -/* - return filesystem attribute info -*/ -static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs) -{ - struct stat st; - struct svfs_private *private = req->conn->ntvfs_private; - - if (fs->generic.level != SMB_FSATTR_GENERIC) { - return ntvfs_map_fsattr(req, fs); - } - - if (stat(private->connectpath, &st) != 0) { - return map_nt_error_from_unix(errno); - } - - unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); - fs->generic.out.fs_attr = - FILE_CASE_PRESERVED_NAMES | - FILE_CASE_SENSITIVE_SEARCH | - FILE_PERSISTENT_ACLS; - fs->generic.out.max_file_component_length = 255; - fs->generic.out.serial_number = 1; - fs->generic.out.fs_type = talloc_strdup(req->mem_ctx, "NTFS"); - fs->generic.out.volume_name = talloc_strdup(req->mem_ctx, - lp_servicename(req->conn->service)); - - return NT_STATUS_OK; -} - -/* - return print queue info -*/ -static NTSTATUS svfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - list files in a directory matching a wildcard pattern -*/ -NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - struct svfs_dir *dir; - int i; - struct svfs_private *private = req->conn->ntvfs_private; - struct search_state *search; - union smb_search_data file; - TALLOC_CTX *mem_ctx; - uint_t max_count; - - if (io->generic.level != SMB_SEARCH_T2FFIRST_BOTH) { - return NT_STATUS_NOT_SUPPORTED; - } - - mem_ctx = talloc_init("svfs_search"); - - search = talloc_zero(mem_ctx, sizeof(struct search_state)); - if (!search) { - return NT_STATUS_NO_MEMORY; - } - - max_count = io->t2ffirst.in.max_count; - - dir = svfs_list(mem_ctx, req, io->t2ffirst.in.pattern); - if (!dir) { - talloc_destroy_pool(mem_ctx); - return NT_STATUS_FOOBAR; - } - - search->mem_ctx = mem_ctx; - search->handle = private->next_search_handle; - search->dir = dir; - - if (dir->count < max_count) { - max_count = dir->count; - } - - for (i=0; i < max_count;i++) { - ZERO_STRUCT(file); - unix_to_nt_time(&file.both.create_time, dir->files[i].st.st_ctime); - unix_to_nt_time(&file.both.access_time, dir->files[i].st.st_atime); - unix_to_nt_time(&file.both.write_time, dir->files[i].st.st_mtime); - unix_to_nt_time(&file.both.change_time, dir->files[i].st.st_mtime); - file.both.name = dir->files[i].name; - file.both.short_name = dir->files[i].name; - file.both.size = dir->files[i].st.st_size; - file.both.ex_attrib = svfs_file_attrib(&dir->files[i].st); - - if (!callback(search_private, &file)) { - break; - } - } - - search->current_index = i; - - io->t2ffirst.out.count = i; - io->t2ffirst.out.handle = search->handle; - io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; - - /* work out if we are going to keep the search state */ - if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || - ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - talloc_destroy(search->mem_ctx); - } else { - private->next_search_handle++; - DLIST_ADD(private->search, search); - } - - return NT_STATUS_OK; -} - -/* continue a search */ -NTSTATUS svfs_search_next(struct smbsrv_request *req, union smb_search_next *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - struct svfs_dir *dir; - int i; - struct svfs_private *private = req->conn->ntvfs_private; - struct search_state *search; - union smb_search_data file; - uint_t max_count; - - if (io->generic.level != SMB_SEARCH_T2FFIRST_BOTH) { - return NT_STATUS_NOT_SUPPORTED; - } - - for (search=private->search; search; search = search->next) { - if (search->handle == io->t2fnext.in.handle) break; - } - - if (!search) { - /* we didn't find the search handle */ - return NT_STATUS_FOOBAR; - } - - dir = search->dir; - - /* the client might be asking for something other than just continuing - with the search */ - if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && - (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && - io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { - /* look backwards first */ - for (i=search->current_index; i > 0; i--) { - if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { - search->current_index = i; - goto found; - } - } - - /* then look forwards */ - for (i=search->current_index+1; i <= dir->count; i++) { - if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { - search->current_index = i; - goto found; - } - } - } - -found: - max_count = search->current_index + io->t2fnext.in.max_count; - - if (max_count > dir->count) { - max_count = dir->count; - } - - for (i = search->current_index; i < max_count;i++) { - ZERO_STRUCT(file); - unix_to_nt_time(&file.both.create_time, dir->files[i].st.st_ctime); - unix_to_nt_time(&file.both.access_time, dir->files[i].st.st_atime); - unix_to_nt_time(&file.both.write_time, dir->files[i].st.st_mtime); - unix_to_nt_time(&file.both.change_time, dir->files[i].st.st_mtime); - file.both.name = dir->files[i].name; - file.both.short_name = dir->files[i].name; - file.both.size = dir->files[i].st.st_size; - file.both.ex_attrib = svfs_file_attrib(&dir->files[i].st); - - if (!callback(search_private, &file)) { - break; - } - } - - io->t2fnext.out.count = i - search->current_index; - io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; - - search->current_index = i; - - /* work out if we are going to keep the search state */ - if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || - ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - DLIST_REMOVE(private->search, search); - talloc_destroy(search->mem_ctx); - } - - return NT_STATUS_OK; -} - -/* close a search */ -NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_close *io) -{ - struct svfs_private *private = req->conn->ntvfs_private; - struct search_state *search; - - for (search=private->search; search; search = search->next) { - if (search->handle == io->findclose.in.handle) break; - } - - if (!search) { - /* we didn't find the search handle */ - return NT_STATUS_FOOBAR; - } - - DLIST_REMOVE(private->search, search); - talloc_destroy(search->mem_ctx); - - return NT_STATUS_OK; -} - - -/* - initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem - */ -BOOL posix_vfs_init(void) -{ - BOOL ret; - struct ntvfs_ops ops; - - ZERO_STRUCT(ops); - - /* fill in all the operations */ - ops.connect = svfs_connect; - ops.disconnect = svfs_disconnect; - ops.unlink = svfs_unlink; - ops.chkpath = svfs_chkpath; - ops.qpathinfo = svfs_qpathinfo; - ops.setpathinfo = svfs_setpathinfo; - ops.open = svfs_open; - ops.mkdir = svfs_mkdir; - ops.rmdir = svfs_rmdir; - ops.rename = svfs_rename; - ops.copy = svfs_copy; - ops.ioctl = svfs_ioctl; - ops.read = svfs_read; - ops.write = svfs_write; - ops.seek = svfs_seek; - ops.flush = svfs_flush; - ops.close = svfs_close; - ops.exit = svfs_exit; - ops.lock = svfs_lock; - ops.setfileinfo = svfs_setfileinfo; - ops.qfileinfo = svfs_qfileinfo; - ops.fsinfo = svfs_fsinfo; - ops.fsattr = svfs_fsattr; - ops.lpq = svfs_lpq; - ops.search_first = svfs_search_first; - ops.search_next = svfs_search_next; - ops.search_close = svfs_search_close; - - /* register ourselves with the NTVFS subsystem. We register under the name 'default' - as we wish to be the default backend */ - ret = ntvfs_register("simple", NTVFS_DISK, &ops); - - if (!ret) { - DEBUG(0,("Failed to register POSIX backend!\n")); - return False; - } - - return True; -} -- cgit From 9c89a30113df8b5a2ebf971f5e1fbb32ba1dc40c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Sep 2004 00:42:20 +0000 Subject: r2572: fixed two places where status is not initialised in the nbench backend (This used to be commit 4103392a597349890e0e7ea1c41d5b0ab3816853) --- source4/ntvfs/nbench/vfs_nbench.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index b88c65d5db..eebf6f1dde 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -110,7 +110,7 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename ntvfs_set_private(req->tcon, depth, private); - PASS_THRU(req->tcon, connect, (req, sharename, depth+1)); + status = PASS_THRU(req->tcon, connect, (req, sharename, depth+1)); return status; } @@ -125,7 +125,7 @@ static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon, int depth) close(private->log_fd); - PASS_THRU(tcon, disconnect, (tcon, depth+1)); + status = PASS_THRU(tcon, disconnect, (tcon, depth+1)); return status; } -- cgit From cb0cd473a0c7d3d7565fccdc9be30cefd19a0473 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Sep 2004 00:44:42 +0000 Subject: r2573: - added a configure test for nanosecond time resolution in struct stat (recently Linux systems support this, allowing us to support the full resolution in NTTIME) - use nanosecond resolution in the posix backend if available - moved the configure tests and list of object files for the posix backend into ntvfs/posix/ to keep them more neatlly separated. (This used to be commit d92ad9f307fe16a3b253a0555b437f14c94b4dd7) --- source4/ntvfs/config.m4 | 5 +++-- source4/ntvfs/config.mk | 25 +------------------------ source4/ntvfs/posix/config.m4 | 23 +++++++++++++++++++++++ source4/ntvfs/posix/config.mk | 23 +++++++++++++++++++++++ source4/ntvfs/posix/pvfs_fileinfo.c | 6 ++++++ 5 files changed, 56 insertions(+), 26 deletions(-) create mode 100644 source4/ntvfs/posix/config.m4 create mode 100644 source4/ntvfs/posix/config.mk (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index f23610fef4..051a6883e2 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -1,5 +1,8 @@ dnl # NTVFS Server subsystem +SMB_INCLUDE_M4(ntvfs/posix/config.m4) +SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/posix/config.mk) + SMB_MODULE_MK(ntvfs_cifs, NTVFS, STATIC, ntvfs/config.mk) SMB_MODULE_MK(ntvfs_simple, NTVFS, STATIC, ntvfs/config.mk) @@ -8,8 +11,6 @@ SMB_MODULE_MK(ntvfs_print, NTVFS, STATIC, ntvfs/config.mk) SMB_MODULE_MK(ntvfs_ipc, NTVFS, STATIC, ntvfs/config.mk) -SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) - SMB_MODULE_MK(ntvfs_nbench, NTVFS, STATIC, ntvfs/config.mk) SMB_SUBSYSTEM_MK(NTVFS,ntvfs/config.mk) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index cf48cc61c2..d00cc2b1f4 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -35,33 +35,10 @@ INIT_OBJ_FILES = \ ntvfs/ipc/vfs_ipc.o \ ntvfs/ipc/ipc_rap.o \ ntvfs/ipc/rap_server.o - # End MODULE ntvfs_ipc ################################################ -################################################ -# Start MODULE ntvfs_posix -[MODULE::ntvfs_posix] -INIT_OBJ_FILES = \ - ntvfs/posix/vfs_posix.o -ADD_OBJ_FILES = \ - ntvfs/posix/pvfs_util.o \ - ntvfs/posix/pvfs_search.o \ - ntvfs/posix/pvfs_dirlist.o \ - ntvfs/posix/pvfs_fileinfo.o \ - ntvfs/posix/pvfs_unlink.o \ - ntvfs/posix/pvfs_mkdir.o \ - ntvfs/posix/pvfs_open.o \ - ntvfs/posix/pvfs_read.o \ - ntvfs/posix/pvfs_write.o \ - ntvfs/posix/pvfs_fsinfo.o \ - ntvfs/posix/pvfs_qfileinfo.o \ - ntvfs/posix/pvfs_setfileinfo.o \ - ntvfs/posix/pvfs_rename.o \ - ntvfs/posix/pvfs_resolve.o \ - ntvfs/posix/pvfs_shortname.o -# End MODULE ntvfs_posix -################################################ + ################################################ # Start MODULE ntvfs_nbench diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 new file mode 100644 index 0000000000..d8a2e3ec36 --- /dev/null +++ b/source4/ntvfs/posix/config.m4 @@ -0,0 +1,23 @@ +SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) + + +dnl ############################################# +dnl see if we have nanosecond resolution for stat +AC_CACHE_CHECK([for tv_nsec nanosecond fields in struct stat],ac_cv_have_stat_tv_nsec,[ +AC_TRY_COMPILE( +[ +#include +#include +#include +], +[struct stat st; + st.st_mtim.tv_nsec; + st.st_atim.tv_nsec; + st.st_ctim.tv_nsec; +], +ac_cv_decl_have_stat_tv_nsec=yes, +ac_cv_decl_have_stat_tv_nsec=no) +]) +if test x"$ac_cv_decl_have_stat_tv_nsec" = x"yes"; then + AC_DEFINE(HAVE_STAT_TV_NSEC,1,[Whether stat has tv_nsec nanosecond fields]) +fi diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk new file mode 100644 index 0000000000..ad4c754ca7 --- /dev/null +++ b/source4/ntvfs/posix/config.mk @@ -0,0 +1,23 @@ +################################################ +# Start MODULE ntvfs_posix +[MODULE::ntvfs_posix] +INIT_OBJ_FILES = \ + ntvfs/posix/vfs_posix.o +ADD_OBJ_FILES = \ + ntvfs/posix/pvfs_util.o \ + ntvfs/posix/pvfs_search.o \ + ntvfs/posix/pvfs_dirlist.o \ + ntvfs/posix/pvfs_fileinfo.o \ + ntvfs/posix/pvfs_unlink.o \ + ntvfs/posix/pvfs_mkdir.o \ + ntvfs/posix/pvfs_open.o \ + ntvfs/posix/pvfs_read.o \ + ntvfs/posix/pvfs_write.o \ + ntvfs/posix/pvfs_fsinfo.o \ + ntvfs/posix/pvfs_qfileinfo.o \ + ntvfs/posix/pvfs_setfileinfo.o \ + ntvfs/posix/pvfs_rename.o \ + ntvfs/posix/pvfs_resolve.o \ + ntvfs/posix/pvfs_shortname.o +# End MODULE ntvfs_posix +################################################ diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index be559cf179..77eb10422d 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -139,6 +139,12 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) unix_to_nt_time(&name->dos.access_time, name->st.st_atime); unix_to_nt_time(&name->dos.write_time, name->st.st_mtime); unix_to_nt_time(&name->dos.change_time, name->st.st_mtime); +#ifdef HAVE_STAT_TV_NSEC + name->dos.create_time += name->st.st_ctim.tv_nsec / 100; + name->dos.access_time += name->st.st_atim.tv_nsec / 100; + name->dos.write_time += name->st.st_mtim.tv_nsec / 100; + name->dos.change_time += name->st.st_mtim.tv_nsec / 100; +#endif name->dos.attrib = dos_mode_from_stat(pvfs, &name->st); name->dos.alloc_size = name->st.st_size; name->dos.nlink = name->st.st_nlink; -- cgit From 5d4fc1284ea662029f509a88ca49a2a5812f78f1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Sep 2004 03:31:43 +0000 Subject: r2580: fixed an uninitialised byte found by valgrind (This used to be commit 0806378b0e34ba3d665a9db739539819f3f52054) --- source4/ntvfs/ipc/rap_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 4ab1915c81..b414b40d7e 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -32,12 +32,12 @@ NTSTATUS rap_netshareenum(struct smbsrv_request *req, r->out.info = talloc_array_p(req, union rap_shareenum_info, 2); - strncpy(r->out.info[0].info1.name, "C$", 12); + strncpy(r->out.info[0].info1.name, "C$", sizeof(r->out.info[0].info1.name)); r->out.info[0].info1.pad = 0; r->out.info[0].info1.type = 0; r->out.info[0].info1.comment = talloc_strdup(req, "Bla"); - strncpy(r->out.info[1].info1.name, "IPC$", 12); + strncpy(r->out.info[1].info1.name, "IPC$", sizeof(r->out.info[0].info1.name)); r->out.info[1].info1.pad = 0; r->out.info[1].info1.type = 1; r->out.info[1].info1.comment = talloc_strdup(req, "Blub"); -- cgit From a1ed65e8edd80cff405f91c5ab93f53e3afb2479 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Sep 2004 06:49:10 +0000 Subject: r2586: updated the nbench example in the README to reflect the new chaining syntax (This used to be commit be20b3164cfe1d5c228072722cb6e5894fdacb23) --- source4/ntvfs/nbench/README | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/README b/source4/ntvfs/nbench/README index 9aaae9d7ee..e1601e4440 100644 --- a/source4/ntvfs/nbench/README +++ b/source4/ntvfs/nbench/README @@ -5,8 +5,7 @@ filter module. Here is an example config that passes through to the CIFS NTVFS backend. [bench] - ntvfs handler = nbench - nbench:passthru = cifs + ntvfs handler = nbench cifs cifs:server = myserver cifs:user = myuser cifs:password = mypass -- cgit From 4f2058175e8763a7ed4066f16e934779506d7035 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Sep 2004 07:28:16 +0000 Subject: r2591: fixed two errors in simple backend found with valgrind (This used to be commit 1730882b9d2ecff1b65e5fc85961edb300a9ce17) --- source4/ntvfs/simple/vfs_simple.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 5bdec64f2b..5b2fe9df56 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -72,6 +72,8 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename, private->next_search_handle = 0; private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service)); private->open_files = NULL; + private->ops = ntvfs_backend_byname("simple", NTVFS_DISK); + private->search = NULL; /* the directory must exist */ if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { -- cgit From 4fa2904290e2c345eae76ad66fc284b76eccd5f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 04:45:52 +0000 Subject: r2613: use a talloc destructor to ensure that file descriptors are not leaked on abnormal termination of a connection. As long as the top level connection structure is freed then that should cascade down to the file structure, and call this destructor which will close the open file descriptor. In general I'd like to use this technique in any place in Samba4 where we hold operating system resources that we need to make sure are released on abnormal termination. (This used to be commit ed87b7fcbd9fedc155528ce6dd8ab5d5fce637b2) --- source4/ntvfs/posix/pvfs_open.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1c6ecc1eb2..a1c6dcdcfe 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -38,6 +38,21 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, uint16_t fnum) return NULL; } +/* + by using a destructor we make sure that abnormal cleanup will not + leak file descriptors (assuming at least the top level pointer is freed, which + will cascade down to here) +*/ +static int pvfs_fd_destructor(void *p) +{ + struct pvfs_file *f = p; + if (f->fd != -1) { + close(f->fd); + f->fd = -1; + } + return 0; +} + /* open a file TODO: this is a temporary implementation derived from the simple backend @@ -132,6 +147,10 @@ do_open: f->fd = fd; f->name = talloc_steal(f, name); + /* setup a destructor to avoid file descriptor leaks on + abnormal termination */ + talloc_set_destructor(f, pvfs_fd_destructor); + DLIST_ADD(pvfs->open_files, f); ZERO_STRUCT(io->generic.out); @@ -157,6 +176,7 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) { NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); struct pvfs_file *f; + NTSTATUS status; if (io->generic.level != RAW_CLOSE_CLOSE) { /* we need a mapping function */ @@ -169,12 +189,16 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) } if (close(f->fd) != 0) { - return pvfs_map_errno(pvfs, errno); + status = pvfs_map_errno(pvfs, errno); + } else { + status = NT_STATUS_OK; } + talloc_set_destructor(f, NULL); + DLIST_REMOVE(pvfs->open_files, f); talloc_free(f); - return NT_STATUS_OK; + return status; } -- cgit From d79c7d41da373dea7f95506c178b18f0dd896043 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 11:24:10 +0000 Subject: r2627: use the new talloc capabilities in a bunch more places in the rpc server code. This fixes a number of memory leaks I found when testing with valgrind and smbtorture, as the cascading effect of a talloc_free() ensures that anything derived from the top level object is destroyed on disconnect. (This used to be commit 76d0b8206ce64d6ff4a192979c43dddbec726d6e) --- source4/ntvfs/ipc/vfs_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 96e7820be5..1ed2efba6b 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -249,7 +249,7 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, session_info = req->session->session_info; } - status = dcesrv_endpoint_search_connect(&req->smb_conn->dcesrv, + status = dcesrv_endpoint_search_connect(req->smb_conn->dcesrv, &ep_description, session_info, &p->dce_conn); -- cgit From 18104c5679331c763f513f4c01b67b68f7a746fd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 12:48:09 +0000 Subject: r2633: fixed some function types in the (unused) print backend (This used to be commit e9803058ecc0b0f849aee48a077bff4e2c8feaa5) --- source4/ntvfs/print/vfs_print.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 7405697bb9..0e6824a14e 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -29,7 +29,7 @@ in. For printing shares this should check that the spool directory is available */ -static NTSTATUS print_connect(struct smbsrv_request *req, const char *sharename) +static NTSTATUS print_connect(struct smbsrv_request *req, const char *sharename, int depth) { return NT_STATUS_OK; } @@ -37,7 +37,7 @@ static NTSTATUS print_connect(struct smbsrv_request *req, const char *sharename) /* disconnect from a share */ -static NTSTATUS print_disconnect(struct smbsrv_tcon *tcon) +static NTSTATUS print_disconnect(struct smbsrv_tcon *tcon, int depth) { return NT_STATUS_OK; } -- cgit From 6310f40448f9f9e856874cbefcc25b753963a41e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 25 Sep 2004 12:48:56 +0000 Subject: r2634: use discard_const_p() in a few places (This used to be commit 56ecda2178e33508c55c6195ccec41c06e099d6f) --- source4/ntvfs/ipc/vfs_ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 1ed2efba6b..ce6629739a 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -435,13 +435,13 @@ static NTSTATUS ipc_write(struct smbsrv_request *req, union smb_write *wr) switch (wr->generic.level) { case RAW_WRITE_WRITE: fnum = wr->write.in.fnum; - data.data = wr->write.in.data; + data.data = discard_const_p(void, wr->write.in.data); data.length = wr->write.in.count; break; case RAW_WRITE_WRITEX: fnum = wr->writex.in.fnum; - data.data = wr->writex.in.data; + data.data = discard_const_p(void, wr->writex.in.data); data.length = wr->writex.in.count; break; -- cgit From 3ea916b2278c202c99c80c02e80e588bd7daedb8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 06:44:08 +0000 Subject: r2654: fixed some more server memory leaks. We are now down to a single leak of 16 bytes, caused by the 16 byte data_blob in the smb_signing code. (This used to be commit 2f1b788e09686e065d22f621f5c0c585192c6740) --- source4/ntvfs/posix/vfs_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 9bd060c639..8705317b2a 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -59,7 +59,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename, DEBUG(0,("WARNING: the posix vfs handler is incomplete - you probably want \"ntvfs handler = simple\"\n")); - pvfs = talloc_named(tcon, sizeof(struct pvfs_state), "pvfs_connect(%s)", sharename); + pvfs = talloc_p(tcon, struct pvfs_state); if (pvfs == NULL) { return NT_STATUS_NO_MEMORY; } -- cgit From aeb9d1e1adb4a7d3c5745b9c5a6906cdc7a8ccb0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 07:44:15 +0000 Subject: r2656: moved the seteuid configure tests into the posix backend (these tests don't actually work yet, that will come later) (This used to be commit 46b790c19da25ba88d29f555f828688bb05e531d) --- source4/ntvfs/posix/config.m4 | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index d8a2e3ec36..3415948f95 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -21,3 +21,60 @@ ac_cv_decl_have_stat_tv_nsec=no) if test x"$ac_cv_decl_have_stat_tv_nsec" = x"yes"; then AC_DEFINE(HAVE_STAT_TV_NSEC,1,[Whether stat has tv_nsec nanosecond fields]) fi + + +################################################ +# look for a method of setting the effective uid +seteuid=no; +if test $seteuid = no; then +AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETRESUID 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) +if test x"$samba_cv_USE_SETRESUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) +fi +fi + + +if test $seteuid = no; then +AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETREUID 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) +if test x"$samba_cv_USE_SETREUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) +fi +fi + +if test $seteuid = no; then +AC_CACHE_CHECK([for seteuid],samba_cv_USE_SETEUID,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETEUID 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETEUID=yes,samba_cv_USE_SETEUID=no,samba_cv_USE_SETEUID=cross)]) +if test x"$samba_cv_USE_SETEUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETEUID,1,[Whether seteuid() is available]) +fi +fi + +if test $seteuid = no; then +AC_CACHE_CHECK([for setuidx],samba_cv_USE_SETUIDX,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETUIDX 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETUIDX=yes,samba_cv_USE_SETUIDX=no,samba_cv_USE_SETUIDX=cross)]) +if test x"$samba_cv_USE_SETUIDX" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETUIDX,1,[Whether setuidx() is available]) +fi +fi -- cgit From e3880fa759cfa03222262327854fe7bbe585fe01 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Sep 2004 11:30:20 +0000 Subject: r2660: - converted the libcli/raw/ library to use talloc_increase_ref_count() 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) --- source4/ntvfs/cifs/vfs_cifs.c | 25 ++++++++++++++-- source4/ntvfs/ipc/vfs_ipc.c | 43 +++++++++++++++++++++++++-- source4/ntvfs/nbench/vfs_nbench.c | 14 +++++++++ source4/ntvfs/ntvfs.h | 3 ++ source4/ntvfs/posix/pvfs_open.c | 53 ++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_read.c | 3 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 4 +-- source4/ntvfs/posix/vfs_posix.c | 10 +------ source4/ntvfs/posix/vfs_posix.h | 8 +++++ source4/ntvfs/simple/vfs_simple.c | 11 ++++++- 12 files changed, 156 insertions(+), 22 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2ae41a674c..3931792ee8 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -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; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index ce6629739a..33e1287d21 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -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); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index eebf6f1dde..90b5d43bd6 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -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 */ diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index c9cf6de1e0..96434f44e2 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -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); }; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a1c6dcdcfe..f3bec4085e 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -27,11 +27,16 @@ /* 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; +} + diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 649036b09a..81706bcfe8 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -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; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index cbb0317638..72ac00a32d 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -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; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index c2c58415be..2ea2fdaf8e 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -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; } diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index ac9d23b88f..02ba1b8228 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -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; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 8705317b2a..7ae7c6759a 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -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 diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index bfb1fbf7ca..96ab7f85b2 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -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; }; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 5b2fe9df56..f60646ed77 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -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' -- cgit From 5b44130afad1bb1764d986de3ef0e8e04b0e7357 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 01:36:19 +0000 Subject: r2671: we're getting too many errors caused by the talloc_realloc() API not taking a context (so when you pass a NULL pointer you end up with memory in a top level context). Fixed it by changing the API to take a context. The context is only used if the pointer you are reallocing is NULL. (This used to be commit 8dc23821c9f54b2f13049b5e608a0cafb81aa540) --- source4/ntvfs/ipc/ipc_rap.c | 7 ++++--- source4/ntvfs/ntvfs_base.c | 9 +++------ source4/ntvfs/posix/pvfs_dirlist.c | 7 +------ source4/ntvfs/simple/svfs.h | 2 +- source4/ntvfs/simple/svfs_util.c | 4 ++-- 5 files changed, 11 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 32b2fa2181..840c389d6c 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -178,9 +178,10 @@ static NTSTATUS rap_push_string(struct ndr_push *data_push, NDR_CHECK(ndr_push_uint16(data_push, heap->offset)); NDR_CHECK(ndr_push_uint16(data_push, 0)); - heap->strings = talloc_realloc(heap->strings, - sizeof(*heap->strings) * - (heap->num_strings + 1)); + heap->strings = talloc_realloc_p(heap->mem_ctx, + heap->strings, + const char *, + heap->num_strings + 1); if (heap->strings == NULL) return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 03873ce697..72f4759cd5 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -153,11 +153,8 @@ NTSTATUS ntvfs_init_connection(struct smbsrv_request *req) */ void ntvfs_set_private(struct smbsrv_tcon *tcon, int depth, void *value) { - if (!tcon->ntvfs_private_list) { - tcon->ntvfs_private_list = talloc_array_p(tcon, void *, depth+1); - } else { - tcon->ntvfs_private_list = talloc_realloc_p(tcon->ntvfs_private_list, - void *, depth+1); - } + tcon->ntvfs_private_list = talloc_realloc_p(tcon, + tcon->ntvfs_private_list, + void *, depth+1); tcon->ntvfs_private_list[depth] = value; } diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 0137424dc4..85c307a1b2 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -89,11 +89,6 @@ NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct p return NT_STATUS_NO_MEMORY; } - dir->names = talloc(dir, 0); - if (!dir->names) { - return NT_STATUS_NO_MEMORY; - } - odir = opendir(name->full_name); if (!odir) { return pvfs_map_errno(pvfs, errno); @@ -110,7 +105,7 @@ NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct p if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; - dir->names = talloc_realloc_p(dir->names, const char *, allocated); + dir->names = talloc_realloc_p(dir, dir->names, const char *, allocated); if (!dir->names) { closedir(odir); return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index 33b7cb7011..d3bafb42e3 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -17,7 +17,7 @@ struct svfs_private { struct svfs_dir { uint_t count; char *unix_dir; - struct { + struct svfs_dirfile { char *name; struct stat st; } *files; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 2e64920fc8..b6b7171487 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -61,7 +61,7 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, uint_t allocated = 0; char *low_mask; - dir = talloc(mem_ctx, sizeof(struct svfs_dir)); + dir = talloc_p(mem_ctx, struct svfs_dir); if (!dir) { return NULL; } dir->count = 0; @@ -105,7 +105,7 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; - dir->files = talloc_realloc(dir->files, allocated * sizeof(dir->files[0])); + dir->files = talloc_realloc_p(dir, dir->files, struct svfs_dirfile, allocated); if (!dir->files) { closedir(odir); return NULL; -- cgit From 3aa3428bc93e6c8741b52eaa65d43f3a5abcee2e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Sep 2004 08:39:51 +0000 Subject: r2679: fixed an uninitialised variable found with valgrind (This used to be commit 9087fab0adcf1791caeb795509ca9f14f5f47e82) --- source4/ntvfs/posix/pvfs_dirlist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 85c307a1b2..56afb4f33b 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -82,7 +82,8 @@ NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct p if (!name->has_wildcard) { return pvfs_list_no_wildcard(pvfs, name, pattern, dir); } - + + dir->names = NULL; dir->count = 0; dir->unix_path = talloc_strdup(dir, name->full_name); if (!dir->unix_path) { -- cgit From b2f1a29e4348a5bc34a87d72d526e23e421ed9d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 28 Sep 2004 05:44:59 +0000 Subject: r2710: continue with the new style of providing a parent context whenever possible to a structure creation routine. This makes for much easier global cleanup. (This used to be commit e14ee428ec357fab76a960387a9820a673786e27) --- source4/ntvfs/cifs/vfs_cifs.c | 15 ++++++++------- source4/ntvfs/ipc/vfs_ipc.c | 26 ++++++++------------------ 2 files changed, 16 insertions(+), 25 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 3931792ee8..c0160e6852 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -122,13 +122,14 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename, ntvfs_set_private(req->tcon, depth, private); - status = smbcli_tree_full_connection(&private->tree, - "vfs_cifs", - host, - 0, - remote_share, "?????", - user, domain, - pass); + status = smbcli_tree_full_connection(private, + &private->tree, + "vfs_cifs", + host, + 0, + remote_share, "?????", + user, domain, + pass); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 33e1287d21..59da6faea5 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -38,7 +38,6 @@ struct ipc_private { /* a list of open pipes */ struct pipe_state { struct pipe_state *next, *prev; - TALLOC_CTX *mem_ctx; const char *pipe_name; uint16_t fnum; struct dcesrv_connection *dce_conn; @@ -85,10 +84,9 @@ again: */ static void pipe_shutdown(struct ipc_private *private, struct pipe_state *p) { - TALLOC_CTX *mem_ctx = private->pipe_list->mem_ctx; - dcesrv_endpoint_disconnect(private->pipe_list->dce_conn); - DLIST_REMOVE(private->pipe_list, private->pipe_list); - talloc_destroy(mem_ctx); + talloc_free(p->dce_conn); + DLIST_REMOVE(private->pipe_list, p); + talloc_destroy(p); } @@ -199,33 +197,25 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, struct pipe_state **ps) { struct pipe_state *p; - TALLOC_CTX *mem_ctx; NTSTATUS status; struct dcesrv_ep_description ep_description; struct auth_session_info *session_info = NULL; NTVFS_GET_PRIVATE(ipc_private, private, req); - mem_ctx = talloc_init("ipc_open '%s'", fname); - if (!mem_ctx) { - return NT_STATUS_NO_MEMORY; - } - - p = talloc(mem_ctx, sizeof(struct pipe_state)); + p = talloc_p(private, struct pipe_state); if (!p) { - talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } - p->mem_ctx = mem_ctx; - p->pipe_name = talloc_strdup(mem_ctx, fname); + p->pipe_name = talloc_strdup(p, fname); if (!p->pipe_name) { - talloc_destroy(mem_ctx); + talloc_free(p); return NT_STATUS_NO_MEMORY; } p->fnum = find_next_fnum(private); if (p->fnum == 0) { - talloc_destroy(mem_ctx); + talloc_free(p); return NT_STATUS_TOO_MANY_OPENED_FILES; } @@ -261,7 +251,7 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, session_info, &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { - talloc_destroy(mem_ctx); + talloc_free(p); return status; } -- cgit From dcad0f6fd492506efd9a69b4e32c7bbfa5da90e5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 29 Sep 2004 13:17:09 +0000 Subject: r2751: this is a new ntvfs design which tries to solve: - the stacking of modules - finding the modules private data - hide the ntvfs details from the calling layer - I set NTVFS_INTERFACE_VERSION 0 till we are closer to release (because we need to solve some async problems with the module stacking) metze (This used to be commit 3ff03b5cb21bb79afdd3b1609be9635f6688a539) --- source4/ntvfs/cifs/vfs_cifs.c | 139 ++++---- source4/ntvfs/config.mk | 1 + source4/ntvfs/ipc/vfs_ipc.c | 131 +++++--- source4/ntvfs/nbench/vfs_nbench.c | 235 +++++++------- source4/ntvfs/ntvfs.h | 117 +++++-- source4/ntvfs/ntvfs_base.c | 54 +++- source4/ntvfs/ntvfs_generic.c | 18 +- source4/ntvfs/ntvfs_interface.c | 566 +++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_fsinfo.c | 7 +- source4/ntvfs/posix/pvfs_mkdir.c | 10 +- source4/ntvfs/posix/pvfs_open.c | 29 +- source4/ntvfs/posix/pvfs_qfileinfo.c | 16 +- source4/ntvfs/posix/pvfs_read.c | 7 +- source4/ntvfs/posix/pvfs_rename.c | 5 +- source4/ntvfs/posix/pvfs_search.c | 29 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 7 +- source4/ntvfs/posix/pvfs_unlink.c | 5 +- source4/ntvfs/posix/pvfs_write.c | 9 +- source4/ntvfs/posix/vfs_posix.c | 38 ++- source4/ntvfs/posix/vfs_posix.h | 2 - source4/ntvfs/print/vfs_print.c | 12 +- source4/ntvfs/simple/svfs.h | 2 - source4/ntvfs/simple/svfs_util.c | 12 +- source4/ntvfs/simple/vfs_simple.c | 142 +++++---- 24 files changed, 1178 insertions(+), 415 deletions(-) create mode 100644 source4/ntvfs/ntvfs_interface.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c0160e6852..65a7c7a206 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,7 +32,7 @@ struct cvfs_private { struct smbcli_tree *tree; struct smbcli_transport *transport; struct smbsrv_tcon *tcon; - const struct ntvfs_ops *ops; + /*const struct ntvfs_ops *ops;*/ }; @@ -89,7 +89,8 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, /* connect to a share - used when a tree_connect operation comes in. */ -static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename, int depth) +static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; NTSTATUS status; @@ -120,7 +121,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename, } ZERO_STRUCTP(private); - ntvfs_set_private(req->tcon, depth, private); + ntvfs->private_data = private; status = smbcli_tree_full_connection(private, &private->tree, @@ -137,7 +138,7 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename, private->transport = private->tree->session->transport; private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); private->tcon = req->tcon; - private->ops = ntvfs_backend_byname("cifs", NTVFS_DISK); + /*private->ops = ntvfs_backend_byname("cifs", NTVFS_DISK);*/ tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); @@ -158,9 +159,10 @@ static NTSTATUS cvfs_connect(struct smbsrv_request *req, const char *sharename, /* disconnect from a share */ -static NTSTATUS cvfs_disconnect(struct smbsrv_tcon *tcon, int depth) +static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) { - struct cvfs_private *private = tcon->ntvfs_private_list[depth]; + struct cvfs_private *private = ntvfs->private_data; smb_tree_disconnect(private->tree); talloc_free(private->tree); @@ -204,9 +206,10 @@ static void async_simple(struct smbcli_request *c_req) delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS cvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; /* see if the front end will allow us to perform this @@ -234,9 +237,10 @@ static void async_ioctl(struct smbcli_request *c_req) /* ioctl interface */ -static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; /* see if the front end will allow us to perform this @@ -253,9 +257,10 @@ static NTSTATUS cvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS cvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -281,9 +286,10 @@ static void async_qpathinfo(struct smbcli_request *c_req) /* return info on a pathname */ -static NTSTATUS cvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -309,9 +315,10 @@ static void async_qfileinfo(struct smbcli_request *c_req) /* query info on a open file */ -static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -327,9 +334,10 @@ static NTSTATUS cvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i /* set info on a pathname */ -static NTSTATUS cvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -356,9 +364,10 @@ static void async_open(struct smbcli_request *c_req) /* open a file */ -static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) +static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -373,9 +382,10 @@ static NTSTATUS cvfs_open(struct smbsrv_request *req, union smb_open *io) /* create a directory */ -static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -390,9 +400,10 @@ static NTSTATUS cvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -406,9 +417,10 @@ static NTSTATUS cvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS cvfs_rename(struct smbsrv_request *req, union smb_rename *ren) +static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -423,7 +435,8 @@ static NTSTATUS cvfs_rename(struct smbsrv_request *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS cvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) +static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -442,9 +455,10 @@ static void async_read(struct smbcli_request *c_req) /* read from a file */ -static NTSTATUS cvfs_read(struct smbsrv_request *req, union smb_read *rd) +static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *rd) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -470,9 +484,10 @@ static void async_write(struct smbcli_request *c_req) /* write to a file */ -static NTSTATUS cvfs_write(struct smbsrv_request *req, union smb_write *wr) +static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *wr) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -487,7 +502,8 @@ static NTSTATUS cvfs_write(struct smbsrv_request *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS cvfs_seek(struct smbsrv_request *req, struct smb_seek *io) +static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) { return NT_STATUS_NOT_SUPPORTED; } @@ -495,7 +511,8 @@ static NTSTATUS cvfs_seek(struct smbsrv_request *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS cvfs_flush(struct smbsrv_request *req, struct smb_flush *io) +static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *io) { return NT_STATUS_OK; } @@ -503,9 +520,10 @@ static NTSTATUS cvfs_flush(struct smbsrv_request *req, struct smb_flush *io) /* close a file */ -static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io) +static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -520,9 +538,10 @@ static NTSTATUS cvfs_close(struct smbsrv_request *req, union smb_close *io) /* exit - closing files open by the pid */ -static NTSTATUS cvfs_exit(struct smbsrv_request *req) +static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -537,7 +556,8 @@ static NTSTATUS cvfs_exit(struct smbsrv_request *req) /* logoff - closing files open by the user */ -static NTSTATUS cvfs_logoff(struct smbsrv_request *req) +static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { /* we can't do this right in the cifs backend .... */ return NT_STATUS_OK; @@ -546,9 +566,10 @@ static NTSTATUS cvfs_logoff(struct smbsrv_request *req) /* lock a byte range */ -static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck) +static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -562,10 +583,11 @@ static NTSTATUS cvfs_lock(struct smbsrv_request *req, union smb_lock *lck) /* set info on a open file */ -static NTSTATUS cvfs_setfileinfo(struct smbsrv_request *req, +static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -591,9 +613,10 @@ static void async_fsinfo(struct smbcli_request *c_req) /* return filesystem space info */ -static NTSTATUS cvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -608,7 +631,8 @@ static NTSTATUS cvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) /* return print queue info */ -static NTSTATUS cvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -616,29 +640,32 @@ static NTSTATUS cvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -static NTSTATUS cvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, +static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; return smb_raw_search_first(private->tree, req, io, search_private, callback); } /* continue a search */ -static NTSTATUS cvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, +static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; return smb_raw_search_next(private->tree, req, io, search_private, callback); } /* close a search */ -static NTSTATUS cvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; return smb_raw_search_close(private->tree, io); } @@ -655,9 +682,10 @@ static void async_trans2(struct smbcli_request *c_req) } /* raw trans2 */ -static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) +static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) { - NTVFS_GET_PRIVATE(cvfs_private, private, req); + struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; if (!req->async.send_fn) { @@ -671,7 +699,8 @@ static NTSTATUS cvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans /* SMBtrans - not used on file shares */ -static NTSTATUS cvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) +static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } @@ -721,7 +750,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.logoff = cvfs_logoff; if (lp_parm_bool(-1, "cifs", "maptrans2", False)) { - ops.trans2 = cvfs_trans2; + ops.trans2 = cvfs_trans2; } /* register ourselves with the NTVFS subsystem. We register diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index d00cc2b1f4..e2320e0684 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -55,6 +55,7 @@ INIT_OBJ_FILES = \ ntvfs/ntvfs_base.o ADD_OBJ_FILES = \ ntvfs/ntvfs_generic.o \ + ntvfs/ntvfs_interface.o \ ntvfs/ntvfs_util.o # # End SUBSYSTEM NTVFS diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 59da6faea5..69fed6f86f 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -110,7 +110,8 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t /* connect to a share - always works */ -static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename, int depth) +static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; @@ -123,7 +124,7 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename, i if (!private) { return NT_STATUS_NO_MEMORY; } - ntvfs_set_private(tcon, depth, private); + ntvfs->private_data = private; private->pipe_list = NULL; private->next_fnum = 1; @@ -135,9 +136,10 @@ static NTSTATUS ipc_connect(struct smbsrv_request *req, const char *sharename, i /* disconnect from a share */ -static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon, int depth) +static NTSTATUS ipc_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) { - struct ipc_private *private = tcon->ntvfs_private_list[depth]; + struct ipc_private *private = ntvfs->private_data; /* close any pipes that are open. Discard any unread data */ while (private->pipe_list) { @@ -150,7 +152,8 @@ static NTSTATUS ipc_disconnect(struct smbsrv_tcon *tcon, int depth) /* delete a file */ -static NTSTATUS ipc_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +static NTSTATUS ipc_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } @@ -159,7 +162,8 @@ static NTSTATUS ipc_unlink(struct smbsrv_request *req, struct smb_unlink *unl) /* ioctl interface - we don't do any */ -static NTSTATUS ipc_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) { return NT_STATUS_ACCESS_DENIED; } @@ -167,7 +171,8 @@ static NTSTATUS ipc_ioctl(struct smbsrv_request *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS ipc_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +static NTSTATUS ipc_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) { return NT_STATUS_ACCESS_DENIED; } @@ -175,7 +180,8 @@ static NTSTATUS ipc_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) /* return info on a pathname */ -static NTSTATUS ipc_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS ipc_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -183,7 +189,8 @@ static NTSTATUS ipc_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *in /* set info on a pathname */ -static NTSTATUS ipc_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) { return NT_STATUS_ACCESS_DENIED; } @@ -193,14 +200,15 @@ static NTSTATUS ipc_setpathinfo(struct smbsrv_request *req, union smb_setfileinf /* open a file backend - used for MSRPC pipes */ -static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, +static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *fname, struct pipe_state **ps) { struct pipe_state *p; NTSTATUS status; struct dcesrv_ep_description ep_description; struct auth_session_info *session_info = NULL; - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; p = talloc_p(private, struct pipe_state); if (!p) { @@ -270,12 +278,13 @@ static NTSTATUS ipc_open_generic(struct smbsrv_request *req, const char *fname, /* open a file with ntcreatex - used for MSRPC pipes */ -static NTSTATUS ipc_open_ntcreatex(struct smbsrv_request *req, union smb_open *oi) +static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *oi) { struct pipe_state *p; NTSTATUS status; - status = ipc_open_generic(req, oi->ntcreatex.in.fname, &p); + status = ipc_open_generic(ntvfs, req, oi->ntcreatex.in.fname, &p); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -290,7 +299,8 @@ static NTSTATUS ipc_open_ntcreatex(struct smbsrv_request *req, union smb_open *o /* open a file with openx - used for MSRPC pipes */ -static NTSTATUS ipc_open_openx(struct smbsrv_request *req, union smb_open *oi) +static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *oi) { struct pipe_state *p; NTSTATUS status; @@ -302,7 +312,7 @@ static NTSTATUS ipc_open_openx(struct smbsrv_request *req, union smb_open *oi) fname += 4; - status = ipc_open_generic(req, fname, &p); + status = ipc_open_generic(ntvfs, req, fname, &p); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -318,16 +328,17 @@ static NTSTATUS ipc_open_openx(struct smbsrv_request *req, union smb_open *oi) /* open a file - used for MSRPC pipes */ -static NTSTATUS ipc_open(struct smbsrv_request *req, union smb_open *oi) +static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *oi) { NTSTATUS status; switch (oi->generic.level) { case RAW_OPEN_NTCREATEX: - status = ipc_open_ntcreatex(req, oi); + status = ipc_open_ntcreatex(ntvfs, req, oi); break; case RAW_OPEN_OPENX: - status = ipc_open_openx(req, oi); + status = ipc_open_openx(ntvfs, req, oi); break; default: status = NT_STATUS_NOT_SUPPORTED; @@ -340,7 +351,8 @@ static NTSTATUS ipc_open(struct smbsrv_request *req, union smb_open *oi) /* create a directory */ -static NTSTATUS ipc_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +static NTSTATUS ipc_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) { return NT_STATUS_ACCESS_DENIED; } @@ -348,7 +360,8 @@ static NTSTATUS ipc_mkdir(struct smbsrv_request *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS ipc_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +static NTSTATUS ipc_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) { return NT_STATUS_ACCESS_DENIED; } @@ -356,7 +369,8 @@ static NTSTATUS ipc_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS ipc_rename(struct smbsrv_request *req, union smb_rename *ren) +static NTSTATUS ipc_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) { return NT_STATUS_ACCESS_DENIED; } @@ -364,7 +378,8 @@ static NTSTATUS ipc_rename(struct smbsrv_request *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS ipc_copy(struct smbsrv_request *req, struct smb_copy *cp) +static NTSTATUS ipc_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) { return NT_STATUS_ACCESS_DENIED; } @@ -372,9 +387,10 @@ static NTSTATUS ipc_copy(struct smbsrv_request *req, struct smb_copy *cp) /* read from a file */ -static NTSTATUS ipc_read(struct smbsrv_request *req, union smb_read *rd) +static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *rd) { - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; DATA_BLOB data; uint16_t fnum; struct pipe_state *p; @@ -424,9 +440,10 @@ static NTSTATUS ipc_read(struct smbsrv_request *req, union smb_read *rd) /* write to a file */ -static NTSTATUS ipc_write(struct smbsrv_request *req, union smb_write *wr) +static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *wr) { - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; DATA_BLOB data; uint16_t fnum; struct pipe_state *p; @@ -477,7 +494,8 @@ static NTSTATUS ipc_write(struct smbsrv_request *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS ipc_seek(struct smbsrv_request *req, struct smb_seek *io) +static NTSTATUS ipc_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) { return NT_STATUS_ACCESS_DENIED; } @@ -485,7 +503,8 @@ static NTSTATUS ipc_seek(struct smbsrv_request *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS ipc_flush(struct smbsrv_request *req, struct smb_flush *io) +static NTSTATUS ipc_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *io) { return NT_STATUS_ACCESS_DENIED; } @@ -493,9 +512,10 @@ static NTSTATUS ipc_flush(struct smbsrv_request *req, struct smb_flush *io) /* close a file */ -static NTSTATUS ipc_close(struct smbsrv_request *req, union smb_close *io) +static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) { - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; struct pipe_state *p; if (io->generic.level != RAW_CLOSE_CLOSE) { @@ -516,9 +536,10 @@ static NTSTATUS ipc_close(struct smbsrv_request *req, union smb_close *io) /* exit - closing files */ -static NTSTATUS ipc_exit(struct smbsrv_request *req) +static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; struct pipe_state *p, *next; for (p=private->pipe_list; p; p=next) { @@ -534,9 +555,10 @@ static NTSTATUS ipc_exit(struct smbsrv_request *req) /* logoff - closing files open by the user */ -static NTSTATUS ipc_logoff(struct smbsrv_request *req) +static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; struct pipe_state *p, *next; for (p=private->pipe_list; p; p=next) { @@ -552,7 +574,8 @@ static NTSTATUS ipc_logoff(struct smbsrv_request *req) /* lock a byte range */ -static NTSTATUS ipc_lock(struct smbsrv_request *req, union smb_lock *lck) +static NTSTATUS ipc_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) { return NT_STATUS_ACCESS_DENIED; } @@ -560,7 +583,8 @@ static NTSTATUS ipc_lock(struct smbsrv_request *req, union smb_lock *lck) /* set info on a open file */ -static NTSTATUS ipc_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) +static NTSTATUS ipc_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -568,7 +592,8 @@ static NTSTATUS ipc_setfileinfo(struct smbsrv_request *req, union smb_setfileinf /* query info on a open file */ -static NTSTATUS ipc_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS ipc_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -577,7 +602,8 @@ static NTSTATUS ipc_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *in /* return filesystem info */ -static NTSTATUS ipc_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +static NTSTATUS ipc_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) { return NT_STATUS_ACCESS_DENIED; } @@ -585,7 +611,8 @@ static NTSTATUS ipc_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) /* return print queue info */ -static NTSTATUS ipc_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +static NTSTATUS ipc_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_ACCESS_DENIED; } @@ -593,7 +620,8 @@ static NTSTATUS ipc_lpq(struct smbsrv_request *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -NTSTATUS ipc_search_first(struct smbsrv_request *req, union smb_search_first *io, +static NTSTATUS ipc_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -603,7 +631,8 @@ NTSTATUS ipc_search_first(struct smbsrv_request *req, union smb_search_first *io /* continue listing files in a directory */ -NTSTATUS ipc_search_next(struct smbsrv_request *req, union smb_search_next *io, +static NTSTATUS ipc_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -613,17 +642,19 @@ NTSTATUS ipc_search_next(struct smbsrv_request *req, union smb_search_next *io, /* end listing files in a directory */ -NTSTATUS ipc_search_close(struct smbsrv_request *req, union smb_search_close *io) +static NTSTATUS ipc_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) { return NT_STATUS_ACCESS_DENIED; } /* SMBtrans - handle a DCERPC command */ -static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *trans) +static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans) { struct pipe_state *p; - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; NTSTATUS status; /* the fnum is in setup[1] */ @@ -665,9 +696,10 @@ static NTSTATUS ipc_dcerpc_cmd(struct smbsrv_request *req, struct smb_trans2 *tr /* SMBtrans - set named pipe state */ -static NTSTATUS ipc_set_nm_pipe_state(struct smbsrv_request *req, struct smb_trans2 *trans) +static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans) { - NTVFS_GET_PRIVATE(ipc_private, private, req); + struct ipc_private *private = ntvfs->private_data; struct pipe_state *p; /* the fnum is in setup[1] */ @@ -691,7 +723,8 @@ static NTSTATUS ipc_set_nm_pipe_state(struct smbsrv_request *req, struct smb_tra /* SMBtrans - used to provide access to SMB pipes */ -static NTSTATUS ipc_trans(struct smbsrv_request *req, struct smb_trans2 *trans) +static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans) { NTSTATUS status; @@ -704,10 +737,10 @@ static NTSTATUS ipc_trans(struct smbsrv_request *req, struct smb_trans2 *trans) switch (trans->in.setup[0]) { case TRANSACT_SETNAMEDPIPEHANDLESTATE: - status = ipc_set_nm_pipe_state(req, trans); + status = ipc_set_nm_pipe_state(ntvfs, req, trans); break; case TRANSACT_DCERPCCMD: - status = ipc_dcerpc_cmd(req, trans); + status = ipc_dcerpc_cmd(ntvfs, req, trans); break; default: status = NT_STATUS_INVALID_PARAMETER; diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 90b5d43bd6..06c237afb5 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -28,11 +28,9 @@ /* this is stored in ntvfs_private */ struct nbench_private { - const struct ntvfs_ops *passthru_ops; int log_fd; }; - /* log one request to the nbench log */ @@ -53,12 +51,6 @@ static void nbench_log(struct nbench_private *private, free(s); } - -/* - this is used to call the next module in the ntvfs chain -*/ -#define PASS_THRU(tcon, op, args) private->passthru_ops->op args; - /* this pass through macro operates on request contexts, and disables async calls. @@ -66,12 +58,10 @@ static void nbench_log(struct nbench_private *private, async calls are a pain for the nbench module as it makes pulling the status code and any result parameters much harder. */ -#define PASS_THRU_REQ(req, op, args) do { \ +#define PASS_THRU_REQ(ntvfs, req, op, args) do { \ void *send_fn_saved = req->async.send_fn; \ req->async.send_fn = NULL; \ - req->ntvfs_depth++; \ - status = PASS_THRU(req->tcon, op, args); \ - req->ntvfs_depth--; \ + status = ntvfs_next_##op args; \ req->async.send_fn = send_fn_saved; \ } while (0) @@ -79,21 +69,20 @@ static void nbench_log(struct nbench_private *private, /* connect to a share - used when a tree_connect operation comes in. */ -static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename, int depth) +static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) { struct nbench_private *private; - const char *passthru; NTSTATUS status; char *logname = NULL; - const char **handlers = lp_ntvfs_handler(req->tcon->service); private = talloc_p(req->tcon, struct nbench_private); if (!private) { return NT_STATUS_NO_MEMORY; } - asprintf(&logname, "/tmp/nbenchlog%d.%u", depth, getpid()); - private->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); + asprintf(&logname, "/tmp/nbenchlog%d.%u", ntvfs->depth, getpid()); + private->log_fd = sys_open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); free(logname); if (private->log_fd == -1) { @@ -101,16 +90,9 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename return NT_STATUS_UNSUCCESSFUL; } - private->passthru_ops = ntvfs_backend_byname(handlers[depth+1], NTVFS_DISK); + ntvfs->private_data = private; - if (!private->passthru_ops) { - DEBUG(0,("Unable to connect to '%s' pass through backend\n", passthru)); - return NT_STATUS_UNSUCCESSFUL; - } - - ntvfs_set_private(req->tcon, depth, private); - - status = PASS_THRU(req->tcon, connect, (req, sharename, depth+1)); + status = ntvfs_next_connect(ntvfs, req, sharename); return status; } @@ -118,15 +100,16 @@ static NTSTATUS nbench_connect(struct smbsrv_request *req, const char *sharename /* disconnect from a share */ -static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon, int depth) +static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) { - struct nbench_private *private = tcon->ntvfs_private_list[depth]; + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; close(private->log_fd); - status = PASS_THRU(tcon, disconnect, (tcon, depth+1)); - + status = ntvfs_next_disconnect(ntvfs, tcon); + return status; } @@ -134,12 +117,13 @@ static NTSTATUS nbench_disconnect(struct smbsrv_tcon *tcon, int depth) delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS nbench_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, unlink, (req, unl)); + PASS_THRU_REQ(ntvfs, req, unlink, (ntvfs, req, unl)); nbench_log(private, "Unlink \"%s\" 0x%x %s\n", unl->in.pattern, unl->in.attrib, @@ -151,12 +135,13 @@ static NTSTATUS nbench_unlink(struct smbsrv_request *req, struct smb_unlink *unl /* ioctl interface */ -static NTSTATUS nbench_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, ioctl, (req, io)); + PASS_THRU_REQ(ntvfs, req, ioctl, (ntvfs, req, io)); nbench_log(private, "Ioctl - NOT HANDLED\n"); @@ -166,12 +151,13 @@ static NTSTATUS nbench_ioctl(struct smbsrv_request *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS nbench_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, chkpath, (req, cp)); + PASS_THRU_REQ(ntvfs, req, chkpath, (ntvfs, req, cp)); nbench_log(private, "Chkpath \"%s\" %s\n", cp->in.path, @@ -183,12 +169,13 @@ static NTSTATUS nbench_chkpath(struct smbsrv_request *req, struct smb_chkpath *c /* return info on a pathname */ -static NTSTATUS nbench_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, qpathinfo, (req, info)); + PASS_THRU_REQ(ntvfs, req, qpathinfo, (ntvfs, req, info)); nbench_log(private, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", info->generic.in.fname, @@ -201,12 +188,13 @@ static NTSTATUS nbench_qpathinfo(struct smbsrv_request *req, union smb_fileinfo /* query info on a open file */ -static NTSTATUS nbench_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, qfileinfo, (req, info)); + PASS_THRU_REQ(ntvfs, req, qfileinfo, (ntvfs, req, info)); nbench_log(private, "QUERY_FILE_INFORMATION %d %d %s\n", info->generic.in.fnum, @@ -220,12 +208,13 @@ static NTSTATUS nbench_qfileinfo(struct smbsrv_request *req, union smb_fileinfo /* set info on a pathname */ -static NTSTATUS nbench_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, setpathinfo, (req, st)); + PASS_THRU_REQ(ntvfs, req, setpathinfo, (ntvfs, req, st)); nbench_log(private, "SET_PATH_INFORMATION \"%s\" %d %s\n", st->generic.file.fname, @@ -238,12 +227,15 @@ static NTSTATUS nbench_setpathinfo(struct smbsrv_request *req, union smb_setfile /* open a file */ -static NTSTATUS nbench_open(struct smbsrv_request *req, union smb_open *io) +static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, open, (req, io)); + PASS_THRU_REQ(ntvfs, req, open, (ntvfs, req, io)); + + DEBUG(0,("%d: %s\n", ntvfs->depth, get_nt_error_c_code(status))); switch (io->generic.level) { case RAW_OPEN_NTCREATEX: @@ -267,12 +259,13 @@ static NTSTATUS nbench_open(struct smbsrv_request *req, union smb_open *io) /* create a directory */ -static NTSTATUS nbench_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, mkdir, (req, md)); + PASS_THRU_REQ(ntvfs, req, mkdir, (ntvfs, req, md)); nbench_log(private, "Mkdir - NOT HANDLED\n"); @@ -282,12 +275,13 @@ static NTSTATUS nbench_mkdir(struct smbsrv_request *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS nbench_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, rmdir, (req, rd)); + PASS_THRU_REQ(ntvfs, req, rmdir, (ntvfs, req, rd)); nbench_log(private, "Rmdir \"%s\" %s\n", rd->in.path, @@ -299,12 +293,13 @@ static NTSTATUS nbench_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS nbench_rename(struct smbsrv_request *req, union smb_rename *ren) +static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, rename, (req, ren)); + PASS_THRU_REQ(ntvfs, req, rename, (ntvfs, req, ren)); switch (ren->generic.level) { case RAW_RENAME_RENAME: @@ -326,12 +321,13 @@ static NTSTATUS nbench_rename(struct smbsrv_request *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS nbench_copy(struct smbsrv_request *req, struct smb_copy *cp) +static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, copy, (req, cp)); + PASS_THRU_REQ(ntvfs, req, copy, (ntvfs, req, cp)); nbench_log(private, "Copy - NOT HANDLED\n"); @@ -341,12 +337,13 @@ static NTSTATUS nbench_copy(struct smbsrv_request *req, struct smb_copy *cp) /* read from a file */ -static NTSTATUS nbench_read(struct smbsrv_request *req, union smb_read *rd) +static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *rd) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, read, (req, rd)); + PASS_THRU_REQ(ntvfs, req, read, (ntvfs, req, rd)); switch (rd->generic.level) { case RAW_READ_READX: @@ -369,12 +366,13 @@ static NTSTATUS nbench_read(struct smbsrv_request *req, union smb_read *rd) /* write to a file */ -static NTSTATUS nbench_write(struct smbsrv_request *req, union smb_write *wr) +static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *wr) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, write, (req, wr)); + PASS_THRU_REQ(ntvfs, req, write, (ntvfs, req, wr)); switch (wr->generic.level) { case RAW_WRITE_WRITEX: @@ -407,12 +405,13 @@ static NTSTATUS nbench_write(struct smbsrv_request *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS nbench_seek(struct smbsrv_request *req, struct smb_seek *io) +static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, seek, (req, io)); + PASS_THRU_REQ(ntvfs, req, seek, (ntvfs, req, io)); nbench_log(private, "Seek - NOT HANDLED\n"); @@ -422,12 +421,13 @@ static NTSTATUS nbench_seek(struct smbsrv_request *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS nbench_flush(struct smbsrv_request *req, struct smb_flush *io) +static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *io) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, flush, (req, io)); + PASS_THRU_REQ(ntvfs, req, flush, (ntvfs, req, io)); nbench_log(private, "Flush %d %s\n", io->in.fnum, @@ -439,12 +439,13 @@ static NTSTATUS nbench_flush(struct smbsrv_request *req, struct smb_flush *io) /* close a file */ -static NTSTATUS nbench_close(struct smbsrv_request *req, union smb_close *io) +static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, close, (req, io)); + PASS_THRU_REQ(ntvfs, req, close, (ntvfs, req, io)); switch (io->generic.level) { case RAW_CLOSE_CLOSE: @@ -465,12 +466,12 @@ static NTSTATUS nbench_close(struct smbsrv_request *req, union smb_close *io) /* exit - closing files */ -static NTSTATUS nbench_exit(struct smbsrv_request *req) +static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { - NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; - PASS_THRU_REQ(req, exit, (req)); + PASS_THRU_REQ(ntvfs, req, exit, (ntvfs, req)); return status; } @@ -478,12 +479,12 @@ static NTSTATUS nbench_exit(struct smbsrv_request *req) /* logoff - closing files */ -static NTSTATUS nbench_logoff(struct smbsrv_request *req) +static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { - NTVFS_GET_PRIVATE(nbench_private, private, req); NTSTATUS status; - PASS_THRU_REQ(req, logoff, (req)); + PASS_THRU_REQ(ntvfs, req, logoff, (ntvfs, req)); return status; } @@ -491,12 +492,13 @@ static NTSTATUS nbench_logoff(struct smbsrv_request *req) /* lock a byte range */ -static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck) +static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, lock, (req, lck)); + PASS_THRU_REQ(ntvfs, req, lock, (ntvfs, req, lck)); if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.lock_cnt == 1 && @@ -523,13 +525,14 @@ static NTSTATUS nbench_lock(struct smbsrv_request *req, union smb_lock *lck) /* set info on a open file */ -static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req, - union smb_setfileinfo *info) +static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + union smb_setfileinfo *info) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, setfileinfo, (req, info)); + PASS_THRU_REQ(ntvfs, req, setfileinfo, (ntvfs, req, info)); nbench_log(private, "SET_FILE_INFORMATION %d %d %s\n", info->generic.file.fnum, @@ -543,12 +546,13 @@ static NTSTATUS nbench_setfileinfo(struct smbsrv_request *req, /* return filesystem space info */ -static NTSTATUS nbench_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, fsinfo, (req, fs)); + PASS_THRU_REQ(ntvfs, req, fsinfo, (ntvfs, req, fs)); nbench_log(private, "QUERY_FS_INFORMATION %d %s\n", fs->generic.level, @@ -560,12 +564,13 @@ static NTSTATUS nbench_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) /* return print queue info */ -static NTSTATUS nbench_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, lpq, (req, lpq)); + PASS_THRU_REQ(ntvfs, req, lpq, (ntvfs, req, lpq)); nbench_log(private, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); @@ -575,14 +580,15 @@ static NTSTATUS nbench_lpq(struct smbsrv_request *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -static NTSTATUS nbench_search_first(struct smbsrv_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) +static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, search_first, (req, io, search_private, callback)); + PASS_THRU_REQ(ntvfs, req, search_first, (ntvfs, req, io, search_private, callback)); switch (io->generic.level) { case RAW_SEARCH_BOTH_DIRECTORY_INFO: @@ -603,14 +609,15 @@ static NTSTATUS nbench_search_first(struct smbsrv_request *req, union smb_search } /* continue a search */ -static NTSTATUS nbench_search_next(struct smbsrv_request *req, union smb_search_next *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) +static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, search_next, (req, io, search_private, callback)); + PASS_THRU_REQ(ntvfs, req, search_next, (ntvfs, req, io, search_private, callback)); nbench_log(private, "Searchnext-%d - NOT HANDLED\n", io->generic.level); @@ -618,12 +625,13 @@ static NTSTATUS nbench_search_next(struct smbsrv_request *req, union smb_search_ } /* close a search */ -static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search_close *io) +static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, search_close, (req, io)); + PASS_THRU_REQ(ntvfs, req, search_close, (ntvfs, req, io)); nbench_log(private, "Searchclose-%d - NOT HANDLED\n", io->generic.level); @@ -631,12 +639,13 @@ static NTSTATUS nbench_search_close(struct smbsrv_request *req, union smb_search } /* SMBtrans - not used on file shares */ -static NTSTATUS nbench_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) +static NTSTATUS nbench_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) { - NTVFS_GET_PRIVATE(nbench_private, private, req); + struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(req, trans, (req,trans2)); + PASS_THRU_REQ(ntvfs, req, trans, (ntvfs, req, trans2)); nbench_log(private, "Trans - NOT HANDLED\n"); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 96434f44e2..bee10e3c38 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. NTVFS structures and defines Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan Metzmacher 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,9 +20,15 @@ */ /* modules can use the following to determine if the interface has changed */ -#define NTVFS_INTERFACE_VERSION 1 +/* version 1 -> 0 - make module stacking easier -- metze */ +#define NTVFS_INTERFACE_VERSION 0 +struct ntvfs_module_context; +/* each backend has to be one one of the following 3 basic types. In + * earlier versions of Samba backends needed to handle all types, now + * we implement them separately. */ +enum ntvfs_type {NTVFS_DISK, NTVFS_PRINT, NTVFS_IPC}; /* the ntvfs operations structure - contains function pointers to the backend implementations of each operation */ @@ -30,65 +37,105 @@ struct ntvfs_ops { enum ntvfs_type type; /* initial setup */ - NTSTATUS (*connect)(struct smbsrv_request *req, const char *sharename, int depth); - NTSTATUS (*disconnect)(struct smbsrv_tcon *tcon, int depth); + NTSTATUS (*connect)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename); + NTSTATUS (*disconnect)(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon); /* path operations */ - NTSTATUS (*unlink)(struct smbsrv_request *req, struct smb_unlink *unl); - NTSTATUS (*chkpath)(struct smbsrv_request *req, struct smb_chkpath *cp); - NTSTATUS (*qpathinfo)(struct smbsrv_request *req, union smb_fileinfo *st); - NTSTATUS (*setpathinfo)(struct smbsrv_request *req, union smb_setfileinfo *st); - NTSTATUS (*open)(struct smbsrv_request *req, union smb_open *oi); - NTSTATUS (*mkdir)(struct smbsrv_request *req, union smb_mkdir *md); - NTSTATUS (*rmdir)(struct smbsrv_request *req, struct smb_rmdir *rd); - NTSTATUS (*rename)(struct smbsrv_request *req, union smb_rename *ren); - NTSTATUS (*copy)(struct smbsrv_request *req, struct smb_copy *cp); + NTSTATUS (*unlink)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl); + NTSTATUS (*chkpath)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp); + NTSTATUS (*qpathinfo)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *st); + NTSTATUS (*setpathinfo)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st); + NTSTATUS (*open)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *oi); + NTSTATUS (*mkdir)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md); + NTSTATUS (*rmdir)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd); + NTSTATUS (*rename)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren); + NTSTATUS (*copy)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp); /* directory search */ - NTSTATUS (*search_first)(struct smbsrv_request *req, union smb_search_first *io, void *private, + NTSTATUS (*search_first)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)); - NTSTATUS (*search_next)(struct smbsrv_request *req, union smb_search_next *io, void *private, + NTSTATUS (*search_next)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)); - NTSTATUS (*search_close)(struct smbsrv_request *req, union smb_search_close *io); + NTSTATUS (*search_close)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io); /* operations on open files */ - NTSTATUS (*ioctl)(struct smbsrv_request *req, union smb_ioctl *io); - NTSTATUS (*read)(struct smbsrv_request *req, union smb_read *io); - NTSTATUS (*write)(struct smbsrv_request *req, union smb_write *io); - NTSTATUS (*seek)(struct smbsrv_request *req, struct smb_seek *io); - NTSTATUS (*flush)(struct smbsrv_request *req, struct smb_flush *flush); - NTSTATUS (*close)(struct smbsrv_request *req, union smb_close *io); - NTSTATUS (*exit)(struct smbsrv_request *req); - NTSTATUS (*lock)(struct smbsrv_request *req, union smb_lock *lck); - NTSTATUS (*setfileinfo)(struct smbsrv_request *req, union smb_setfileinfo *info); - NTSTATUS (*qfileinfo)(struct smbsrv_request *req, union smb_fileinfo *info); + NTSTATUS (*ioctl)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io); + NTSTATUS (*read)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *io); + NTSTATUS (*write)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *io); + NTSTATUS (*seek)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io); + NTSTATUS (*flush)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *flush); + NTSTATUS (*close)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io); + NTSTATUS (*exit)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req); + NTSTATUS (*lock)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck); + NTSTATUS (*setfileinfo)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info); + NTSTATUS (*qfileinfo)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info); /* filesystem operations */ - NTSTATUS (*fsinfo)(struct smbsrv_request *req, union smb_fsinfo *fs); + NTSTATUS (*fsinfo)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs); /* printing specific operations */ - NTSTATUS (*lpq)(struct smbsrv_request *req, union smb_lpq *lpq); + NTSTATUS (*lpq)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq); /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ - NTSTATUS (*trans2)(struct smbsrv_request *req, struct smb_trans2 *trans2); + NTSTATUS (*trans2)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2); /* trans interface - used by IPC backend for pipes and RAP calls */ - NTSTATUS (*trans)(struct smbsrv_request *req, struct smb_trans2 *trans); + NTSTATUS (*trans)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans); /* logoff - called when a vuid is closed */ - NTSTATUS (*logoff)(struct smbsrv_request *req); + NTSTATUS (*logoff)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req); }; +struct ntvfs_module_context { + struct ntvfs_module_context *prev, *next; + void *private_data; + const struct ntvfs_ops *ops; + int depth; +}; + +struct ntvfs_context { + enum ntvfs_type type; + /* + * linked list of module contexts + */ + struct ntvfs_module_context *modules; +}; /* this structure is used by backends to determine the size of some critical types */ struct ntvfs_critical_sizes { int interface_version; + int sizeof_ntvfs_context; + int sizeof_ntvfs_module_context; int sizeof_ntvfs_ops; - int sizeof_SMB_OFF_T; int sizeof_smbsrv_tcon; int sizeof_smbsrv_request; }; - -/* useful macro for backends */ -#define NTVFS_GET_PRIVATE(struct_name, name, req) \ - struct struct_name *name = req->tcon->ntvfs_private_list[req->ntvfs_depth] diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 72f4759cd5..acbd02d915 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -100,8 +100,9 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { static const struct ntvfs_critical_sizes critical_sizes = { NTVFS_INTERFACE_VERSION, + sizeof(struct ntvfs_context), + sizeof(struct ntvfs_module_context), sizeof(struct ntvfs_ops), - sizeof(SMB_OFF_T), sizeof(struct smbsrv_tcon), sizeof(struct smbsrv_request), }; @@ -133,28 +134,47 @@ BOOL ntvfs_init(void) /* initialise a connection structure to point at a NTVFS backend */ -NTSTATUS ntvfs_init_connection(struct smbsrv_request *req) +NTSTATUS ntvfs_init_connection(struct smbsrv_request *req, enum ntvfs_type type) { const char **handlers = lp_ntvfs_handler(req->tcon->service); + int i; + struct ntvfs_context *ctx; - req->tcon->ntvfs_ops = ntvfs_backend_byname(handlers[0], req->tcon->type); + if (!handlers) { + return NT_STATUS_FOOBAR; + } - if (!req->tcon->ntvfs_ops) { - DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handlers[0], req->tcon->type)); - return NT_STATUS_UNSUCCESSFUL; + ctx = talloc_p(req->tcon, struct ntvfs_context); + if (!ctx) { + return NT_STATUS_NO_MEMORY; } + ctx->type = type; + ctx->modules = NULL; - return NT_STATUS_OK; -} + for (i=0; handlers[i]; i++) { + struct ntvfs_module_context *ntvfs; + ntvfs = talloc_p(ctx, struct ntvfs_module_context); + if (!ntvfs) { + return NT_STATUS_NO_MEMORY; + } -/* - set the private pointer for a backend -*/ -void ntvfs_set_private(struct smbsrv_tcon *tcon, int depth, void *value) -{ - tcon->ntvfs_private_list = talloc_realloc_p(tcon, - tcon->ntvfs_private_list, - void *, depth+1); - tcon->ntvfs_private_list[depth] = value; + ntvfs->ops = ntvfs_backend_byname(handlers[i], ctx->type); + if (!ntvfs->ops) { + DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", + handlers[i], ctx->type)); + return NT_STATUS_UNSUCCESSFUL; + } + ntvfs->depth = i; + DLIST_ADD_END(ctx->modules, ntvfs, struct ntvfs_module_context *); + } + + if (!ctx->modules) { + talloc_free(ctx); + return NT_STATUS_FOOBAR; + } + + req->tcon->ntvfs_ctx = ctx; + + return NT_STATUS_OK; } diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 731e91f5c9..9e1d653465 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -58,7 +58,7 @@ static BOOL is_exe_file(const char *fname) NTVFS open generic to any mapper */ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, - const struct ntvfs_ops *ops) + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_open io2; @@ -146,7 +146,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2.generic.in.file_attr = io->openx.in.file_attrs; io2.generic.in.fname = io->openx.in.fname; - status = ops->open(req, &io2); + status = ntvfs->ops->open(ntvfs, req, &io2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -228,7 +228,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", io->open.in.flags, io2.generic.in.access_mask, io2.generic.in.share_access)); - status = ops->open(req, &io2); + status = ntvfs->ops->open(ntvfs, req, &io2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -251,7 +251,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, NTVFS fsinfo generic to any mapper */ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, - const struct ntvfs_ops *ops) + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_fsinfo fs2; @@ -263,7 +263,7 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, /* ask the backend for the generic info */ fs2.generic.level = RAW_QFS_GENERIC; - status = ops->fsinfo(req, &fs2); + status = ntvfs->ops->fsinfo(ntvfs, req, &fs2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -593,7 +593,7 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info NTVFS fileinfo generic to any mapper */ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info, - const struct ntvfs_ops *ops) + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_fileinfo info2; @@ -606,7 +606,7 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf info2.generic.level = RAW_FILEINFO_GENERIC; info2.generic.in.fnum = info->generic.in.fnum; - status = ops->qfileinfo(req, &info2); + status = ntvfs->ops->qfileinfo(ntvfs, req, &info2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -617,7 +617,7 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf NTVFS pathinfo generic to any mapper */ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info, - const struct ntvfs_ops *ops) + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_fileinfo info2; @@ -630,7 +630,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf info2.generic.level = RAW_FILEINFO_GENERIC; info2.generic.in.fname = info->generic.in.fname; - status = ops->qpathinfo(req, &info2); + status = ntvfs->ops->qpathinfo(ntvfs, req, &info2); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c new file mode 100644 index 0000000000..06cda11000 --- /dev/null +++ b/source4/ntvfs/ntvfs_interface.c @@ -0,0 +1,566 @@ +/* + Unix SMB/CIFS implementation. + NTVFS interface functions + + Copyright (C) Stefan (metze) Metzmacher 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* connect/disconnect */ +NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->connect) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->connect(ntvfs, req, sharename); +} + +NTSTATUS ntvfs_disconnect(struct smbsrv_tcon *tcon) +{ + struct ntvfs_module_context *ntvfs = tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->disconnect) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->disconnect(ntvfs, tcon); +} + +/* path operations */ +NTSTATUS ntvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->unlink) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->unlink(ntvfs, req, unl); +} + +NTSTATUS ntvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->chkpath) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->chkpath(ntvfs, req, cp); +} + +NTSTATUS ntvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *st) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->qpathinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->qpathinfo(ntvfs, req, st); +} + +NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->setpathinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->setpathinfo(ntvfs, req, st); +} + +NTSTATUS ntvfs_open(struct smbsrv_request *req, union smb_open *oi) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->open) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->open(ntvfs, req, oi); +} + +NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->mkdir) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->mkdir(ntvfs, req, md); +} + +NTSTATUS ntvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->rmdir) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->rmdir(ntvfs, req, rd); +} + +NTSTATUS ntvfs_rename(struct smbsrv_request *req, union smb_rename *ren) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->rename) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->rename(ntvfs, req, ren); +} + +NTSTATUS ntvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->copy) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->copy(ntvfs, req, cp); +} + +/* directory search */ +NTSTATUS ntvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *private, + BOOL ntvfs_callback(void *private, union smb_search_data *file)) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->search_first) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->search_first(ntvfs, req, io, private, ntvfs_callback); +} + +NTSTATUS ntvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *private, + BOOL ntvfs_callback(void *private, union smb_search_data *file)) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->search_next) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->search_next(ntvfs, req, io, private, ntvfs_callback); +} + +NTSTATUS ntvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->search_close) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->search_close(ntvfs, req, io); +} + +/* operations on open files */ +NTSTATUS ntvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->ioctl) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->ioctl(ntvfs, req, io); +} + +NTSTATUS ntvfs_read(struct smbsrv_request *req, union smb_read *io) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->read) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->read(ntvfs, req, io); +} + +NTSTATUS ntvfs_write(struct smbsrv_request *req, union smb_write *io) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->write) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->write(ntvfs, req, io); +} + +NTSTATUS ntvfs_seek(struct smbsrv_request *req, struct smb_seek *io) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->seek) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->seek(ntvfs, req, io); +} + +NTSTATUS ntvfs_flush(struct smbsrv_request *req, struct smb_flush *flush) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->flush) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->flush(ntvfs, req, flush); +} + +NTSTATUS ntvfs_close(struct smbsrv_request *req, union smb_close *io) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->close) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->close(ntvfs, req, io); +} + +NTSTATUS ntvfs_exit(struct smbsrv_request *req) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->exit) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->exit(ntvfs, req); +} + +NTSTATUS ntvfs_lock(struct smbsrv_request *req, union smb_lock *lck) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->lock) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->lock(ntvfs, req, lck); +} + +NTSTATUS ntvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->setfileinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->setfileinfo(ntvfs, req, info); +} + +NTSTATUS ntvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->qfileinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->qfileinfo(ntvfs, req, info); +} + +/* filesystem operations */ +NTSTATUS ntvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->fsinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->fsinfo(ntvfs, req, fs); +} + +/* printing specific operations */ +NTSTATUS ntvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->lpq) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->lpq(ntvfs, req, lpq); +} + +/* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ +NTSTATUS ntvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->trans2) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->trans2(ntvfs, req, trans2); +} + +/* trans interface - used by IPC backend for pipes and RAP calls */ +NTSTATUS ntvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->trans) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->trans(ntvfs, req, trans); +} + +/* logoff - called when a vuid is closed */ +NTSTATUS ntvfs_logoff(struct smbsrv_request *req) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->logoff) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->logoff(ntvfs, req); +} + +/* initial setup */ +NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) +{ + if (!ntvfs->next || !ntvfs->next->ops->connect) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->connect(ntvfs->next, req, sharename); +} + +NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) +{ + if (!ntvfs->next || !ntvfs->next->ops->disconnect) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->disconnect(ntvfs->next, tcon); +} + +/* path operations */ +NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) +{ + if (!ntvfs->next || !ntvfs->next->ops->unlink) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->unlink(ntvfs->next, req, unl); +} + +NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) +{ + if (!ntvfs->next || !ntvfs->next->ops->chkpath) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->chkpath(ntvfs->next, req, cp); +} + +NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *st) +{ + if (!ntvfs->next || !ntvfs->next->ops->qpathinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->qpathinfo(ntvfs->next, req, st); +} + +NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) +{ + if (!ntvfs->next || !ntvfs->next->ops->setpathinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st); +} + +NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *oi) +{ + if (!ntvfs->next || !ntvfs->next->ops->open) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->open(ntvfs->next, req, oi); +} + +NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) +{ + if (!ntvfs->next || !ntvfs->next->ops->mkdir) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->mkdir(ntvfs->next, req, md); +} + +NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) +{ + if (!ntvfs->next || !ntvfs->next->ops->rmdir) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->rmdir(ntvfs->next, req, rd); +} + +NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) +{ + if (!ntvfs->next || !ntvfs->next->ops->rename) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->rename(ntvfs->next, req, ren); +} + +NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) +{ + if (!ntvfs->next || !ntvfs->next->ops->copy) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->copy(ntvfs->next, req, cp); +} + +/* directory search */ +NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) +{ + if (!ntvfs->next || !ntvfs->next->ops->search_first) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->search_first(ntvfs->next, req, io, private, callback); +} + +NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) +{ + if (!ntvfs->next || !ntvfs->next->ops->search_next) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->search_next(ntvfs->next, req, io, private, callback); +} + +NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) +{ + if (!ntvfs->next || !ntvfs->next->ops->search_close) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->search_close(ntvfs->next, req, io); +} + +/* operations on open files */ +NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) +{ + if (!ntvfs->next || !ntvfs->next->ops->ioctl) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->ioctl(ntvfs->next, req, io); +} + +NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *io) +{ + if (!ntvfs->next || !ntvfs->next->ops->read) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->read(ntvfs->next, req, io); +} + +NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *io) +{ + if (!ntvfs->next || !ntvfs->next->ops->write) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->write(ntvfs->next, req, io); +} + +NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) +{ + if (!ntvfs->next || !ntvfs->next->ops->seek) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->seek(ntvfs->next, req, io); +} + +NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *flush) +{ + if (!ntvfs->next || !ntvfs->next->ops->flush) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->flush(ntvfs->next, req, flush); +} + +NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) +{ + if (!ntvfs->next || !ntvfs->next->ops->close) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->close(ntvfs->next, req, io); +} + +NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + if (!ntvfs->next || !ntvfs->next->ops->exit) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->exit(ntvfs->next, req); +} + +NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) +{ + if (!ntvfs->next || !ntvfs->next->ops->lock) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->lock(ntvfs->next, req, lck); +} + +NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) +{ + if (!ntvfs->next || !ntvfs->next->ops->setfileinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info); +} + +NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) +{ + if (!ntvfs->next || !ntvfs->next->ops->qfileinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->qfileinfo(ntvfs->next, req, info); +} + +/* filesystem operations */ +NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) +{ + if (!ntvfs->next || !ntvfs->next->ops->fsinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->fsinfo(ntvfs->next, req, fs); +} + +/* printing specific operations */ +NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) +{ + if (!ntvfs->next || !ntvfs->next->ops->lpq) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->lpq(ntvfs->next, req, lpq); +} + +/* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ +NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) +{ + if (!ntvfs->next || !ntvfs->next->ops->trans2) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->trans2(ntvfs->next, req, trans2); +} + +/* trans interface - used by IPC backend for pipes and RAP calls */ +NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans) +{ + if (!ntvfs->next || !ntvfs->next->ops->trans) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->trans(ntvfs->next, req, trans); +} + +/* logoff - called when a vuid is closed */ +NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + if (!ntvfs->next || !ntvfs->next->ops->logoff) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->logoff(ntvfs->next, req); +} diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index f1c42e8920..a9153b4c19 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -27,13 +27,14 @@ /* return filesystem space info */ -NTSTATUS pvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { - return ntvfs_map_fsinfo(req, fs, pvfs->ops); + return ntvfs_map_fsinfo(req, fs, ntvfs); } if (sys_fsusage(pvfs->base_directory, diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index de51d2e8fd..d7dcc7dd50 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -26,9 +26,10 @@ /* create a directory */ -NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name; @@ -60,9 +61,10 @@ NTSTATUS pvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) /* remove a directory */ -NTSTATUS pvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index f3bec4085e..560d194a34 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -27,9 +27,9 @@ /* find open file handle given fnum */ -struct pvfs_file *pvfs_find_fd(struct smbsrv_request *req, uint16_t fnum) +struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, + 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) { @@ -63,16 +63,17 @@ static int pvfs_fd_destructor(void *p) TODO: this is a temporary implementation derived from the simple backend its purpose is to allow other tests to run */ -NTSTATUS pvfs_open(struct smbsrv_request *req, union smb_open *io) +NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; int fd, flags; struct pvfs_filename *name; struct pvfs_file *f; NTSTATUS status; if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(req, io, pvfs->ops); + return ntvfs_map_open(req, io, ntvfs); } /* resolve the cifs name to a posix name */ @@ -179,9 +180,10 @@ do_open: /* close a file */ -NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) +NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; NTSTATUS status; @@ -190,7 +192,7 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) return NT_STATUS_INVALID_LEVEL; } - f = pvfs_find_fd(req, io->close.in.fnum); + f = pvfs_find_fd(pvfs, req, io->close.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } @@ -213,9 +215,10 @@ NTSTATUS pvfs_close(struct smbsrv_request *req, union smb_close *io) /* logoff - close all file descriptors open by a vuid */ -NTSTATUS pvfs_logoff(struct smbsrv_request *req) +NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f, *next; for (f=pvfs->open_files;f;f=next) { @@ -234,9 +237,10 @@ NTSTATUS pvfs_logoff(struct smbsrv_request *req) /* exit - close files for the current pid */ -NTSTATUS pvfs_exit(struct smbsrv_request *req) +NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f, *next; for (f=pvfs->open_files;f;f=next) { @@ -250,4 +254,3 @@ NTSTATUS pvfs_exit(struct smbsrv_request *req) return NT_STATUS_OK; } - diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 81706bcfe8..30390722d1 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -78,14 +78,15 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* return info on a pathname */ -NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_filename *name; NTSTATUS status; if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qpathinfo(req, info, pvfs->ops); + return ntvfs_map_qpathinfo(req, info, ntvfs); } /* resolve the cifs name to a posix name */ @@ -104,17 +105,18 @@ NTSTATUS pvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) /* query info on a open file */ -NTSTATUS pvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; NTSTATUS status; if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qfileinfo(req, info, pvfs->ops); + return ntvfs_map_qfileinfo(req, info, ntvfs); } - f = pvfs_find_fd(req, info->generic.in.fnum); + f = pvfs_find_fd(pvfs, req, info->generic.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 72ac00a32d..e0c7e0b1f2 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -26,9 +26,10 @@ /* read from a file */ -NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) +NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *rd) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; ssize_t ret; struct pvfs_file *f; @@ -37,7 +38,7 @@ NTSTATUS pvfs_read(struct smbsrv_request *req, union smb_read *rd) } - f = pvfs_find_fd(req, rd->readx.in.fnum); + f = pvfs_find_fd(pvfs, req, rd->readx.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index a58a1e9c6e..51393c9499 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -26,9 +26,10 @@ /* rename a set of files */ -NTSTATUS pvfs_rename(struct smbsrv_request *req, union smb_rename *ren) +NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 414b010263..f8d538bab2 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -250,12 +250,13 @@ again: /* list files in a directory matching a wildcard pattern - old SMBsearch interface */ -static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_search_first *io, +static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { struct pvfs_dir *dir; - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; uint_t reply_count; uint16_t search_attrib; @@ -327,11 +328,12 @@ static NTSTATUS pvfs_search_first_old(struct smbsrv_request *req, union smb_sear } /* continue a old style search */ -static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_search_next *io, +static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; struct pvfs_dir *dir; uint_t reply_count, max_count; @@ -374,12 +376,13 @@ static NTSTATUS pvfs_search_next_old(struct smbsrv_request *req, union smb_searc /* list files in a directory matching a wildcard pattern */ -NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, +NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { struct pvfs_dir *dir; - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; uint_t reply_count; uint16_t search_attrib, max_count; @@ -388,7 +391,7 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i struct pvfs_filename *name; if (io->generic.level >= RAW_SEARCH_SEARCH) { - return pvfs_search_first_old(req, io, search_private, callback); + return pvfs_search_first_old(ntvfs, req, io, search_private, callback); } search_attrib = io->t2ffirst.in.search_attrib; @@ -466,11 +469,12 @@ NTSTATUS pvfs_search_first(struct smbsrv_request *req, union smb_search_first *i } /* continue a search */ -NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, +NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; struct pvfs_dir *dir; uint_t reply_count; @@ -479,7 +483,7 @@ NTSTATUS pvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, int i; if (io->generic.level >= RAW_SEARCH_SEARCH) { - return pvfs_search_next_old(req, io, search_private, callback); + return pvfs_search_next_old(ntvfs, req, io, search_private, callback); } handle = io->t2fnext.in.handle; @@ -545,9 +549,10 @@ found: } /* close a search */ -NTSTATUS pvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; uint16_t handle; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 2ea2fdaf8e..f1d5d14089 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -26,14 +26,15 @@ /* set info on a open file */ -NTSTATUS pvfs_setfileinfo(struct smbsrv_request *req, +NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) { - NTVFS_GET_PRIVATE(pvfs_private, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct utimbuf unix_times; struct pvfs_file *f; - f = pvfs_find_fd(req, info->generic.file.fnum); + f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 9e0353c041..0f4ff8b148 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -61,9 +61,10 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -NTSTATUS pvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_dir *dir; NTSTATUS status; uint32_t i, total_deleted=0; diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 02ba1b8228..a49f4fe947 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -27,15 +27,16 @@ /* write to a file */ -NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) +NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *wr) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; ssize_t ret; struct pvfs_file *f; switch (wr->generic.level) { case RAW_WRITE_WRITEX: - f = pvfs_find_fd(req, wr->writex.in.fnum); + f = pvfs_find_fd(pvfs, req, wr->writex.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } @@ -53,7 +54,7 @@ NTSTATUS pvfs_write(struct smbsrv_request *req, union smb_write *wr) return NT_STATUS_OK; case RAW_WRITE_WRITE: - f = pvfs_find_fd(req, wr->write.in.fnum); + f = pvfs_find_fd(pvfs, req, wr->write.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 7ae7c6759a..44875f1879 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -50,7 +50,8 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename, int depth) +static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; struct pvfs_state *pvfs; @@ -71,7 +72,6 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename, pvfs->tcon = tcon; pvfs->base_directory = base_directory; - pvfs->ops = ntvfs_backend_byname("posix", NTVFS_DISK); /* the directory must exist. Note that we deliberately don't check that it is readable */ @@ -84,7 +84,7 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename, tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); - ntvfs_set_private(tcon, depth, pvfs); + ntvfs->private_data = pvfs; pvfs_setup_options(pvfs); @@ -94,7 +94,8 @@ static NTSTATUS pvfs_connect(struct smbsrv_request *req, const char *sharename, /* disconnect from a share */ -static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon, int depth) +static NTSTATUS pvfs_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) { return NT_STATUS_OK; } @@ -102,7 +103,8 @@ static NTSTATUS pvfs_disconnect(struct smbsrv_tcon *tcon, int depth) /* ioctl interface - we don't do any */ -static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +static NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) { return NT_STATUS_INVALID_PARAMETER; } @@ -110,9 +112,10 @@ static NTSTATUS pvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) { - NTVFS_GET_PRIVATE(pvfs_state, pvfs, req); + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_filename *name; NTSTATUS status; @@ -136,7 +139,8 @@ static NTSTATUS pvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) /* copy a set of files */ -static NTSTATUS pvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) +static NTSTATUS pvfs_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) { DEBUG(0,("pvfs_copy not implemented\n")); return NT_STATUS_NOT_SUPPORTED; @@ -145,7 +149,8 @@ static NTSTATUS pvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) /* seek in a file */ -static NTSTATUS pvfs_seek(struct smbsrv_request *req, struct smb_seek *io) +static NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) { DEBUG(0,("pvfs_seek not implemented\n")); return NT_STATUS_NOT_SUPPORTED; @@ -154,7 +159,8 @@ static NTSTATUS pvfs_seek(struct smbsrv_request *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io) +static NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *io) { DEBUG(0,("pvfs_flush not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; @@ -163,7 +169,8 @@ static NTSTATUS pvfs_flush(struct smbsrv_request *req, struct smb_flush *io) /* lock a byte range */ -static NTSTATUS pvfs_lock(struct smbsrv_request *req, union smb_lock *lck) +static NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) { DEBUG(0,("pvfs_lock not implemented\n")); return NT_STATUS_NOT_IMPLEMENTED; @@ -172,7 +179,8 @@ static NTSTATUS pvfs_lock(struct smbsrv_request *req, union smb_lock *lck) /* set info on a pathname */ -static NTSTATUS pvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +static NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) { DEBUG(0,("pvfs_setpathinfo not implemented\n")); return NT_STATUS_NOT_SUPPORTED; @@ -181,13 +189,15 @@ static NTSTATUS pvfs_setpathinfo(struct smbsrv_request *req, union smb_setfilein /* return print queue info */ -static NTSTATUS pvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +static NTSTATUS pvfs_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } /* SMBtrans - not used on file shares */ -static NTSTATUS pvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) +static NTSTATUS pvfs_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 96ab7f85b2..0daacf2c33 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -49,8 +49,6 @@ struct pvfs_state { } search; struct pvfs_file *open_files; - - const struct ntvfs_ops *ops; }; diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 0e6824a14e..d487392e6f 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -29,7 +29,8 @@ in. For printing shares this should check that the spool directory is available */ -static NTSTATUS print_connect(struct smbsrv_request *req, const char *sharename, int depth) +static NTSTATUS print_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) { return NT_STATUS_OK; } @@ -37,7 +38,8 @@ static NTSTATUS print_connect(struct smbsrv_request *req, const char *sharename, /* disconnect from a share */ -static NTSTATUS print_disconnect(struct smbsrv_tcon *tcon, int depth) +static NTSTATUS print_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) { return NT_STATUS_OK; } @@ -45,7 +47,8 @@ static NTSTATUS print_disconnect(struct smbsrv_tcon *tcon, int depth) /* lots of operations are not allowed on printing shares - mostly return NT_STATUS_ACCESS_DENIED */ -static NTSTATUS print_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +static NTSTATUS print_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } @@ -54,7 +57,8 @@ static NTSTATUS print_unlink(struct smbsrv_request *req, struct smb_unlink *unl) /* ioctl - used for job query */ -static NTSTATUS print_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) { char *p; diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index d3bafb42e3..8e462d99f4 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -10,8 +10,6 @@ struct svfs_private { uint16_t next_search_handle; struct svfs_file *open_files; - - const struct ntvfs_ops *ops; }; struct svfs_dir { diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index b6b7171487..2ac12b1918 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -29,9 +29,10 @@ /* convert a windows path to a unix path - don't do any manging or case sensitive handling */ -char *svfs_unix_path(struct smbsrv_request *req, const char *name) +char *svfs_unix_path(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *name) { - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; char *ret; if (*name != '\\') { @@ -135,14 +136,15 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *svfs_list(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, const char *pattern) +struct svfs_dir *svfs_list(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *pattern) { + struct svfs_private *private = ntvfs->private_data; char *unix_path; - unix_path = svfs_unix_path(req, pattern); + unix_path = svfs_unix_path(ntvfs, req, pattern); if (!unix_path) { return NULL; } - return svfs_list_unix(mem_ctx, req, unix_path); + return svfs_list_unix(private, req, unix_path); } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index f60646ed77..7f5d447a09 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -61,7 +61,8 @@ static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offs directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename, int depth) +static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) { struct stat st; struct smbsrv_tcon *tcon = req->tcon; @@ -72,7 +73,6 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename, private->next_search_handle = 0; private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service)); private->open_files = NULL; - private->ops = ntvfs_backend_byname("simple", NTVFS_DISK); private->search = NULL; /* the directory must exist */ @@ -85,7 +85,7 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename, tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); - ntvfs_set_private(tcon, depth, private); + ntvfs->private_data = private; DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); @@ -95,7 +95,8 @@ static NTSTATUS svfs_connect(struct smbsrv_request *req, const char *sharename, /* disconnect from a share */ -static NTSTATUS svfs_disconnect(struct smbsrv_tcon *tcon, int depth) +static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) { return NT_STATUS_OK; } @@ -118,13 +119,14 @@ static struct svfs_file *find_fd(struct svfs_private *private, int fd) delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS svfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) { char *unix_path; CHECK_READ_ONLY(req); - unix_path = svfs_unix_path(req, unl->in.pattern); + unix_path = svfs_unix_path(ntvfs, req, unl->in.pattern); /* ignoring wildcards ... */ if (unlink(unix_path) == -1) { @@ -138,7 +140,8 @@ static NTSTATUS svfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) /* ioctl interface - we don't do any */ -static NTSTATUS svfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) { return NT_STATUS_INVALID_PARAMETER; } @@ -146,12 +149,13 @@ static NTSTATUS svfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) /* check if a directory exists */ -static NTSTATUS svfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) { char *unix_path; struct stat st; - unix_path = svfs_unix_path(req, cp->in.path); + unix_path = svfs_unix_path(ntvfs, req, cp->in.path); if (stat(unix_path, &st) == -1) { return map_nt_error_from_unix(errno); @@ -167,7 +171,8 @@ static NTSTATUS svfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) /* approximately map a struct stat to a generic fileinfo struct */ -static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, +static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info, struct stat *st, const char *unix_path) { struct svfs_dir *dir = NULL; @@ -242,18 +247,18 @@ static NTSTATUS svfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo /* return info on a pathname */ -static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(svfs_private, private, req); char *unix_path; struct stat st; DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level)); if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qpathinfo(req, info, private->ops); + return ntvfs_map_qpathinfo(req, info, ntvfs); } - unix_path = svfs_unix_path(req, info->generic.in.fname); + unix_path = svfs_unix_path(ntvfs, req, info->generic.in.fname); DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); if (stat(unix_path, &st) == -1) { DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); @@ -262,20 +267,21 @@ static NTSTATUS svfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *i return map_nt_error_from_unix(errno); } DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); - return svfs_map_fileinfo(req, info, &st, unix_path); + return svfs_map_fileinfo(ntvfs, req, info, &st, unix_path); } /* query info on a open file */ -static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; struct stat st; if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qfileinfo(req, info, private->ops); + return ntvfs_map_qfileinfo(req, info, ntvfs); } f = find_fd(private, info->generic.in.fnum); @@ -289,16 +295,17 @@ static NTSTATUS svfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *i return map_nt_error_from_unix(errno); } - return svfs_map_fileinfo(req, info, &st, f->name); + return svfs_map_fileinfo(ntvfs, req,info, &st, f->name); } /* open a file */ -static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) +static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) { - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; char *unix_path; struct stat st; int fd, flags; @@ -306,7 +313,7 @@ static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) int create_flags, rdwr_flags; if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(req, io, private->ops); + return ntvfs_map_open(req, io, ntvfs); } if (lp_readonly(req->tcon->service)) { @@ -317,7 +324,7 @@ static NTSTATUS svfs_open(struct smbsrv_request *req, union smb_open *io) rdwr_flags = O_RDWR; } - unix_path = svfs_unix_path(req, io->ntcreatex.in.fname); + unix_path = svfs_unix_path(ntvfs, req, io->ntcreatex.in.fname); switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: @@ -402,7 +409,8 @@ do_open: /* create a directory */ -static NTSTATUS svfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) { char *unix_path; @@ -412,7 +420,7 @@ static NTSTATUS svfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) return NT_STATUS_INVALID_LEVEL; } - unix_path = svfs_unix_path(req, md->mkdir.in.path); + unix_path = svfs_unix_path(ntvfs, req, md->mkdir.in.path); if (mkdir(unix_path, 0777) == -1) { return map_nt_error_from_unix(errno); @@ -424,13 +432,14 @@ static NTSTATUS svfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) /* remove a directory */ -static NTSTATUS svfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) { char *unix_path; CHECK_READ_ONLY(req); - unix_path = svfs_unix_path(req, rd->in.path); + unix_path = svfs_unix_path(ntvfs, req, rd->in.path); if (rmdir(unix_path) == -1) { return map_nt_error_from_unix(errno); @@ -442,7 +451,8 @@ static NTSTATUS svfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) /* rename a set of files */ -static NTSTATUS svfs_rename(struct smbsrv_request *req, union smb_rename *ren) +static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) { char *unix_path1, *unix_path2; @@ -452,8 +462,8 @@ static NTSTATUS svfs_rename(struct smbsrv_request *req, union smb_rename *ren) return NT_STATUS_INVALID_LEVEL; } - unix_path1 = svfs_unix_path(req, ren->rename.in.pattern1); - unix_path2 = svfs_unix_path(req, ren->rename.in.pattern2); + unix_path1 = svfs_unix_path(ntvfs, req, ren->rename.in.pattern1); + unix_path2 = svfs_unix_path(ntvfs, req, ren->rename.in.pattern2); if (rename(unix_path1, unix_path2) != 0) { return map_nt_error_from_unix(errno); @@ -465,7 +475,8 @@ static NTSTATUS svfs_rename(struct smbsrv_request *req, union smb_rename *ren) /* copy a set of files */ -static NTSTATUS svfs_copy(struct smbsrv_request *req, struct smb_copy *cp) +static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -473,7 +484,8 @@ static NTSTATUS svfs_copy(struct smbsrv_request *req, struct smb_copy *cp) /* read from a file */ -static NTSTATUS svfs_read(struct smbsrv_request *req, union smb_read *rd) +static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *rd) { ssize_t ret; @@ -499,7 +511,8 @@ static NTSTATUS svfs_read(struct smbsrv_request *req, union smb_read *rd) /* write to a file */ -static NTSTATUS svfs_write(struct smbsrv_request *req, union smb_write *wr) +static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *wr) { ssize_t ret; @@ -545,7 +558,8 @@ static NTSTATUS svfs_write(struct smbsrv_request *req, union smb_write *wr) /* seek in a file */ -static NTSTATUS svfs_seek(struct smbsrv_request *req, struct smb_seek *io) +static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) { return NT_STATUS_NOT_SUPPORTED; } @@ -553,7 +567,8 @@ static NTSTATUS svfs_seek(struct smbsrv_request *req, struct smb_seek *io) /* flush a file */ -static NTSTATUS svfs_flush(struct smbsrv_request *req, struct smb_flush *io) +static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *io) { fsync(io->in.fnum); return NT_STATUS_OK; @@ -562,9 +577,10 @@ static NTSTATUS svfs_flush(struct smbsrv_request *req, struct smb_flush *io) /* close a file */ -static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io) +static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) { - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; if (io->generic.level != RAW_CLOSE_CLOSE) { @@ -591,7 +607,8 @@ static NTSTATUS svfs_close(struct smbsrv_request *req, union smb_close *io) /* exit - closing files */ -static NTSTATUS svfs_exit(struct smbsrv_request *req) +static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { return NT_STATUS_NOT_SUPPORTED; } @@ -599,7 +616,8 @@ static NTSTATUS svfs_exit(struct smbsrv_request *req) /* logoff - closing files */ -static NTSTATUS svfs_logoff(struct smbsrv_request *req) +static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { return NT_STATUS_NOT_SUPPORTED; } @@ -607,7 +625,8 @@ static NTSTATUS svfs_logoff(struct smbsrv_request *req) /* lock a byte range */ -static NTSTATUS svfs_lock(struct smbsrv_request *req, union smb_lock *lck) +static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) { DEBUG(0,("REWRITE: not doing byte range locking!\n")); return NT_STATUS_OK; @@ -616,7 +635,8 @@ static NTSTATUS svfs_lock(struct smbsrv_request *req, union smb_lock *lck) /* set info on a pathname */ -static NTSTATUS svfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) { CHECK_READ_ONLY(req); @@ -626,7 +646,8 @@ static NTSTATUS svfs_setpathinfo(struct smbsrv_request *req, union smb_setfilein /* set info on a open file */ -static NTSTATUS svfs_setfileinfo(struct smbsrv_request *req, +static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) { struct utimbuf unix_times; @@ -669,13 +690,14 @@ static NTSTATUS svfs_setfileinfo(struct smbsrv_request *req, /* return filesystem space info */ -static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) { - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { - return ntvfs_map_fsinfo(req, fs, private->ops); + return ntvfs_map_fsinfo(req, fs, ntvfs); } if (sys_fsusage(private->connectpath, @@ -710,13 +732,14 @@ static NTSTATUS svfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) /* return filesystem attribute info */ -static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs) +static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsattr *fs) { struct stat st; - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; if (fs->generic.level != RAW_FSATTR_GENERIC) { - return ntvfs_map_fsattr(req, fs); + return ntvfs_map_fsattr(req, fs, ntvfs); } if (stat(private->connectpath, &st) != 0) { @@ -741,7 +764,8 @@ static NTSTATUS svfs_fsattr(struct smbsrv_request *req, union smb_fsattr *fs) /* return print queue info */ -static NTSTATUS svfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -749,13 +773,14 @@ static NTSTATUS svfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) /* list files in a directory matching a wildcard pattern */ -static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_first *io, +static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { struct svfs_dir *dir; int i; - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; struct search_state *search; union smb_search_data file; uint_t max_count; @@ -771,7 +796,7 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f max_count = io->t2ffirst.in.max_count; - dir = svfs_list(private, req, io->t2ffirst.in.pattern); + dir = svfs_list(ntvfs, req, io->t2ffirst.in.pattern); if (!dir) { return NT_STATUS_FOOBAR; } @@ -818,13 +843,14 @@ static NTSTATUS svfs_search_first(struct smbsrv_request *req, union smb_search_f } /* continue a search */ -static NTSTATUS svfs_search_next(struct smbsrv_request *req, union smb_search_next *io, +static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { struct svfs_dir *dir; int i; - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; struct search_state *search; union smb_search_data file; uint_t max_count; @@ -905,9 +931,10 @@ found: } /* close a search */ -static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) { - NTVFS_GET_PRIVATE(svfs_private, private, req); + struct svfs_private *private = ntvfs->private_data; struct search_state *search; for (search=private->search; search; search = search->next) { @@ -926,7 +953,8 @@ static NTSTATUS svfs_search_close(struct smbsrv_request *req, union smb_search_c } /* SMBtrans - not used on file shares */ -static NTSTATUS svfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans2) +static NTSTATUS svfs_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } -- cgit From 84bbe948f3beff0fbdc51c9c63e2f674b70b5bbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 2 Oct 2004 12:25:02 +0000 Subject: r2786: - match on both long and short name for search posix backend - a final name component of . is illegal (This used to be commit 11c852170b83e5adbdb58407e1c7d3aeb4ab5bb8) --- source4/ntvfs/posix/pvfs_dirlist.c | 11 ++++++++++- source4/ntvfs/posix/pvfs_resolve.c | 10 ++++++++-- source4/ntvfs/posix/pvfs_shortname.c | 12 +++++++++++- 3 files changed, 29 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 56afb4f33b..79d9a9a3fa 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -98,11 +98,20 @@ NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct p while ((dent = readdir(odir))) { uint_t i = dir->count; const char *dname = dent->d_name; + char *short_name; + + short_name = pvfs_short_name_component(pvfs, dname); /* check it matches the wildcard pattern */ - if (ms_fnmatch(pattern, dname, PROTOCOL_NT1) != 0) { + if (ms_fnmatch(pattern, dname, + pvfs->tcon->smb_conn->negotiate.protocol) != 0 && + ms_fnmatch(pattern, short_name, + pvfs->tcon->smb_conn->negotiate.protocol) != 0) { + talloc_free(short_name); continue; } + + talloc_free(short_name); if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index dfd6744eff..e846b7be77 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -159,6 +159,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, uint_t flags, struct pvfs_filename *name) { char *ret, *p; + size_t len; name->original_name = talloc_strdup(name, cifs_name); name->stream_name = NULL; @@ -183,8 +184,13 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, p = ret + strlen(pvfs->base_directory) + 1; - if (p[strlen(cifs_name)-1] == '\\') { - p[strlen(cifs_name)-1] = 0; + len = strlen(cifs_name); + if (len>0 && p[len-1] == '\\') { + p[len-1] = 0; + len--; + } + if (len>1 && p[len-1] == '.' && p[len-2] == '\\') { + return NT_STATUS_OBJECT_NAME_INVALID; } /* now do an in-place conversion of '\' to '/', checking diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index fe6fd8e030..33e601e429 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -24,6 +24,16 @@ #include "vfs_posix.h" +/* + return the short name for a component of a full name + TODO: this is obviously not very useful in its current form ! +*/ +char *pvfs_short_name_component(struct pvfs_state *pvfs, const char *name) +{ + return talloc_strndup(pvfs, name, 12); +} + + /* return the short name for a given entry in a directory TODO: this is obviously not very useful in its current form ! @@ -31,5 +41,5 @@ char *pvfs_short_name(struct pvfs_state *pvfs, struct pvfs_filename *name) { char *p = strrchr(name->full_name, '/'); - return talloc_strndup(name, p+1, 12); + return pvfs_short_name_component(pvfs, p+1); } -- cgit From 421ff99f5d33c4be72f56f09d82f6ba6fe1bea5c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 2 Oct 2004 13:29:20 +0000 Subject: r2788: prevent a memory leak in the pvfs search backend (This used to be commit 1de22070610231e60d329f56997bbec2cc674a4e) --- source4/ntvfs/posix/pvfs_search.c | 4 ++-- source4/ntvfs/posix/pvfs_shortname.c | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index f8d538bab2..211cb68b86 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -125,7 +125,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->both_directory_info.alloc_size = name->dos.alloc_size; file->both_directory_info.attrib = name->dos.attrib; file->both_directory_info.ea_size = name->dos.ea_size; - file->both_directory_info.short_name.s = pvfs_short_name(pvfs, name); + file->both_directory_info.short_name.s = pvfs_short_name(pvfs, file, name); file->both_directory_info.name.s = fname; return NT_STATUS_OK; @@ -154,7 +154,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->id_both_directory_info.attrib = name->dos.attrib; file->id_both_directory_info.ea_size = name->dos.ea_size; file->id_both_directory_info.file_id = name->dos.file_id; - file->id_both_directory_info.short_name.s = pvfs_short_name(pvfs, name); + file->id_both_directory_info.short_name.s = pvfs_short_name(pvfs, file, name); file->id_both_directory_info.name.s = fname; return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 33e601e429..21c0ca6ea0 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -38,8 +38,10 @@ char *pvfs_short_name_component(struct pvfs_state *pvfs, const char *name) return the short name for a given entry in a directory TODO: this is obviously not very useful in its current form ! */ -char *pvfs_short_name(struct pvfs_state *pvfs, struct pvfs_filename *name) +char *pvfs_short_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, struct pvfs_filename *name) { char *p = strrchr(name->full_name, '/'); - return pvfs_short_name_component(pvfs, p+1); + char *ret = pvfs_short_name_component(pvfs, p+1); + talloc_steal(mem_ctx, ret); + return ret; } -- cgit From 54ae58fbcdf18d6d4b0ab2227099e6b7d7bb963e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 2 Oct 2004 15:28:16 +0000 Subject: r2789: fix compile (This used to be commit a34ba8dafebb65e59616a0e68cc3d6fe3a349801) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 30390722d1..78d0983bf6 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -47,7 +47,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, info->generic.out.ea_size = 0; info->generic.out.num_eas = 0; info->generic.out.fname.s = name->original_name; - info->generic.out.alt_fname.s = pvfs_short_name(pvfs, name); + info->generic.out.alt_fname.s = pvfs_short_name(pvfs, name, name); info->generic.out.compressed_size = name->st.st_size; info->generic.out.format = 0; info->generic.out.unit_shift = 0; -- cgit From 5a872512b0d6ed09c515f7f85c29add5934361d3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Oct 2004 06:46:29 +0000 Subject: r2794: a very simple version of the unixuid NTVFS pass-thru module. In conjunction with the posix backend this gives us a way to correctly setup the unix security context in Samba4. I chose the following method to determine the unix uid's and gid's to use given the list of SIDs from the login process - look for a "UnixID" field in the sam record. If present, then use it (check if the record is of the right type as well) - if UnixID is not present, then look for the "UnixName" sam field. If it is present then use getpwnam() or getgrnam() to find the unix id. - if UnixID and UnixName are not present, then look for a unix account of the right type called by the same name as the sAMAccountName field. - if none of the above work then fail the operation with NT_STATUS_ACCESS_DENIED obviously these steps only work well with a local SAM. It will need to be more sophisticated in future. I did not put any cache in place at all. That will need to be added for decent performance. (This used to be commit 78b67d19b9766131f0270e451089ee5bb1aa8bd9) --- source4/ntvfs/config.m4 | 3 + source4/ntvfs/posix/config.m4 | 55 --- source4/ntvfs/unixuid/config.m4 | 58 +++ source4/ntvfs/unixuid/config.mk | 7 + source4/ntvfs/unixuid/vfs_unixuid.c | 753 ++++++++++++++++++++++++++++++++++++ 5 files changed, 821 insertions(+), 55 deletions(-) create mode 100644 source4/ntvfs/unixuid/config.m4 create mode 100644 source4/ntvfs/unixuid/config.mk create mode 100644 source4/ntvfs/unixuid/vfs_unixuid.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 index 051a6883e2..dd8e60adde 100644 --- a/source4/ntvfs/config.m4 +++ b/source4/ntvfs/config.m4 @@ -3,6 +3,9 @@ dnl # NTVFS Server subsystem SMB_INCLUDE_M4(ntvfs/posix/config.m4) SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/posix/config.mk) +SMB_INCLUDE_M4(ntvfs/unixuid/config.m4) +SMB_MODULE_MK(ntvfs_unixuid, NTVFS, STATIC, ntvfs/unixuid/config.mk) + SMB_MODULE_MK(ntvfs_cifs, NTVFS, STATIC, ntvfs/config.mk) SMB_MODULE_MK(ntvfs_simple, NTVFS, STATIC, ntvfs/config.mk) diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 3415948f95..b1de4c20e5 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -23,58 +23,3 @@ if test x"$ac_cv_decl_have_stat_tv_nsec" = x"yes"; then fi -################################################ -# look for a method of setting the effective uid -seteuid=no; -if test $seteuid = no; then -AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETRESUID 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) -if test x"$samba_cv_USE_SETRESUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) -fi -fi - - -if test $seteuid = no; then -AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETREUID 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) -if test x"$samba_cv_USE_SETREUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) -fi -fi - -if test $seteuid = no; then -AC_CACHE_CHECK([for seteuid],samba_cv_USE_SETEUID,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETEUID 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETEUID=yes,samba_cv_USE_SETEUID=no,samba_cv_USE_SETEUID=cross)]) -if test x"$samba_cv_USE_SETEUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETEUID,1,[Whether seteuid() is available]) -fi -fi - -if test $seteuid = no; then -AC_CACHE_CHECK([for setuidx],samba_cv_USE_SETUIDX,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETUIDX 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETUIDX=yes,samba_cv_USE_SETUIDX=no,samba_cv_USE_SETUIDX=cross)]) -if test x"$samba_cv_USE_SETUIDX" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETUIDX,1,[Whether setuidx() is available]) -fi -fi diff --git a/source4/ntvfs/unixuid/config.m4 b/source4/ntvfs/unixuid/config.m4 new file mode 100644 index 0000000000..61e7db3d91 --- /dev/null +++ b/source4/ntvfs/unixuid/config.m4 @@ -0,0 +1,58 @@ +SMB_MODULE_MK(ntvfs_unixuid, NTVFS, STATIC, ntvfs/config.mk) + + +################################################ +# look for a method of setting the effective uid +seteuid=no; +if test $seteuid = no; then +AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETRESUID 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) +if test x"$samba_cv_USE_SETRESUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) +fi +fi + + +if test $seteuid = no; then +AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETREUID 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) +if test x"$samba_cv_USE_SETREUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) +fi +fi + +if test $seteuid = no; then +AC_CACHE_CHECK([for seteuid],samba_cv_USE_SETEUID,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETEUID 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETEUID=yes,samba_cv_USE_SETEUID=no,samba_cv_USE_SETEUID=cross)]) +if test x"$samba_cv_USE_SETEUID" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETEUID,1,[Whether seteuid() is available]) +fi +fi + +if test $seteuid = no; then +AC_CACHE_CHECK([for setuidx],samba_cv_USE_SETUIDX,[ +AC_TRY_RUN([ +#define AUTOCONF_TEST 1 +#define USE_SETUIDX 1 +#include "confdefs.h" +#include "${srcdir-.}/lib/util_sec.c"], + samba_cv_USE_SETUIDX=yes,samba_cv_USE_SETUIDX=no,samba_cv_USE_SETUIDX=cross)]) +if test x"$samba_cv_USE_SETUIDX" = x"yes"; then + seteuid=yes;AC_DEFINE(USE_SETUIDX,1,[Whether setuidx() is available]) +fi +fi diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk new file mode 100644 index 0000000000..76e7aebc76 --- /dev/null +++ b/source4/ntvfs/unixuid/config.mk @@ -0,0 +1,7 @@ +################################################ +# Start MODULE ntvfs_unixuid +[MODULE::ntvfs_unixuid] +INIT_OBJ_FILES = \ + ntvfs/unixuid/vfs_unixuid.o +# End MODULE ntvfs_unixuid +################################################ diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c new file mode 100644 index 0000000000..6eef6dbc37 --- /dev/null +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -0,0 +1,753 @@ +/* + Unix SMB/CIFS implementation. + + a pass-thru NTVFS module to setup a security context using unix + uid/gid + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +struct unixuid_private { + void *samctx; +}; + + +/* + map a sid to a unix uid +*/ +static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct dom_sid *sid, uid_t *uid) +{ + struct unixuid_private *private = ntvfs->private_data; + const char *attrs[] = { "sAMAccountName", "UnixID", "UnixName", "sAMAccountType", NULL }; + int ret; + const char *s; + void *ctx; + struct ldb_message **res; + const char *sidstr; + + ctx = talloc(req, 0); + sidstr = dom_sid_string(ctx, sid); + + ret = samdb_search(private->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); + if (ret != 1) { + DEBUG(2,("Unable to map sid %s to unix uid\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* make sure its a user, not a group */ + if (samdb_result_uint(res[0], "sAMAccountType", 0) != ATYPE_NORMAL_ACCOUNT) { + DEBUG(0,("sid_to_unixuid: sid %s is not ATYPE_NORMAL_ACCOUNT\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* first try to get the uid directly */ + s = samdb_result_string(res[0], "UnixID", NULL); + if (s != NULL) { + *uid = strtoul(s, NULL, 0); + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* next try via the UnixName attribute */ + s = samdb_result_string(res[0], "UnixName", NULL); + if (s != NULL) { + struct passwd *pwd = getpwnam(s); + if (!pwd) { + DEBUG(0,("UnixName %s for sid %s does not exist as a local user\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *uid = pwd->pw_uid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* finally try via the sAMAccountName attribute */ + s = samdb_result_string(res[0], "sAMAccountName", NULL); + if (s != NULL) { + struct passwd *pwd = getpwnam(s); + if (!pwd) { + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *uid = pwd->pw_uid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + DEBUG(0,("No sAMAccountName for sid %s!?\n", sidstr)); + + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; +} + + +/* + map a sid to a unix gid +*/ +static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct dom_sid *sid, gid_t *gid) +{ + struct unixuid_private *private = ntvfs->private_data; + const char *attrs[] = { "sAMAccountName", "UnixID", "UnixName", "sAMAccountType", NULL }; + int ret; + const char *s; + void *ctx; + struct ldb_message **res; + const char *sidstr; + + ctx = talloc(req, 0); + sidstr = dom_sid_string(ctx, sid); + + ret = samdb_search(private->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); + if (ret != 1) { + DEBUG(2,("Unable to map sid %s to unix gid\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* make sure its not a user */ + if (samdb_result_uint(res[0], "sAMAccountType", 0) == ATYPE_NORMAL_ACCOUNT) { + DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* first try to get the gid directly */ + s = samdb_result_string(res[0], "UnixID", NULL); + if (s != NULL) { + *gid = strtoul(s, NULL, 0); + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* next try via the UnixName attribute */ + s = samdb_result_string(res[0], "UnixName", NULL); + if (s != NULL) { + struct group *grp = getgrnam(s); + if (!grp) { + DEBUG(0,("UnixName '%s' for sid %s does not exist as a local group\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *gid = grp->gr_gid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* finally try via the sAMAccountName attribute */ + s = samdb_result_string(res[0], "sAMAccountName", NULL); + if (s != NULL) { + struct group *grp = getgrnam(s); + if (!grp) { + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *gid = grp->gr_gid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + DEBUG(0,("No sAMAccountName for sid %s!?\n", sidstr)); + + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; +} + +struct unix_sec_ctx { + uid_t uid; + gid_t gid; + uint_t ngroups; + gid_t *groups; +}; + +/* + pull the current security context into a unix_sec_ctx +*/ +static struct unix_sec_ctx *save_unix_security(TALLOC_CTX *mem_ctx) +{ + struct unix_sec_ctx *sec = talloc_p(mem_ctx, struct unix_sec_ctx); + if (sec == NULL) { + return NULL; + } + sec->uid = geteuid(); + sec->gid = getegid(); + sec->ngroups = getgroups(0, NULL); + if (sec->ngroups == -1) { + talloc_free(sec); + return NULL; + } + sec->groups = talloc_array_p(sec, gid_t, sec->ngroups); + if (sec->groups == NULL) { + talloc_free(sec); + return NULL; + } + + if (getgroups(sec->ngroups, sec->groups) != sec->ngroups) { + talloc_free(sec); + return NULL; + } + + return sec; +} + +/* + set the current security context from a unix_sec_ctx +*/ +static NTSTATUS set_unix_security(struct unix_sec_ctx *sec) +{ + seteuid(0); + + if (setgroups(sec->ngroups, sec->groups) != 0) { + return NT_STATUS_ACCESS_DENIED; + } + if (setegid(sec->gid) != 0) { + return NT_STATUS_ACCESS_DENIED; + } + if (seteuid(sec->uid) != 0) { + return NT_STATUS_ACCESS_DENIED; + } + return NT_STATUS_OK; +} + +/* + form a unix_sec_ctx from the current session info +*/ +static NTSTATUS authinfo_to_unix_security(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + struct auth_serversupplied_info *info, + struct unix_sec_ctx **sec) +{ + int i; + NTSTATUS status; + *sec = talloc_p(req, struct unix_sec_ctx); + + status = sid_to_unixuid(ntvfs, req, info->user_sid, &(*sec)->uid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = sid_to_unixgid(ntvfs, req, info->primary_group_sid, &(*sec)->gid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + (*sec)->ngroups = info->n_domain_groups; + (*sec)->groups = talloc_array_p(*sec, gid_t, (*sec)->ngroups); + if ((*sec)->groups == NULL) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0;i<(*sec)->ngroups;i++) { + status = sid_to_unixgid(ntvfs, req, info->domain_groups[i], &(*sec)->groups[i]); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + return NT_STATUS_OK; +} + +/* + setup our unix security context according to the session authentication info +*/ +static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct unix_sec_ctx **sec) +{ + struct auth_serversupplied_info *info = req->session->session_info->server_info; + void *ctx = talloc(req, 0); + struct unix_sec_ctx *newsec; + NTSTATUS status; + + *sec = save_unix_security(req); + if (*sec == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = authinfo_to_unix_security(ntvfs, req, info, &newsec); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return status; + } + + status = set_unix_security(newsec); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return status; + } + + talloc_free(ctx); + + return NT_STATUS_OK; +} + +/* + this pass through macro operates on request contexts +*/ +#define PASS_THRU_REQ(ntvfs, req, op, args) do { \ + NTSTATUS status2; \ + struct unix_sec_ctx *sec; \ + status = unixuid_setup_security(ntvfs, req, &sec); \ + if (NT_STATUS_IS_OK(status)) status = ntvfs_next_##op args; \ + status2 = set_unix_security(sec); \ + if (!NT_STATUS_IS_OK(status2)) smb_panic("Unable to reset security context"); \ +} while (0) + + + +/* + connect to a share - used when a tree_connect operation comes in. +*/ +static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) +{ + struct unixuid_private *private; + NTSTATUS status; + + private = talloc_p(req->tcon, struct unixuid_private); + if (!private) { + return NT_STATUS_NO_MEMORY; + } + + private->samctx = samdb_connect(private); + if (private->samctx == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + ntvfs->private_data = private; + + PASS_THRU_REQ(ntvfs, req, connect, (ntvfs, req, sharename)); + + return status; +} + +/* + disconnect from a share +*/ +static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) +{ + struct unixuid_private *private = ntvfs->private_data; + NTSTATUS status; + + talloc_free(private); + + status = ntvfs_next_disconnect(ntvfs, tcon); + + return status; +} + + +/* + delete a file +*/ +static NTSTATUS unixuid_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, unlink, (ntvfs, req, unl)); + + return status; +} + +/* + ioctl interface +*/ +static NTSTATUS unixuid_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, ioctl, (ntvfs, req, io)); + + return status; +} + +/* + check if a directory exists +*/ +static NTSTATUS unixuid_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, chkpath, (ntvfs, req, cp)); + + return status; +} + +/* + return info on a pathname +*/ +static NTSTATUS unixuid_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, qpathinfo, (ntvfs, req, info)); + + return status; +} + +/* + query info on a open file +*/ +static NTSTATUS unixuid_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, qfileinfo, (ntvfs, req, info)); + + return status; +} + + +/* + set info on a pathname +*/ +static NTSTATUS unixuid_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, setpathinfo, (ntvfs, req, st)); + + return status; +} + +/* + open a file +*/ +static NTSTATUS unixuid_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, open, (ntvfs, req, io)); + + return status; +} + +/* + create a directory +*/ +static NTSTATUS unixuid_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, mkdir, (ntvfs, req, md)); + + return status; +} + +/* + remove a directory +*/ +static NTSTATUS unixuid_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, rmdir, (ntvfs, req, rd)); + + return status; +} + +/* + rename a set of files +*/ +static NTSTATUS unixuid_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, rename, (ntvfs, req, ren)); + + return status; +} + +/* + copy a set of files +*/ +static NTSTATUS unixuid_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, copy, (ntvfs, req, cp)); + + return status; +} + +/* + read from a file +*/ +static NTSTATUS unixuid_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *rd) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, read, (ntvfs, req, rd)); + + return status; +} + +/* + write to a file +*/ +static NTSTATUS unixuid_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *wr) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, write, (ntvfs, req, wr)); + + return status; +} + +/* + seek in a file +*/ +static NTSTATUS unixuid_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, seek, (ntvfs, req, io)); + + return status; +} + +/* + flush a file +*/ +static NTSTATUS unixuid_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, flush, (ntvfs, req, io)); + + return status; +} + +/* + close a file +*/ +static NTSTATUS unixuid_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, close, (ntvfs, req, io)); + + return status; +} + +/* + exit - closing files +*/ +static NTSTATUS unixuid_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, exit, (ntvfs, req)); + + return status; +} + +/* + logoff - closing files +*/ +static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, logoff, (ntvfs, req)); + + return status; +} + +/* + lock a byte range +*/ +static NTSTATUS unixuid_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, lock, (ntvfs, req, lck)); + + return status; +} + +/* + set info on a open file +*/ +static NTSTATUS unixuid_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + union smb_setfileinfo *info) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, setfileinfo, (ntvfs, req, info)); + + return status; +} + + +/* + return filesystem space info +*/ +static NTSTATUS unixuid_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, fsinfo, (ntvfs, req, fs)); + + return status; +} + +/* + return print queue info +*/ +static NTSTATUS unixuid_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, lpq, (ntvfs, req, lpq)); + + return status; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, search_first, (ntvfs, req, io, search_private, callback)); + + return status; +} + +/* continue a search */ +static NTSTATUS unixuid_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, search_next, (ntvfs, req, io, search_private, callback)); + + return status; +} + +/* close a search */ +static NTSTATUS unixuid_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, search_close, (ntvfs, req, io)); + + return status; +} + +/* SMBtrans - not used on file shares */ +static NTSTATUS unixuid_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, trans, (ntvfs, req, trans2)); + + return status; +} + +/* + initialise the unixuid backend, registering ourselves with the ntvfs subsystem + */ +NTSTATUS ntvfs_unixuid_init(void) +{ + NTSTATUS ret; + struct ntvfs_ops ops; + + ZERO_STRUCT(ops); + + /* fill in the name and type */ + ops.name = "unixuid"; + ops.type = NTVFS_DISK; + + /* fill in all the operations */ + ops.connect = unixuid_connect; + ops.disconnect = unixuid_disconnect; + ops.unlink = unixuid_unlink; + ops.chkpath = unixuid_chkpath; + ops.qpathinfo = unixuid_qpathinfo; + ops.setpathinfo = unixuid_setpathinfo; + ops.open = unixuid_open; + ops.mkdir = unixuid_mkdir; + ops.rmdir = unixuid_rmdir; + ops.rename = unixuid_rename; + ops.copy = unixuid_copy; + ops.ioctl = unixuid_ioctl; + ops.read = unixuid_read; + ops.write = unixuid_write; + ops.seek = unixuid_seek; + ops.flush = unixuid_flush; + ops.close = unixuid_close; + ops.exit = unixuid_exit; + ops.lock = unixuid_lock; + ops.setfileinfo = unixuid_setfileinfo; + ops.qfileinfo = unixuid_qfileinfo; + ops.fsinfo = unixuid_fsinfo; + ops.lpq = unixuid_lpq; + ops.search_first = unixuid_search_first; + ops.search_next = unixuid_search_next; + ops.search_close = unixuid_search_close; + ops.trans = unixuid_trans; + ops.logoff = unixuid_logoff; + + /* register ourselves with the NTVFS subsystem. */ + ret = register_backend("ntvfs", &ops); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register unixuid backend!\n")); + } + + return ret; +} -- cgit From c5722fb81b14bf067c4c97eda2ee01f1640084f7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Oct 2004 07:31:32 +0000 Subject: r2796: - changed ldap attributes "UnixID" to "unixID" and "UnixName" to "unixName" to be more ldap traditional - register the unixuid module as all 3 ntvfs backend types, as it doesn't care what type of backend it filters (This used to be commit cd43def6ce280442306f14ca61508b4f7eb92cb6) --- source4/ntvfs/unixuid/vfs_unixuid.c | 41 +++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 6eef6dbc37..de759f6e5f 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -35,7 +35,7 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct dom_sid *sid, uid_t *uid) { struct unixuid_private *private = ntvfs->private_data; - const char *attrs[] = { "sAMAccountName", "UnixID", "UnixName", "sAMAccountType", NULL }; + const char *attrs[] = { "sAMAccountName", "unixID", "unixName", "sAMAccountType", NULL }; int ret; const char *s; void *ctx; @@ -47,7 +47,7 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, ret = samdb_search(private->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); if (ret != 1) { - DEBUG(2,("Unable to map sid %s to unix uid\n", sidstr)); + DEBUG(0,("sid_to_unixuid: unable to find sam record for sid %s\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; } @@ -60,7 +60,7 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, } /* first try to get the uid directly */ - s = samdb_result_string(res[0], "UnixID", NULL); + s = samdb_result_string(res[0], "unixID", NULL); if (s != NULL) { *uid = strtoul(s, NULL, 0); talloc_free(ctx); @@ -68,11 +68,11 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, } /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "UnixName", NULL); + s = samdb_result_string(res[0], "unixName", NULL); if (s != NULL) { struct passwd *pwd = getpwnam(s); if (!pwd) { - DEBUG(0,("UnixName %s for sid %s does not exist as a local user\n", s, sidstr)); + DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; } @@ -109,7 +109,7 @@ static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct dom_sid *sid, gid_t *gid) { struct unixuid_private *private = ntvfs->private_data; - const char *attrs[] = { "sAMAccountName", "UnixID", "UnixName", "sAMAccountType", NULL }; + const char *attrs[] = { "sAMAccountName", "unixID", "unixName", "sAMAccountType", NULL }; int ret; const char *s; void *ctx; @@ -121,7 +121,7 @@ static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, ret = samdb_search(private->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); if (ret != 1) { - DEBUG(2,("Unable to map sid %s to unix gid\n", sidstr)); + DEBUG(0,("sid_to_unixgid: unable to find sam record for sid %s\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; } @@ -134,7 +134,7 @@ static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, } /* first try to get the gid directly */ - s = samdb_result_string(res[0], "UnixID", NULL); + s = samdb_result_string(res[0], "unixID", NULL); if (s != NULL) { *gid = strtoul(s, NULL, 0); talloc_free(ctx); @@ -142,11 +142,11 @@ static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, } /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "UnixName", NULL); + s = samdb_result_string(res[0], "unixName", NULL); if (s != NULL) { struct group *grp = getgrnam(s); if (!grp) { - DEBUG(0,("UnixName '%s' for sid %s does not exist as a local group\n", s, sidstr)); + DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", s, sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; } @@ -708,10 +708,6 @@ NTSTATUS ntvfs_unixuid_init(void) ZERO_STRUCT(ops); - /* fill in the name and type */ - ops.name = "unixuid"; - ops.type = NTVFS_DISK; - /* fill in all the operations */ ops.connect = unixuid_connect; ops.disconnect = unixuid_disconnect; @@ -742,12 +738,21 @@ NTSTATUS ntvfs_unixuid_init(void) ops.trans = unixuid_trans; ops.logoff = unixuid_logoff; - /* register ourselves with the NTVFS subsystem. */ + ops.name = "unixuid"; + + /* we register under all 3 backend types, as we are not type specific */ + ops.type = NTVFS_DISK; ret = register_backend("ntvfs", &ops); + if (!NT_STATUS_IS_OK(ret)) goto failed; - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register unixuid backend!\n")); - } + ops.type = NTVFS_PRINT; + ret = register_backend("ntvfs", &ops); + if (!NT_STATUS_IS_OK(ret)) goto failed; + + ops.type = NTVFS_IPC; + ret = register_backend("ntvfs", &ops); + if (!NT_STATUS_IS_OK(ret)) goto failed; +failed: return ret; } -- cgit From a56c984df498488f2e99b1fa8ae156a882f82175 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Oct 2004 08:27:56 +0000 Subject: r2800: removed the warning about using the posix ntvfs handler, as it is now considerably more complete than the simple handler (This used to be commit e6ecd31be8e91f552d891c41b2f8737519a490a1) --- source4/ntvfs/posix/vfs_posix.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 44875f1879..1990f77f82 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -58,8 +58,6 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, struct stat st; char *base_directory; - DEBUG(0,("WARNING: the posix vfs handler is incomplete - you probably want \"ntvfs handler = simple\"\n")); - pvfs = talloc_p(tcon, struct pvfs_state); if (pvfs == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From fe3294f7f02c7ed57aab8ea17f0072f721284a8c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Oct 2004 10:25:06 +0000 Subject: r2803: allow unixuid module to work with foreign security principles (This used to be commit f522728728fa523ce7d9e73c93b27e71f3757d50) --- source4/ntvfs/unixuid/vfs_unixuid.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index de759f6e5f..ae29fd7bea 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -41,6 +41,7 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, void *ctx; struct ldb_message **res; const char *sidstr; + uint_t atype; ctx = talloc(req, 0); sidstr = dom_sid_string(ctx, sid); @@ -53,7 +54,8 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, } /* make sure its a user, not a group */ - if (samdb_result_uint(res[0], "sAMAccountType", 0) != ATYPE_NORMAL_ACCOUNT) { + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype && atype != ATYPE_NORMAL_ACCOUNT) { DEBUG(0,("sid_to_unixuid: sid %s is not ATYPE_NORMAL_ACCOUNT\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; @@ -95,7 +97,7 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } - DEBUG(0,("No sAMAccountName for sid %s!?\n", sidstr)); + DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; @@ -115,6 +117,7 @@ static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, void *ctx; struct ldb_message **res; const char *sidstr; + uint_t atype; ctx = talloc(req, 0); sidstr = dom_sid_string(ctx, sid); @@ -127,7 +130,8 @@ static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, } /* make sure its not a user */ - if (samdb_result_uint(res[0], "sAMAccountType", 0) == ATYPE_NORMAL_ACCOUNT) { + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype && atype == ATYPE_NORMAL_ACCOUNT) { DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; @@ -169,7 +173,7 @@ static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } - DEBUG(0,("No sAMAccountName for sid %s!?\n", sidstr)); + DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; -- cgit From 18dc1cd00f09d051497cf89e348f8ba794c63230 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Oct 2004 05:29:59 +0000 Subject: r2893: added very primitive name mangling support to pvfs (This used to be commit 749fa73544201f521d9cd3fa972b89cae99bc2c0) --- source4/ntvfs/posix/pvfs_resolve.c | 16 ++++++++++--- source4/ntvfs/posix/pvfs_shortname.c | 46 +++++++++++++++++++++++++++++++++++- 2 files changed, 58 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index e846b7be77..5d6f270a42 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -33,9 +33,19 @@ /* compare two filename components. This is where the name mangling hook will go */ -static int component_compare(const char *c1, const char *c2) +static int component_compare(struct pvfs_state *pvfs, const char *comp, const char *name) { - return StrCaseCmp(c1, c2); + char *shortname; + int ret; + + if (StrCaseCmp(comp, name) == 0) return 0; + + shortname = pvfs_short_name_component(pvfs, name); + + ret = StrCaseCmp(comp, shortname); + + talloc_free(shortname); + return ret; } /* @@ -110,7 +120,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * } while ((de = readdir(dir))) { - if (component_compare(components[i], de->d_name) == 0) { + if (component_compare(pvfs, components[i], de->d_name) == 0) { break; } } diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 21c0ca6ea0..ae911ad885 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -23,6 +23,34 @@ #include "include/includes.h" #include "vfs_posix.h" +#define FNV1_PRIME 0x01000193 +/*the following number is a fnv1 of the string: idra@samba.org 2002 */ +#define FNV1_INIT 0xa6b93095 + +/* + hash a string of the specified length. The string does not need to be + null terminated + + this hash needs to be fast with a low collision rate (what hash doesn't?) +*/ +static uint32_t mangle_hash(const char *key) +{ + uint32_t value; + codepoint_t c; + size_t c_size; + + for (value = FNV1_INIT; + (c=next_codepoint(key, &c_size)); + key += c_size) { + c = toupper_w(c); + value *= (uint32_t)FNV1_PRIME; + value ^= (uint32_t)c; + } + + /* note that we force it to a 31 bit hash, to keep within the limits + of the 36^6 mangle space */ + return value & ~0x80000000; +} /* return the short name for a component of a full name @@ -30,7 +58,23 @@ */ char *pvfs_short_name_component(struct pvfs_state *pvfs, const char *name) { - return talloc_strndup(pvfs, name, 12); + const char *basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + uint32_t hash; + char c1, c2; + const char *ext; + + if (strlen(name) < 12) { + return talloc_strdup(pvfs, name); + } + + hash = mangle_hash(name); + ext = strrchr(name, '.'); + + c1 = basechars[(hash/36)%36]; + c2 = basechars[hash%36]; + + return talloc_asprintf(pvfs, "%.5s~%c%c%.4s", name, c1, c2, ext?ext:""); + } -- cgit From af3866903e009271533f91470fe7d8819516b09e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Oct 2004 03:27:16 +0000 Subject: r2904: - fixed the old style SMBsearch to return the pvfs shortname, not a truncated long name. - short name can be up to 12 bytes, not 11 (This used to be commit 657103ec6264bf4c2986fedd3fc6577746395d49) --- source4/ntvfs/posix/pvfs_search.c | 7 +++++-- source4/ntvfs/posix/pvfs_shortname.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 211cb68b86..07f2a0f127 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -36,6 +36,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, { struct pvfs_filename *name; NTSTATUS status; + const char *shortname; status = pvfs_resolve_partial(pvfs, file, unix_path, fname, &name); if (!NT_STATUS_IS_OK(status)) { @@ -50,13 +51,15 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, case RAW_SEARCH_SEARCH: case RAW_SEARCH_FFIRST: case RAW_SEARCH_FUNIQUE: + shortname = pvfs_short_name(pvfs, name, name); file->search.attrib = name->dos.attrib; file->search.write_time = nt_time_to_unix(name->dos.write_time); file->search.size = name->st.st_size; - file->search.name = fname; + file->search.name = shortname; file->search.id.reserved = 8; memset(file->search.id.name, ' ', sizeof(file->search.id.name)); - memcpy(file->search.id.name, fname, MIN(strlen(fname)+1, sizeof(file->search.id.name))); + memcpy(file->search.id.name, shortname, + MIN(strlen(shortname)+1, sizeof(file->search.id.name))); file->search.id.handle = search->handle; file->search.id.server_cookie = dir_index+1; file->search.id.client_cookie = 0; diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index ae911ad885..81cf42e71f 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -63,7 +63,7 @@ char *pvfs_short_name_component(struct pvfs_state *pvfs, const char *name) char c1, c2; const char *ext; - if (strlen(name) < 12) { + if (strlen(name) <= 12) { return talloc_strdup(pvfs, name); } -- cgit From 4d69d2d52b273359b481e1a7b99b9db3711d2768 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Oct 2004 14:35:54 +0000 Subject: r2916: longhorn client doesn't bother setting the directory bit in ntcreatex when opening directories. This change allows samba4 server to work with longhorn client. (This used to be commit 4a8b0302eff37ccfcb66b91259ee5da20879c652) --- source4/ntvfs/posix/pvfs_open.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 560d194a34..271bd41429 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -110,7 +110,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, #define O_DIRECTORY 0 #endif - if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { + if ((io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) && + !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { flags = O_RDONLY | O_DIRECTORY; if (pvfs->flags & PVFS_FLAG_READONLY) { goto do_open; -- cgit From c7130b816b29cab981646482e57cb6923ae91b4f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Oct 2004 05:07:33 +0000 Subject: r2926: name->dos.attrib is not valid unless name->exists is true (This used to be commit f85a0b725d3bf67531e6874d4e8558fb050bb66f) --- source4/ntvfs/posix/pvfs_open.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 271bd41429..29e57e5a08 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -110,12 +110,14 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, #define O_DIRECTORY 0 #endif - if ((io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) && + if (name->exists && + (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { return NT_STATUS_NOT_A_DIRECTORY; } - if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if ((name->exists && name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) || + (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { flags = O_RDONLY | O_DIRECTORY; if (pvfs->flags & PVFS_FLAG_READONLY) { goto do_open; -- cgit From 52f525c104ae2d17901f104cbf482395dc803cc1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Oct 2004 05:10:43 +0000 Subject: r2927: imported the hash2 name mangling code from Samba3 into Samba4, but heavily modified to suit the Samba4 architecture. Samba4 with posix backend now passes the BASE-MANGLE test (This used to be commit ed52d69e8a065b6a8df2fb73c89be67acfdbca65) --- source4/ntvfs/posix/pvfs_dirlist.c | 16 +- source4/ntvfs/posix/pvfs_resolve.c | 21 +- source4/ntvfs/posix/pvfs_shortname.c | 661 +++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/vfs_posix.c | 6 + source4/ntvfs/posix/vfs_posix.h | 28 ++ 5 files changed, 693 insertions(+), 39 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 79d9a9a3fa..0482cda808 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -98,21 +98,19 @@ NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct p while ((dent = readdir(odir))) { uint_t i = dir->count; const char *dname = dent->d_name; - char *short_name; - short_name = pvfs_short_name_component(pvfs, dname); - - /* check it matches the wildcard pattern */ if (ms_fnmatch(pattern, dname, - pvfs->tcon->smb_conn->negotiate.protocol) != 0 && - ms_fnmatch(pattern, short_name, pvfs->tcon->smb_conn->negotiate.protocol) != 0) { + char *short_name = pvfs_short_name_component(pvfs, dname); + if (short_name == NULL || + ms_fnmatch(pattern, short_name, + pvfs->tcon->smb_conn->negotiate.protocol) != 0) { + talloc_free(short_name); + continue; + } talloc_free(short_name); - continue; } - talloc_free(short_name); - if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; dir->names = talloc_realloc_p(dir, dir->names, const char *, allocated); diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 5d6f270a42..5b1a5680ae 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -35,16 +35,18 @@ */ static int component_compare(struct pvfs_state *pvfs, const char *comp, const char *name) { - char *shortname; int ret; - if (StrCaseCmp(comp, name) == 0) return 0; + ret = StrCaseCmp(comp, name); - shortname = pvfs_short_name_component(pvfs, name); - - ret = StrCaseCmp(comp, shortname); + if (ret != 0) { + char *shortname = pvfs_short_name_component(pvfs, name); + if (shortname) { + ret = StrCaseCmp(comp, shortname); + talloc_free(shortname); + } + } - talloc_free(shortname); return ret; } @@ -95,6 +97,13 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * char *test_name; DIR *dir; struct dirent *de; + char *long_component; + + /* possibly remap from the short name cache */ + long_component = pvfs_mangled_lookup(pvfs, name, components[i]); + if (long_component) { + components[i] = long_component; + } test_name = talloc_asprintf(name, "%s/%s", partial_name, components[i]); if (!test_name) { diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 81cf42e71f..818c285fbc 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -23,69 +23,682 @@ #include "include/includes.h" #include "vfs_posix.h" +/* + this mangling scheme uses the following format + + Annnn~n.AAA + + where nnnnn is a base 36 hash, and A represents characters from the original string + + The hash is taken of the leading part of the long filename, in uppercase + + for simplicity, we only allow ascii characters in 8.3 names +*/ + + /* hash alghorithm changed to FNV1 by idra@samba.org (Simo Sorce). + * see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a + * discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors + */ + +/* + =============================================================================== + NOTE NOTE NOTE!!! + + This file deliberately uses non-multibyte string functions in many places. This + is *not* a mistake. This code is multi-byte safe, but it gets this property + through some very subtle knowledge of the way multi-byte strings are encoded + and the fact that this mangling algorithm only supports ascii characters in + 8.3 names. + + please don't convert this file to use the *_m() functions!! + =============================================================================== +*/ + + +#include "includes.h" +#include "vfs_posix.h" + +#if 1 +#define M_DEBUG(level, x) DEBUG(level, x) +#else +#define M_DEBUG(level, x) +#endif + +/* these flags are used to mark characters in as having particular + properties */ +#define FLAG_BASECHAR 1 +#define FLAG_ASCII 2 +#define FLAG_ILLEGAL 4 +#define FLAG_WILDCARD 8 + +/* the "possible" flags are used as a fast way to find possible DOS + reserved filenames */ +#define FLAG_POSSIBLE1 16 +#define FLAG_POSSIBLE2 32 +#define FLAG_POSSIBLE3 64 +#define FLAG_POSSIBLE4 128 + +/* by default have a max of 512 entries in the cache. */ +#ifndef MANGLE_CACHE_SIZE +#define MANGLE_CACHE_SIZE 512 +#endif + +#define DEFAULT_MANGLE_PREFIX 4 + #define FNV1_PRIME 0x01000193 /*the following number is a fnv1 of the string: idra@samba.org 2002 */ #define FNV1_INIT 0xa6b93095 +#define MANGLE_BASECHARS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +#define FLAG_CHECK(c, flag) (ctx->char_flags[(uint8_t)(c)] & (flag)) + + /* hash a string of the specified length. The string does not need to be null terminated this hash needs to be fast with a low collision rate (what hash doesn't?) */ -static uint32_t mangle_hash(const char *key) +static uint32_t mangle_hash(struct pvfs_mangle_context *ctx, + const char *key, size_t length) { - uint32_t value; + uint32_t value = FNV1_INIT; codepoint_t c; size_t c_size; - for (value = FNV1_INIT; - (c=next_codepoint(key, &c_size)); - key += c_size) { + while (*key && length--) { + c = next_codepoint(key, &c_size); c = toupper_w(c); value *= (uint32_t)FNV1_PRIME; value ^= (uint32_t)c; + key += c_size; } - /* note that we force it to a 31 bit hash, to keep within the limits - of the 36^6 mangle space */ - return value & ~0x80000000; + return (value % ctx->mangle_modulus); } /* - return the short name for a component of a full name - TODO: this is obviously not very useful in its current form ! + insert an entry into the prefix cache. The string might not be null + terminated */ +static void cache_insert(struct pvfs_mangle_context *ctx, + const char *prefix, int length, uint32_t hash) +{ + int i = hash % MANGLE_CACHE_SIZE; + + if (ctx->prefix_cache[i]) { + talloc_free(ctx->prefix_cache[i]); + } + + ctx->prefix_cache[i] = talloc_strndup(ctx->prefix_cache, prefix, length); + ctx->prefix_cache_hashes[i] = hash; +} + +/* + lookup an entry in the prefix cache. Return NULL if not found. */ -char *pvfs_short_name_component(struct pvfs_state *pvfs, const char *name) +static const char *cache_lookup(struct pvfs_mangle_context *ctx, uint32_t hash) { - const char *basechars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - uint32_t hash; - char c1, c2; - const char *ext; + int i = hash % MANGLE_CACHE_SIZE; + + + if (!ctx->prefix_cache[i] || hash != ctx->prefix_cache_hashes[i]) { + return NULL; + } + + /* yep, it matched */ + return ctx->prefix_cache[i]; +} - if (strlen(name) <= 12) { - return talloc_strdup(pvfs, name); + +/* + determine if a string is possibly in a mangled format, ignoring + case + + In this algorithm, mangled names use only pure ascii characters (no + multi-byte) so we can avoid doing a UCS2 conversion + */ +static BOOL is_mangled_component(struct pvfs_mangle_context *ctx, + const char *name, size_t len) +{ + unsigned int i; + + M_DEBUG(10,("is_mangled_component %s (len %u) ?\n", name, (unsigned int)len)); + + /* check the length */ + if (len > 12 || len < 8) + return False; + + /* the best distinguishing characteristic is the ~ */ + if (name[6] != '~') + return False; + + /* check extension */ + if (len > 8) { + if (name[8] != '.') + return False; + for (i=9; name[i] && i < len; i++) { + if (! FLAG_CHECK(name[i], FLAG_ASCII)) { + return False; + } + } + } + + /* check lead characters */ + for (i=0;imangle_prefix;i++) { + if (! FLAG_CHECK(name[i], FLAG_ASCII)) { + return False; + } + } + + /* check rest of hash */ + if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) { + return False; } + for (i=ctx->mangle_prefix;i<6;i++) { + if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) { + return False; + } + } + + M_DEBUG(10,("is_mangled_component %s (len %u) -> yes\n", name, (unsigned int)len)); + + return True; +} - hash = mangle_hash(name); - ext = strrchr(name, '.'); - c1 = basechars[(hash/36)%36]; - c2 = basechars[hash%36]; - return talloc_asprintf(pvfs, "%.5s~%c%c%.4s", name, c1, c2, ext?ext:""); +/* + determine if a string is possibly in a mangled format, ignoring + case + + In this algorithm, mangled names use only pure ascii characters (no + multi-byte) so we can avoid doing a UCS2 conversion + + NOTE! This interface must be able to handle a path with unix + directory separators. It should return true if any component is + mangled + */ +static BOOL is_mangled(struct pvfs_mangle_context *ctx, const char *name) +{ + const char *p; + const char *s; + + M_DEBUG(10,("is_mangled %s ?\n", name)); + + for (s=name; (p=strchr(s, '/')); s=p+1) { + if (is_mangled_component(ctx, s, PTR_DIFF(p, s))) { + return True; + } + } + /* and the last part ... */ + return is_mangled_component(ctx, s,strlen(s)); +} + + +/* + see if a filename is an allowable 8.3 name. + + we are only going to allow ascii characters in 8.3 names, as this + simplifies things greatly (it means that we know the string won't + get larger when converted from UNIX to DOS formats) +*/ +static BOOL is_8_3(struct pvfs_mangle_context *ctx, + const char *name, BOOL check_case, BOOL allow_wildcards) +{ + int len, i; + char *dot_p; + + /* as a special case, the names '.' and '..' are allowable 8.3 names */ + if (name[0] == '.') { + if (!name[1] || (name[1] == '.' && !name[2])) { + return True; + } + } + + /* the simplest test is on the overall length of the + filename. Note that we deliberately use the ascii string + length (not the multi-byte one) as it is faster, and gives us + the result we need in this case. Using strlen_m would not + only be slower, it would be incorrect */ + len = strlen(name); + if (len > 12) + return False; + + /* find the '.'. Note that once again we use the non-multibyte + function */ + dot_p = strchr(name, '.'); + + if (!dot_p) { + /* if the name doesn't contain a '.' then its length + must be less than 8 */ + if (len > 8) { + return False; + } + } else { + int prefix_len, suffix_len; + + /* if it does contain a dot then the prefix must be <= + 8 and the suffix <= 3 in length */ + prefix_len = PTR_DIFF(dot_p, name); + suffix_len = len - (prefix_len+1); + + if (prefix_len > 8 || suffix_len > 3 || suffix_len == 0) { + return False; + } + + /* a 8.3 name cannot contain more than 1 '.' */ + if (strchr(dot_p+1, '.')) { + return False; + } + } + + /* the length are all OK. Now check to see if the characters themselves are OK */ + for (i=0; name[i]; i++) { + /* note that we may allow wildcard petterns! */ + if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && name[i] != '.') { + return False; + } + } + + /* it is a good 8.3 name */ + return True; +} + + +/* + try to find a 8.3 name in the cache, and if found then + return the original long name. +*/ +static const char *check_cache(struct pvfs_mangle_context *ctx, + const char *name) +{ + uint32_t hash, multiplier; + unsigned int i; + const char *prefix; + char extension[4]; + + /* make sure that this is a mangled name from this cache */ + if (!is_mangled(ctx, name)) { + M_DEBUG(10,("check_cache: %s -> not mangled\n", name)); + return NULL; + } + + /* we need to extract the hash from the 8.3 name */ + hash = ctx->base_reverse[(unsigned char)name[7]]; + for (multiplier=36, i=5;i>=ctx->mangle_prefix;i--) { + uint32_t v = ctx->base_reverse[(unsigned char)name[i]]; + hash += multiplier * v; + multiplier *= 36; + } + + /* now look in the prefix cache for that hash */ + prefix = cache_lookup(ctx, hash); + if (!prefix) { + M_DEBUG(10,("check_cache: %s -> %08X -> not found\n", name, hash)); + return NULL; + } + + /* we found it - construct the full name */ + if (name[8] == '.') { + strncpy(extension, name+9, 3); + extension[3] = 0; + } else { + extension[0] = 0; + } + + if (extension[0]) { + return talloc_asprintf(ctx, "%s.%s", prefix, extension); + } + + return talloc_strdup(ctx, prefix); +} + + +/* + look for a DOS reserved name +*/ +static BOOL is_reserved_name(struct pvfs_mangle_context *ctx, const char *name) +{ + if (FLAG_CHECK(name[0], FLAG_POSSIBLE1) && + FLAG_CHECK(name[1], FLAG_POSSIBLE2) && + FLAG_CHECK(name[2], FLAG_POSSIBLE3) && + FLAG_CHECK(name[3], FLAG_POSSIBLE4)) { + /* a likely match, scan the lot */ + int i; + for (i=0; ctx->reserved_names[i]; i++) { + int len = strlen(ctx->reserved_names[i]); + /* note that we match on COM1 as well as COM1.foo */ + if (strncasecmp(name, ctx->reserved_names[i], len) == 0 && + (name[len] == '.' || name[len] == 0)) { + return True; + } + } + } + + return False; +} + + +/* + See if a filename is a legal long filename. + A filename ending in a '.' is not legal unless it's "." or "..". JRA. +*/ +static BOOL is_legal_name(struct pvfs_mangle_context *ctx, const char *name) +{ + const char *dot_pos = NULL; + BOOL alldots = True; + size_t numdots = 0; + + while (*name) { + size_t c_size; + codepoint_t c = next_codepoint(name, &c_size); + if (c == INVALID_CODEPOINT) { + return False; + } + /* all high chars are OK */ + if (c >= 128) { + name += c_size; + continue; + } + if (FLAG_CHECK(c, FLAG_ILLEGAL)) { + return False; + } + if (name[0] == '.') { + dot_pos = name; + numdots++; + } else { + alldots = False; + } + + name += c_size; + } + + if (dot_pos) { + if (alldots && (numdots == 1 || numdots == 2)) + return True; /* . or .. is a valid name */ + + /* A valid long name cannot end in '.' */ + if (dot_pos[1] == '\0') + return False; + } + + return True; +} + +/* + the main forward mapping function, which converts a long filename to + a 8.3 name + + if need83 is not set then we only do the mangling if the name is illegal + as a long name + + if cache83 is not set then we don't cache the result + + return NULL if we don't need to do any conversion +*/ +static char *name_map(struct pvfs_mangle_context *ctx, + const char *name, BOOL need83, BOOL cache83) +{ + char *dot_p; + char lead_chars[7]; + char extension[4]; + unsigned int extension_length, i; + unsigned int prefix_len; + uint32_t hash, v; + char *new_name; + const char *basechars = MANGLE_BASECHARS; + + /* reserved names are handled specially */ + if (!is_reserved_name(ctx, name)) { + /* if the name is already a valid 8.3 name then we don't need to + do anything */ + if (is_8_3(ctx, name, False, False)) { + return NULL; + } + + /* if the caller doesn't strictly need 8.3 then just check for illegal + filenames */ + if (!need83 && is_legal_name(ctx, name)) { + return NULL; + } + } + + /* find the '.' if any */ + dot_p = strrchr(name, '.'); + + if (dot_p) { + /* if the extension contains any illegal characters or + is too long or zero length then we treat it as part + of the prefix */ + for (i=0; i<4 && dot_p[i+1]; i++) { + if (! FLAG_CHECK(dot_p[i+1], FLAG_ASCII)) { + dot_p = NULL; + break; + } + } + if (i == 0 || i == 4) dot_p = NULL; + } + + /* the leading characters in the mangled name is taken from + the first characters of the name, if they are ascii otherwise + '_' is used + */ + for (i=0;imangle_prefix && name[i];i++) { + lead_chars[i] = name[i]; + if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) { + lead_chars[i] = '_'; + } + lead_chars[i] = toupper(lead_chars[i]); + } + for (;imangle_prefix;i++) { + lead_chars[i] = '_'; + } + + /* the prefix is anything up to the first dot */ + if (dot_p) { + prefix_len = PTR_DIFF(dot_p, name); + } else { + prefix_len = strlen(name); + } + + /* the extension of the mangled name is taken from the first 3 + ascii chars after the dot */ + extension_length = 0; + if (dot_p) { + for (i=1; extension_length < 3 && dot_p[i]; i++) { + char c = dot_p[i]; + if (FLAG_CHECK(c, FLAG_ASCII)) { + extension[extension_length++] = toupper(c); + } + } + } + + /* find the hash for this prefix */ + v = hash = mangle_hash(ctx, name, prefix_len); + + new_name = talloc_array_p(ctx, char, 13); + if (new_name == NULL) { + return NULL; + } + + /* now form the mangled name. */ + for (i=0;imangle_prefix;i++) { + new_name[i] = lead_chars[i]; + } + new_name[7] = basechars[v % 36]; + new_name[6] = '~'; + for (i=5; i>=ctx->mangle_prefix; i--) { + v = v / 36; + new_name[i] = basechars[v % 36]; + } + + /* add the extension */ + if (extension_length) { + new_name[8] = '.'; + memcpy(&new_name[9], extension, extension_length); + new_name[9+extension_length] = 0; + } else { + new_name[8] = 0; + } + + if (cache83) { + /* put it in the cache */ + cache_insert(ctx, name, prefix_len, hash); + } + + M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", + name, hash, new_name, cache83)); + + return new_name; +} + + +/* initialise the flags table + + we allow only a very restricted set of characters as 'ascii' in this + mangling backend. This isn't a significant problem as modern clients + use the 'long' filenames anyway, and those don't have these + restrictions. +*/ +static void init_tables(struct pvfs_mangle_context *ctx) +{ + const char *basechars = MANGLE_BASECHARS; + int i; + /* the list of reserved dos names - all of these are illegal */ + const char *reserved_names[] = + { "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4", + "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL }; + + + ZERO_STRUCT(ctx->char_flags); + + for (i=1;i<128;i++) { + if ((i >= '0' && i <= '9') || + (i >= 'a' && i <= 'z') || + (i >= 'A' && i <= 'Z')) { + ctx->char_flags[i] |= (FLAG_ASCII | FLAG_BASECHAR); + } + if (strchr("_-$~", i)) { + ctx->char_flags[i] |= FLAG_ASCII; + } + + if (strchr("*\\/?<>|\":", i)) { + ctx->char_flags[i] |= FLAG_ILLEGAL; + } + + if (strchr("*?\"<>", i)) { + ctx->char_flags[i] |= FLAG_WILDCARD; + } + } + + ZERO_STRUCT(ctx->base_reverse); + for (i=0;i<36;i++) { + ctx->base_reverse[(uint8_t)basechars[i]] = i; + } + + ctx->reserved_names = reserved_names; + + /* fill in the reserved names flags. These are used as a very + fast filter for finding possible DOS reserved filenames */ + for (i=0; ctx->reserved_names[i]; i++) { + unsigned char c1, c2, c3, c4; + + c1 = (unsigned char)ctx->reserved_names[i][0]; + c2 = (unsigned char)ctx->reserved_names[i][1]; + c3 = (unsigned char)ctx->reserved_names[i][2]; + c4 = (unsigned char)ctx->reserved_names[i][3]; + + ctx->char_flags[c1] |= FLAG_POSSIBLE1; + ctx->char_flags[c2] |= FLAG_POSSIBLE2; + ctx->char_flags[c3] |= FLAG_POSSIBLE3; + ctx->char_flags[c4] |= FLAG_POSSIBLE4; + ctx->char_flags[tolower(c1)] |= FLAG_POSSIBLE1; + ctx->char_flags[tolower(c2)] |= FLAG_POSSIBLE2; + ctx->char_flags[tolower(c3)] |= FLAG_POSSIBLE3; + ctx->char_flags[tolower(c4)] |= FLAG_POSSIBLE4; + + ctx->char_flags[(unsigned char)'.'] |= FLAG_POSSIBLE4; + } + + ctx->mangle_modulus = 1; + for (i=0;i<(7-ctx->mangle_prefix);i++) { + ctx->mangle_modulus *= 36; + } +} + +/* + initialise the mangling code + */ +NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) +{ + struct pvfs_mangle_context *ctx; + + ctx = talloc_p(pvfs, struct pvfs_mangle_context); + if (ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } + ctx->prefix_cache = talloc_array_p(ctx, char *, MANGLE_CACHE_SIZE); + if (ctx->prefix_cache == NULL) { + return NT_STATUS_NO_MEMORY; + } + ctx->prefix_cache_hashes = talloc_array_p(ctx, uint32_t, MANGLE_CACHE_SIZE); + if (ctx->prefix_cache_hashes == NULL) { + return NT_STATUS_NO_MEMORY; + } + + memset(ctx->prefix_cache, 0, sizeof(char *)*MANGLE_CACHE_SIZE); + memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t)*MANGLE_CACHE_SIZE); + + ctx->mangle_prefix = lp_parm_int(-1, "mangle", "prefix"); + if (ctx->mangle_prefix < 0 || ctx->mangle_prefix > 6) { + ctx->mangle_prefix = DEFAULT_MANGLE_PREFIX; + } + + init_tables(ctx); + + pvfs->mangle_ctx = ctx; + + return NT_STATUS_OK; +} + + +/* + return the short name for a component of a full name +*/ +char *pvfs_short_name_component(struct pvfs_state *pvfs, const char *name) +{ + return name_map(pvfs->mangle_ctx, name, True, True); } /* return the short name for a given entry in a directory - TODO: this is obviously not very useful in its current form ! */ -char *pvfs_short_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, struct pvfs_filename *name) +const char *pvfs_short_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + struct pvfs_filename *name) { char *p = strrchr(name->full_name, '/'); char *ret = pvfs_short_name_component(pvfs, p+1); + if (ret == NULL) { + return p+1; + } talloc_steal(mem_ctx, ret); return ret; } + +/* + lookup a mangled name, returning the original long name if present + in the cache +*/ +char *pvfs_mangled_lookup(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + const char *name) +{ + const char *ret; + ret = check_cache(pvfs->mangle_ctx, name); + if (ret) { + return talloc_steal(mem_ctx, ret); + } + return NULL; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 1990f77f82..7d532c3596 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -57,6 +57,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs; struct stat st; char *base_directory; + NTSTATUS status; pvfs = talloc_p(tcon, struct pvfs_state); if (pvfs == NULL) { @@ -84,6 +85,11 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = pvfs; + status = pvfs_mangle_init(pvfs); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + pvfs_setup_options(pvfs); return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 0daacf2c33..f6faf718be 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -49,6 +49,8 @@ struct pvfs_state { } search; struct pvfs_file *open_files; + + struct pvfs_mangle_context *mangle_ctx; }; @@ -115,6 +117,32 @@ struct pvfs_file { uint16_t smbpid; }; +struct pvfs_mangle_context { + uint8_t char_flags[256]; + /* + this determines how many characters are used from the original + filename in the 8.3 mangled name. A larger value leads to a weaker + hash and more collisions. The largest possible value is 6. + */ + int mangle_prefix; + uint32_t mangle_modulus; + + /* we will use a very simple direct mapped prefix cache. The big + advantage of this cache structure is speed and low memory usage + + The cache is indexed by the low-order bits of the hash, and confirmed by + hashing the resulting cache entry to match the known hash + */ + char **prefix_cache; + uint32_t *prefix_cache_hashes; + + /* this is used to reverse the base 36 mapping */ + unsigned char base_reverse[256]; + + const char **reserved_names; +}; + + /* flags to pvfs_resolve_name() */ #define PVFS_RESOLVE_NO_WILDCARD (1<<0) -- cgit From 4962d9d03efd91bf4e7209cff47877f20d7de25d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Oct 2004 05:33:05 +0000 Subject: r2928: - fixed the handling of reserved names (rejecting them with ACCESS_DENIED) - don't check for '.' specially in checking for legal names. Longhorn doesn't do this any more, and its a real pain. Longhorn allows for filenames ending in '.', and with as many '.' elements as you like. (This used to be commit 0a475175c53016bfa5b8246819676ddcd8b66feb) --- source4/ntvfs/posix/pvfs_resolve.c | 3 ++ source4/ntvfs/posix/pvfs_shortname.c | 56 +++++++++++++----------------------- source4/ntvfs/posix/vfs_posix.h | 2 -- 3 files changed, 23 insertions(+), 38 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 5b1a5680ae..01f6b13ec2 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -84,6 +84,9 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * components[i] = p; p = strchr(p, '/'); if (p) *p++ = 0; + if (pvfs_is_reserved_name(pvfs, components[i])) { + return NT_STATUS_ACCESS_DENIED; + } } partial_name = talloc_strdup(name, components[0]); diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 818c285fbc..c3c33fbc98 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -93,6 +93,10 @@ #define FLAG_CHECK(c, flag) (ctx->char_flags[(uint8_t)(c)] & (flag)) +static const char *reserved_names[] = +{ "AUX", "CON", "COM1", "COM2", "COM3", "COM4", + "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL }; + /* hash a string of the specified length. The string does not need to be @@ -367,11 +371,8 @@ static BOOL is_reserved_name(struct pvfs_mangle_context *ctx, const char *name) FLAG_CHECK(name[3], FLAG_POSSIBLE4)) { /* a likely match, scan the lot */ int i; - for (i=0; ctx->reserved_names[i]; i++) { - int len = strlen(ctx->reserved_names[i]); - /* note that we match on COM1 as well as COM1.foo */ - if (strncasecmp(name, ctx->reserved_names[i], len) == 0 && - (name[len] == '.' || name[len] == 0)) { + for (i=0; reserved_names[i]; i++) { + if (strcasecmp(name, reserved_names[i]) == 0) { return True; } } @@ -387,10 +388,6 @@ static BOOL is_reserved_name(struct pvfs_mangle_context *ctx, const char *name) */ static BOOL is_legal_name(struct pvfs_mangle_context *ctx, const char *name) { - const char *dot_pos = NULL; - BOOL alldots = True; - size_t numdots = 0; - while (*name) { size_t c_size; codepoint_t c = next_codepoint(name, &c_size); @@ -405,25 +402,9 @@ static BOOL is_legal_name(struct pvfs_mangle_context *ctx, const char *name) if (FLAG_CHECK(c, FLAG_ILLEGAL)) { return False; } - if (name[0] == '.') { - dot_pos = name; - numdots++; - } else { - alldots = False; - } - name += c_size; } - if (dot_pos) { - if (alldots && (numdots == 1 || numdots == 2)) - return True; /* . or .. is a valid name */ - - /* A valid long name cannot end in '.' */ - if (dot_pos[1] == '\0') - return False; - } - return True; } @@ -567,10 +548,6 @@ static void init_tables(struct pvfs_mangle_context *ctx) const char *basechars = MANGLE_BASECHARS; int i; /* the list of reserved dos names - all of these are illegal */ - const char *reserved_names[] = - { "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4", - "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL }; - ZERO_STRUCT(ctx->char_flags); @@ -598,17 +575,15 @@ static void init_tables(struct pvfs_mangle_context *ctx) ctx->base_reverse[(uint8_t)basechars[i]] = i; } - ctx->reserved_names = reserved_names; - /* fill in the reserved names flags. These are used as a very fast filter for finding possible DOS reserved filenames */ - for (i=0; ctx->reserved_names[i]; i++) { + for (i=0; reserved_names[i]; i++) { unsigned char c1, c2, c3, c4; - c1 = (unsigned char)ctx->reserved_names[i][0]; - c2 = (unsigned char)ctx->reserved_names[i][1]; - c3 = (unsigned char)ctx->reserved_names[i][2]; - c4 = (unsigned char)ctx->reserved_names[i][3]; + c1 = (unsigned char)reserved_names[i][0]; + c2 = (unsigned char)reserved_names[i][1]; + c3 = (unsigned char)reserved_names[i][2]; + c4 = (unsigned char)reserved_names[i][3]; ctx->char_flags[c1] |= FLAG_POSSIBLE1; ctx->char_flags[c2] |= FLAG_POSSIBLE2; @@ -702,3 +677,12 @@ char *pvfs_mangled_lookup(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, } return NULL; } + + +/* + look for a DOS reserved name +*/ +BOOL pvfs_is_reserved_name(struct pvfs_state *pvfs, const char *name) +{ + return is_reserved_name(pvfs->mangle_ctx, name); +} diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index f6faf718be..38e55fd887 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -138,8 +138,6 @@ struct pvfs_mangle_context { /* this is used to reverse the base 36 mapping */ unsigned char base_reverse[256]; - - const char **reserved_names; }; -- cgit From ca23572f700a059970e0d0e08ee4feef972f326f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Oct 2004 05:59:56 +0000 Subject: r2930: added a security context cache to the unixuid module. The module doesn't actually leave us in the requested sec context between requests yet, but it does prevent us from doing the samdb lookup on every packet. This change speeds up the BASE-MANGLE test against Samba4 with 5000 operations from 61 seconds to 16 seconds. For reference, Samba3 takes 27 seconds for the same test (the string and filename handling in Samba4 is much more efficient than Samba3) (This used to be commit da0481ac75a01270897da5aa24dbb2b431928b30) --- source4/ntvfs/unixuid/vfs_unixuid.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index ae29fd7bea..846bd66179 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -25,6 +25,8 @@ struct unixuid_private { void *samctx; + struct unix_sec_ctx *last_sec_ctx; + struct auth_session_info *last_session_info; }; @@ -279,6 +281,7 @@ static NTSTATUS authinfo_to_unix_security(struct ntvfs_module_context *ntvfs, static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct unix_sec_ctx **sec) { + struct unixuid_private *private = ntvfs->private_data; struct auth_serversupplied_info *info = req->session->session_info->server_info; void *ctx = talloc(req, 0); struct unix_sec_ctx *newsec; @@ -289,10 +292,20 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - status = authinfo_to_unix_security(ntvfs, req, info, &newsec); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(ctx); - return status; + if (req->session->session_info == private->last_session_info) { + newsec = private->last_sec_ctx; + } else { + status = authinfo_to_unix_security(ntvfs, req, info, &newsec); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return status; + } + if (private->last_sec_ctx) { + talloc_free(private->last_sec_ctx); + } + private->last_sec_ctx = newsec; + private->last_session_info = req->session->session_info; + talloc_steal(private, newsec); } status = set_unix_security(newsec); @@ -340,6 +353,8 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, } ntvfs->private_data = private; + private->last_sec_ctx = NULL; + private->last_session_info = NULL; PASS_THRU_REQ(ntvfs, req, connect, (ntvfs, req, sharename)); @@ -591,10 +606,13 @@ static NTSTATUS unixuid_exit(struct ntvfs_module_context *ntvfs, static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) { + struct unixuid_private *private = ntvfs->private_data; NTSTATUS status; PASS_THRU_REQ(ntvfs, req, logoff, (ntvfs, req)); + private->last_session_info = NULL; + return status; } -- cgit From 2ec58445cac6152a652024372d367fc23d4770da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Oct 2004 06:07:55 +0000 Subject: r2931: use next_codepoint() to ensure we properly handle multi-byte characters in pvfs_unix_path() (This used to be commit 0acf95d84c51d564f7215d34364c37ca74a2a150) --- source4/ntvfs/posix/pvfs_resolve.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 01f6b13ec2..205e1e283f 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -217,8 +217,10 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, /* now do an in-place conversion of '\' to '/', checking for legal characters */ - for (;*p;p++) { - switch (*p) { + while (*p) { + size_t c_size; + codepoint_t c = next_codepoint(p, &c_size); + switch (c) { case '\\': if (name->has_wildcard) { /* wildcards are only allowed in the last part @@ -251,6 +253,8 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, case '|': return NT_STATUS_ILLEGAL_CHARACTER; } + + p += c_size; } name->full_name = ret; -- cgit From 59d3259171c04f86ea94909493e173fec147d9ae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Oct 2004 11:30:48 +0000 Subject: r2934: - changed the unixuid module to use the nt_user_token instead of the server supplied info structure. - added SID_WORLD and SID_NETWORK to the foreign sids in the provisioning, as these are auto-added to the nt_user_token (why is that done? Andrew?) (This used to be commit 1dff12fba88827660a2647457867bf4ff6bc8d3d) --- source4/ntvfs/unixuid/vfs_unixuid.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 846bd66179..a5934a07fa 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -26,7 +26,7 @@ struct unixuid_private { void *samctx; struct unix_sec_ctx *last_sec_ctx; - struct auth_session_info *last_session_info; + struct nt_user_token *last_token; }; @@ -238,35 +238,40 @@ static NTSTATUS set_unix_security(struct unix_sec_ctx *sec) } /* - form a unix_sec_ctx from the current session info + form a unix_sec_ctx from the current nt_user_token */ -static NTSTATUS authinfo_to_unix_security(struct ntvfs_module_context *ntvfs, +static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, - struct auth_serversupplied_info *info, + struct nt_user_token *token, struct unix_sec_ctx **sec) { int i; NTSTATUS status; *sec = talloc_p(req, struct unix_sec_ctx); - status = sid_to_unixuid(ntvfs, req, info->user_sid, &(*sec)->uid); + /* we can't do unix security without a user and group */ + if (token->num_sids < 2) { + return NT_STATUS_ACCESS_DENIED; + } + + status = sid_to_unixuid(ntvfs, req, token->user_sids[0], &(*sec)->uid); if (!NT_STATUS_IS_OK(status)) { return status; } - status = sid_to_unixgid(ntvfs, req, info->primary_group_sid, &(*sec)->gid); + status = sid_to_unixgid(ntvfs, req, token->user_sids[1], &(*sec)->gid); if (!NT_STATUS_IS_OK(status)) { return status; } - (*sec)->ngroups = info->n_domain_groups; + (*sec)->ngroups = token->num_sids - 2; (*sec)->groups = talloc_array_p(*sec, gid_t, (*sec)->ngroups); if ((*sec)->groups == NULL) { return NT_STATUS_NO_MEMORY; } for (i=0;i<(*sec)->ngroups;i++) { - status = sid_to_unixgid(ntvfs, req, info->domain_groups[i], &(*sec)->groups[i]); + status = sid_to_unixgid(ntvfs, req, token->user_sids[i+2], &(*sec)->groups[i]); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -282,7 +287,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct unix_sec_ctx **sec) { struct unixuid_private *private = ntvfs->private_data; - struct auth_serversupplied_info *info = req->session->session_info->server_info; + struct nt_user_token *token = req->session->session_info->nt_user_token; void *ctx = talloc(req, 0); struct unix_sec_ctx *newsec; NTSTATUS status; @@ -292,10 +297,10 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - if (req->session->session_info == private->last_session_info) { + if (req->session->session_info->nt_user_token == private->last_token) { newsec = private->last_sec_ctx; } else { - status = authinfo_to_unix_security(ntvfs, req, info, &newsec); + status = nt_token_to_unix_security(ntvfs, req, token, &newsec); if (!NT_STATUS_IS_OK(status)) { talloc_free(ctx); return status; @@ -304,7 +309,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, talloc_free(private->last_sec_ctx); } private->last_sec_ctx = newsec; - private->last_session_info = req->session->session_info; + private->last_token = req->session->session_info->nt_user_token; talloc_steal(private, newsec); } @@ -354,7 +359,7 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; private->last_sec_ctx = NULL; - private->last_session_info = NULL; + private->last_token = NULL; PASS_THRU_REQ(ntvfs, req, connect, (ntvfs, req, sharename)); @@ -611,7 +616,7 @@ static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs, PASS_THRU_REQ(ntvfs, req, logoff, (ntvfs, req)); - private->last_session_info = NULL; + private->last_token = NULL; return status; } -- cgit From 2003ab2598e7dc93ceb2afc7f71986e5f27758b8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 12 Oct 2004 22:18:02 +0000 Subject: r2941: added pvfs_flush() implementation to the posix backend (This used to be commit dac00ef3b0d0f8467367d7b6ff77db7b63a042cc) --- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_flush.c | 64 ++++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 11 +------ source4/ntvfs/posix/vfs_posix.h | 1 + 4 files changed, 67 insertions(+), 10 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_flush.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index ad4c754ca7..019288faaa 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -12,6 +12,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_mkdir.o \ ntvfs/posix/pvfs_open.o \ ntvfs/posix/pvfs_read.o \ + ntvfs/posix/pvfs_flush.o \ ntvfs/posix/pvfs_write.o \ ntvfs/posix/pvfs_fsinfo.o \ ntvfs/posix/pvfs_qfileinfo.o \ diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c new file mode 100644 index 0000000000..49eaa74cfb --- /dev/null +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -0,0 +1,64 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - flush + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + flush a single open file +*/ +static void pvfs_flush_file(struct pvfs_state *pvfs, struct pvfs_file *f) +{ + if (pvfs->flags & PVFS_FLAG_STRICT_SYNC) { + fsync(f->fd); + } +} + +/* + flush a fnum +*/ +NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *io) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + + if (io->in.fnum != 0xFFFF) { + f = pvfs_find_fd(pvfs, req, io->in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + pvfs_flush_file(pvfs, f); + return NT_STATUS_OK; + } + + if (!(pvfs->flags & PVFS_FLAG_STRICT_SYNC)) { + return NT_STATUS_OK; + } + + /* they are asking to flush all open files */ + for (f=pvfs->open_files;f;f=f->next) { + pvfs_flush_file(pvfs, f); + } + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 7d532c3596..a17b90e369 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -39,6 +39,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; if (lp_map_system(snum)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; if (lp_readonly(snum)) pvfs->flags |= PVFS_FLAG_READONLY; + if (lp_strict_sync(snum)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); } @@ -160,16 +161,6 @@ static NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } -/* - flush a file -*/ -static NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) -{ - DEBUG(0,("pvfs_flush not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - /* lock a byte range */ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 38e55fd887..6819d01529 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -152,5 +152,6 @@ struct pvfs_mangle_context { #define PVFS_FLAG_MAP_SYSTEM (1<<2) #define PVFS_FLAG_MAP_HIDDEN (1<<3) #define PVFS_FLAG_READONLY (1<<4) +#define PVFS_FLAG_STRICT_SYNC (1<<5) #endif /* _VFS_POSIX_H_ */ -- cgit From 9d9b42b0591a82ef23bfa367941f711bc454cc26 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Oct 2004 05:40:13 +0000 Subject: r2984: fixed the error code for a non-terminal component of a path name not existing (This used to be commit c6a922dbd844c69bbba83c259169655d17e9f87f) --- source4/ntvfs/posix/pvfs_resolve.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 205e1e283f..97068c3d03 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -140,7 +140,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * if (!de) { if (i < num_components-1) { closedir(dir); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + return NT_STATUS_OBJECT_PATH_NOT_FOUND; } } else { components[i] = talloc_strdup(name, de->d_name); @@ -271,7 +271,6 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, PVFS_RESOLVE_NO_WILDCARD = wildcards are considered illegal characters PVFS_RESOLVE_STREAMS = stream names are allowed - TODO: add reserved name checking (for things like LPT1) TODO: ../ collapsing, and outside share checking */ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, -- cgit From fef617c31bd4a8be09449d6bc726c729ae758423 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 02:55:47 +0000 Subject: r3012: added initial support for byte range locking in the posix vfs. This is enough for us to pass locktest, but does not yet support lock timeouts and some of the other esoteric features. (This used to be commit 58a92abd88f190bc60894a68e0528e95ae33fe39) --- source4/ntvfs/common/brlock.c | 418 +++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/config.mk | 4 +- source4/ntvfs/posix/pvfs_lock.c | 151 ++++++++++++++ source4/ntvfs/posix/pvfs_open.c | 19 ++ source4/ntvfs/posix/pvfs_read.c | 9 + source4/ntvfs/posix/pvfs_write.c | 17 ++ source4/ntvfs/posix/vfs_posix.c | 28 ++- source4/ntvfs/posix/vfs_posix.h | 21 +- 8 files changed, 645 insertions(+), 22 deletions(-) create mode 100644 source4/ntvfs/common/brlock.c create mode 100644 source4/ntvfs/posix/pvfs_lock.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c new file mode 100644 index 0000000000..0eb644e943 --- /dev/null +++ b/source4/ntvfs/common/brlock.c @@ -0,0 +1,418 @@ +/* + Unix SMB/CIFS implementation. + + generic byte range locking code + + Copyright (C) Andrew Tridgell 1992-2004 + Copyright (C) Jeremy Allison 1992-2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* This module implements a tdb based byte range locking service, + replacing the fcntl() based byte range locking previously + used. This allows us to provide the same semantics as NT */ + +#include "includes.h" + +struct brl_context { + struct tdb_wrap *w; + servid_t server; + uint16_t tid; +}; + +/* + in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies + a file. For a local posix filesystem this will usually be a combination + of the device and inode numbers of the file, but it can be anything + that uniquely idetifies a file for locking purposes, as long + as it is applied consistently. +*/ + +/* + the lock context contains the elements that define whether one + lock is the same as another lock +*/ +struct lock_context { + servid_t server; + uint16_t smbpid; + uint16_t tid; +}; + +/* The data in brlock records is an unsorted linear array of these + records. It is unnecessary to store the count as tdb provides the + size of the record */ +struct lock_struct { + struct lock_context context; + uint64_t start; + uint64_t size; + uint16_t fnum; + enum brl_type lock_type; +}; + +/* + Open up the brlock.tdb database. Close it down using + talloc_free() +*/ +void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid) +{ + char *path; + struct brl_context *brl; + + brl = talloc_p(mem_ctx, struct brl_context); + if (brl == NULL) { + return NULL; + } + + path = lock_path(brl, "brlock.tdb"); + brl->w = tdb_wrap_open(brl, path, 0, + TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, 0600); + talloc_free(path); + if (brl->w == NULL) { + talloc_free(brl); + return NULL; + } + + brl->server = server; + brl->tid = tid; + + return (void *)brl; +} + + +/* + see if two locking contexts are equal +*/ +static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) +{ + return (ctx1->server == ctx2->server && + ctx1->smbpid == ctx2->smbpid && + ctx1->tid == ctx2->tid); +} + +/* + See if lock2 can be added when lock1 is in place. +*/ +static BOOL brl_conflict(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { + return False; + } + + if (brl_same_context(&lck1->context, &lck2->context) && + lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) { + return False; + } + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) { + return False; + } + + return True; +} + + +/* + Check to see if this lock conflicts, but ignore our own locks on the + same fnum only. +*/ +static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) +{ + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) + return False; + + if (brl_same_context(&lck1->context, &lck2->context) && + lck1->fnum == lck2->fnum) { + return False; + } + + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) + return False; + + return True; +} + + + +/* + Lock a range of bytes. +*/ +NTSTATUS brl_lock(void *brl_ctx, + DATA_BLOB *file_key, + uint16_t smbpid, + uint16_t fnum, + uint64_t start, uint64_t size, + enum brl_type lock_type) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct lock, *locks; + char *tp; + NTSTATUS status; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + + lock.context.smbpid = smbpid; + lock.context.server = brl->server; + lock.context.tid = brl->tid; + lock.start = start; + lock.size = size; + lock.fnum = fnum; + lock.lock_type = lock_type; + + if (dbuf.dptr) { + /* there are existing locks - make sure they don't conflict */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + for (i=0; iw->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + + fail: + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + Unlock a range of bytes. +*/ +NTSTATUS brl_unlock(void *brl_ctx, + DATA_BLOB *file_key, + uint16_t smbpid, + uint16_t fnum, + uint64_t start, uint64_t size) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct *locks; + struct lock_context context; + NTSTATUS status; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_RANGE_NOT_LOCKED; + } + + context.smbpid = smbpid; + context.server = brl->server; + context.tid = brl->tid; + + /* there are existing locks - find a match */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + for (i=0; icontext, &context) && + lock->fnum == fnum && + lock->start == start && + lock->size == size) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + dbuf.dsize -= sizeof(*locks); + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + + /* we didn't find it */ + status = NT_STATUS_RANGE_NOT_LOCKED; + + fail: + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + Test if we are allowed to perform IO on a region of an open file +*/ +NTSTATUS brl_locktest(void *brl_ctx, + DATA_BLOB *file_key, + uint16_t fnum, + uint16 smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct lock, *locks; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (dbuf.dptr == NULL) { + return NT_STATUS_OK; + } + + lock.context.smbpid = smbpid; + lock.context.server = brl->server; + lock.context.tid = brl->tid; + lock.start = start; + lock.size = size; + lock.fnum = fnum; + lock.lock_type = lock_type; + + /* there are existing locks - make sure they don't conflict */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; idata; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + + /* there are existing locks - remove any for this fnum */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; icontext.tid == brl->tid && + lock->context.server == brl->server && + lock->fnum == fnum) { + /* found it - delete it */ + if (count > 1 && i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + i--; + dcount++; + } + } + + status = NT_STATUS_OK; + + if (count == 0) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } else if (dcount != 0) { + dbuf.dsize -= dcount * sizeof(*locks); + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + + return status; +} + diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 019288faaa..8ca5ad7b0b 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -19,6 +19,8 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_setfileinfo.o \ ntvfs/posix/pvfs_rename.o \ ntvfs/posix/pvfs_resolve.o \ - ntvfs/posix/pvfs_shortname.o + ntvfs/posix/pvfs_shortname.o \ + ntvfs/posix/pvfs_lock.o \ + ntvfs/common/brlock.o # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c new file mode 100644 index 0000000000..d7aca9df8b --- /dev/null +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -0,0 +1,151 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - locking + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + + +/* + check if we can perform IO on a range that might be locked +*/ +NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, + struct pvfs_file *f, + uint16_t smbpid, + uint64_t offset, uint64_t count, + enum brl_type rw) +{ + if (!(pvfs->flags & PVFS_FLAG_STRICT_LOCKING)) { + return NT_STATUS_OK; + } + + return brl_locktest(pvfs->brl_context, + &f->locking_key, + f->fnum, + smbpid, + offset, count, rw); +} + +/* + lock or unlock a byte range +*/ +NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + struct smb_lock_entry *locks; + int i; + enum brl_type rw; + + f = pvfs_find_fd(pvfs, req, lck->generic.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + switch (lck->generic.level) { + case RAW_LOCK_LOCK: + return brl_lock(pvfs->brl_context, + &f->locking_key, + req->smbpid, + f->fnum, + lck->lock.in.offset, + lck->lock.in.count, + WRITE_LOCK); + + case RAW_LOCK_UNLOCK: + return brl_unlock(pvfs->brl_context, + &f->locking_key, + req->smbpid, + f->fnum, + lck->lock.in.offset, + lck->lock.in.count); + + case RAW_LOCK_GENERIC: + return NT_STATUS_INVALID_LEVEL; + + case RAW_LOCK_LOCKX: + /* fall through to the most complex case */ + break; + } + + /* now the lockingX case, most common and also most complex */ + + if (lck->lockx.in.mode & LOCKING_ANDX_SHARED_LOCK) { + rw = READ_LOCK; + } else { + rw = WRITE_LOCK; + } + + if (lck->lockx.in.mode & + (LOCKING_ANDX_OPLOCK_RELEASE | + LOCKING_ANDX_CHANGE_LOCKTYPE | + LOCKING_ANDX_CANCEL_LOCK)) { + /* todo: need to add support for these */ + return NT_STATUS_NOT_IMPLEMENTED; + } + + + /* the unlocks happen first */ + locks = lck->lockx.in.locks; + + for (i=0;ilockx.in.ulock_cnt;i++) { + NTSTATUS status; + status = brl_unlock(pvfs->brl_context, + &f->locking_key, + locks[i].pid, + f->fnum, + locks[i].offset, + locks[i].count); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + locks += i; + + for (i=0;ilockx.in.lock_cnt;i++) { + NTSTATUS status; + + status = brl_lock(pvfs->brl_context, + &f->locking_key, + locks[i].pid, + f->fnum, + locks[i].offset, + locks[i].count, + rw); + if (!NT_STATUS_IS_OK(status)) { + /* undo the locks we just did */ + for (i=i-1;i>=0;i--) { + brl_unlock(pvfs->brl_context, + &f->locking_key, + locks[i].pid, + f->fnum, + locks[i].offset, + locks[i].count); + } + return status; + } + } + + return NT_STATUS_OK; +} + diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 29e57e5a08..51526461e0 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -51,6 +51,9 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, static int pvfs_fd_destructor(void *p) { struct pvfs_file *f = p; + + brl_close(f->pvfs->brl_context, &f->locking_key, f->fnum); + if (f->fd != -1) { close(f->fd); f->fd = -1; @@ -71,6 +74,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; struct pvfs_file *f; NTSTATUS status; + struct { + dev_t device; + ino_t inode; + } lock_context; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(req, io, ntvfs); @@ -161,6 +168,13 @@ do_open: f->name = talloc_steal(f, name); f->session = req->session; f->smbpid = req->smbpid; + f->pvfs = pvfs; + + /* we must zero here to take account of padding */ + ZERO_STRUCT(lock_context); + lock_context.device = name->st.st_dev; + lock_context.inode = name->st.st_ino; + f->locking_key = data_blob_talloc(f, &lock_context, sizeof(lock_context)); /* setup a destructor to avoid file descriptor leaks on abnormal termination */ @@ -204,6 +218,11 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } + status = brl_close(pvfs->brl_context, &f->locking_key, f->fnum); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (close(f->fd) != 0) { status = pvfs_map_errno(pvfs, errno); } else { diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index e0c7e0b1f2..24142a81ee 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -32,6 +32,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; ssize_t ret; struct pvfs_file *f; + NTSTATUS status; if (rd->generic.level != RAW_READ_READX) { return NT_STATUS_NOT_SUPPORTED; @@ -43,6 +44,14 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } + status = pvfs_check_lock(pvfs, f, req->smbpid, + rd->readx.in.offset, + rd->readx.in.maxcnt, + READ_LOCK); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + ret = pread(f->fd, rd->readx.out.data, rd->readx.in.maxcnt, diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index a49f4fe947..80a3dae3a7 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -33,6 +33,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; ssize_t ret; struct pvfs_file *f; + NTSTATUS status; switch (wr->generic.level) { case RAW_WRITE_WRITEX: @@ -40,6 +41,14 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, if (!f) { return NT_STATUS_INVALID_HANDLE; } + status = pvfs_check_lock(pvfs, f, req->smbpid, + wr->writex.in.offset, + wr->writex.in.count, + WRITE_LOCK); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + ret = pwrite(f->fd, wr->writex.in.data, wr->writex.in.count, @@ -62,6 +71,14 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, /* a truncate! */ ret = ftruncate(f->fd, wr->write.in.offset); } else { + status = pvfs_check_lock(pvfs, f, req->smbpid, + wr->write.in.offset, + wr->write.in.count, + WRITE_LOCK); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + ret = pwrite(f->fd, wr->write.in.data, wr->write.in.count, diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index a17b90e369..5e7a605c9f 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -35,11 +35,12 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) { int snum = pvfs->tcon->service; - if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; - if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; - if (lp_map_system(snum)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; - if (lp_readonly(snum)) pvfs->flags |= PVFS_FLAG_READONLY; - if (lp_strict_sync(snum)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; + if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; + if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; + if (lp_map_system(snum)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; + if (lp_readonly(snum)) pvfs->flags |= PVFS_FLAG_READONLY; + if (lp_strict_sync(snum)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; + if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); } @@ -86,6 +87,13 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = pvfs; + pvfs->brl_context = brl_init(pvfs, + pvfs->tcon->smb_conn->connection->server_id, + pvfs->tcon->service); + if (pvfs->brl_context == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + status = pvfs_mangle_init(pvfs); if (!NT_STATUS_IS_OK(status)) { return status; @@ -161,16 +169,6 @@ static NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } -/* - lock a byte range -*/ -static NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) -{ - DEBUG(0,("pvfs_lock not implemented\n")); - return NT_STATUS_NOT_IMPLEMENTED; -} - /* set info on a pathname */ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 6819d01529..e83f0479a9 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -51,6 +51,8 @@ struct pvfs_state { struct pvfs_file *open_files; struct pvfs_mangle_context *mangle_ctx; + + void *brl_context; }; @@ -115,6 +117,12 @@ struct pvfs_file { /* we need to remember the client pid that opened the file so SMBexit works */ uint16_t smbpid; + + /* a unique file key to be used for file locking */ + DATA_BLOB locking_key; + + /* we need this hook back to our parent for lock destruction */ + struct pvfs_state *pvfs; }; struct pvfs_mangle_context { @@ -147,11 +155,12 @@ struct pvfs_mangle_context { #define PVFS_RESOLVE_STREAMS (1<<1) /* flags in pvfs->flags */ -#define PVFS_FLAG_CI_FILESYSTEM (1<<0) /* the filesystem is case insensitive */ -#define PVFS_FLAG_MAP_ARCHIVE (1<<1) -#define PVFS_FLAG_MAP_SYSTEM (1<<2) -#define PVFS_FLAG_MAP_HIDDEN (1<<3) -#define PVFS_FLAG_READONLY (1<<4) -#define PVFS_FLAG_STRICT_SYNC (1<<5) +#define PVFS_FLAG_CI_FILESYSTEM (1<<0) /* the filesystem is case insensitive */ +#define PVFS_FLAG_MAP_ARCHIVE (1<<1) +#define PVFS_FLAG_MAP_SYSTEM (1<<2) +#define PVFS_FLAG_MAP_HIDDEN (1<<3) +#define PVFS_FLAG_READONLY (1<<4) +#define PVFS_FLAG_STRICT_SYNC (1<<5) +#define PVFS_FLAG_STRICT_LOCKING (1<<6) #endif /* _VFS_POSIX_H_ */ -- cgit From 53891ed37e32a97380430e6911878f3b94133e01 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 11:37:22 +0000 Subject: r3017: nicer memory handling for event_context_merge() (This used to be commit 1cef44505e5de9b8ae5206522b624082ad2343b2) --- source4/ntvfs/cifs/vfs_cifs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 65a7c7a206..7c4a1d79d6 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -138,7 +138,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, private->transport = private->tree->session->transport; private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); private->tcon = req->tcon; - /*private->ops = ntvfs_backend_byname("cifs", NTVFS_DISK);*/ tcon->fs_type = talloc_strdup(tcon, "NTFS"); tcon->dev_type = talloc_strdup(tcon, "A:"); @@ -151,7 +150,8 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, private->transport->event.fde->private = private; private->transport->event.ctx = event_context_merge(tcon->smb_conn->connection->event.ctx, - private->transport->event.ctx); + private->transport->event.ctx); + talloc_reference(private, private->transport->event.ctx); return NT_STATUS_OK; } -- cgit From e81230df4b99c4cdcb80648809e62aead3e0ec28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 17 Oct 2004 22:03:33 +0000 Subject: r3024: run the *_connect() NTVFS initialisation operation as root, to allow backends to open databases and perform any other privileged operations that might be needed. (This used to be commit 54fd395025656d9b264ba1c1fab6e3ce8ca3d357) --- source4/ntvfs/unixuid/vfs_unixuid.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index a5934a07fa..542b011c67 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -361,7 +361,10 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, private->last_sec_ctx = NULL; private->last_token = NULL; - PASS_THRU_REQ(ntvfs, req, connect, (ntvfs, req, sharename)); + /* we don't use PASS_THRU_REQ here, as the connect operation runs with + root privileges. This allows the backends to setup any database + links they might need during the connect. */ + status = ntvfs_next_connect(ntvfs, req, sharename); return status; } -- cgit From d0cc571e30bf49443ac7d1b1a0b896ee72d7d9a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Oct 2004 07:40:17 +0000 Subject: r3029: implemented byte range lock timeouts. This adds a pvfs_wait_message() routine which uses the new messaging system, event timers and talloc destructors to give a nice generic async event handling system with a easy to use interface. The extensions to pvfs_lock.c are based on calls to pvfs_wait_message() routines. We now pass all of our smbtorture locking tests, although while writing this code I have thought of some additonal tests that should be added, particularly for lock cancel operations. I'll work on that soon. This commit also extends the smbtorture lock tests to test the rather weird 0xEEFFFFFF locking semantics that I have discovered in win2003. Win2003 treats the 0xEEFFFFFF boundary as special, and will give different error codes on either side of it. Locks on both sides are allowed, the only difference is which error code is given when a lock is denied. Anyone like to hazard a guess as to why? It has me stumped. (This used to be commit 4395c0557ab175d6a8dd99df03c266325949ffa5) --- source4/ntvfs/common/brlock.c | 272 +++++++++++++++++++++++++++++++++++----- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_lock.c | 186 ++++++++++++++++++++++++++- source4/ntvfs/posix/pvfs_open.c | 6 +- source4/ntvfs/posix/pvfs_wait.c | 128 +++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 3 +- 6 files changed, 561 insertions(+), 35 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_wait.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 0eb644e943..792ee52ad5 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -27,12 +27,6 @@ #include "includes.h" -struct brl_context { - struct tdb_wrap *w; - servid_t server; - uint16_t tid; -}; - /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies a file. For a local posix filesystem this will usually be a combination @@ -60,13 +54,25 @@ struct lock_struct { uint64_t size; uint16_t fnum; enum brl_type lock_type; + void *notify_ptr; +}; + +struct brl_context { + struct tdb_wrap *w; + servid_t server; + uint16_t tid; + void *messaging_ctx; + struct lock_struct last_lock_failure; }; + /* Open up the brlock.tdb database. Close it down using - talloc_free() + talloc_free(). We need the messaging_ctx to allow for + pending lock notifications. */ -void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid) +void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, + void *messaging_ctx) { char *path; struct brl_context *brl; @@ -88,6 +94,8 @@ void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid) brl->server = server; brl->tid = tid; + brl->messaging_ctx = messaging_ctx; + ZERO_STRUCT(brl->last_lock_failure); return (void *)brl; } @@ -103,12 +111,31 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx ctx1->tid == ctx2->tid); } +/* + see if lck1 and lck2 overlap +*/ +static BOOL brl_overlap(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + if (lck1->start >= (lck2->start + lck2->size) || + lck2->start >= (lck1->start + lck1->size)) { + return False; + } + return True; +} + /* See if lock2 can be added when lock1 is in place. */ static BOOL brl_conflict(struct lock_struct *lck1, struct lock_struct *lck2) { + /* pending locks don't conflict with anything */ + if (lck1->lock_type >= PENDING_READ_LOCK || + lck2->lock_type >= PENDING_READ_LOCK) { + return False; + } + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { return False; } @@ -118,12 +145,7 @@ static BOOL brl_conflict(struct lock_struct *lck1, return False; } - if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) { - return False; - } - - return True; + return brl_overlap(lck1, lck2); } @@ -133,32 +155,68 @@ static BOOL brl_conflict(struct lock_struct *lck1, */ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) { + /* pending locks don't conflict with anything */ + if (lck1->lock_type >= PENDING_READ_LOCK || + lck2->lock_type >= PENDING_READ_LOCK) { + return False; + } + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) return False; + /* + * note that incoming write calls conflict with existing READ + * locks even if the context is the same. JRA. See LOCKTEST7 + * in smbtorture. + */ if (brl_same_context(&lck1->context, &lck2->context) && - lck1->fnum == lck2->fnum) { + lck1->fnum == lck2->fnum && + (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { return False; } - if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) - return False; - - return True; + return brl_overlap(lck1, lck2); } +/* + amazingly enough, w2k3 "remembers" whether the last lock failure + is the same as this one and changes its error code. I wonder if any + app depends on this? +*/ +static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) +{ + if (brl_same_context(&lock->context, &brl->last_lock_failure.context) && + lock->fnum == brl->last_lock_failure.fnum && + lock->start == brl->last_lock_failure.start && + lock->size == brl->last_lock_failure.size) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } + brl->last_lock_failure = *lock; + if (lock->start >= 0xEF000000) { + /* amazing the little things you learn with a test + suite. Locks beyond this offset (as a 64 bit + number!) always generate the conflict error + code. */ + return NT_STATUS_FILE_LOCK_CONFLICT; + } + return NT_STATUS_LOCK_NOT_GRANTED; +} /* - Lock a range of bytes. + Lock a range of bytes. The lock_type can be a PENDING_*_LOCK, in + which case a real lock is first tried, and if that fails then a + pending lock is created. When the pending lock is triggered (by + someone else closing an overlapping lock range) a messaging + notification is sent, identified by the notify_ptr */ NTSTATUS brl_lock(void *brl_ctx, DATA_BLOB *file_key, uint16_t smbpid, uint16_t fnum, uint64_t start, uint64_t size, - enum brl_type lock_type) + enum brl_type lock_type, + void *notify_ptr) { struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; @@ -174,6 +232,20 @@ NTSTATUS brl_lock(void *brl_ctx, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + /* if this is a pending lock, then with the chainlock held we + try to get the real lock. If we succeed then we don't need + to make it pending. This prevents a possible race condition + where the pending lock gets created after the lock that is + preventing the real lock gets removed */ + if (lock_type >= PENDING_READ_LOCK) { + enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); + status = brl_lock(brl_ctx, file_key, smbpid, fnum, start, size, rw, NULL); + if (NT_STATUS_IS_OK(status)) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + dbuf = tdb_fetch(brl->w->tdb, kbuf); lock.context.smbpid = smbpid; @@ -183,6 +255,7 @@ NTSTATUS brl_lock(void *brl_ctx, lock.size = size; lock.fnum = fnum; lock.lock_type = lock_type; + lock.notify_ptr = notify_ptr; if (dbuf.dptr) { /* there are existing locks - make sure they don't conflict */ @@ -190,7 +263,7 @@ NTSTATUS brl_lock(void *brl_ctx, count = dbuf.dsize / sizeof(*locks); for (i=0; iw->tdb, kbuf); + + /* the caller needs to know if the real lock was granted. If + we have reached here then it must be a pending lock that + was granted, so tell them the lock failed */ + if (lock_type >= PENDING_READ_LOCK) { + return brl_lock_failed(brl, &lock); + } + return NT_STATUS_OK; fail: @@ -224,6 +305,57 @@ NTSTATUS brl_lock(void *brl_ctx, } +/* + we are removing a lock that might be holding up a pending lock. Scan for pending + locks that cover this range and if we find any then notify the server that it should + retry the lock +*/ +static void brl_notify_unlock(struct brl_context *brl, + struct lock_struct *locks, int count, + struct lock_struct *removed_lock) +{ + int i, last_notice; + + /* the last_notice logic is to prevent stampeding on a lock + range. It prevents us sending hundreds of notifies on the + same range of bytes. It doesn't prevent all possible + stampedes, but it does prevent the most common problem */ + last_notice = -1; + + for (i=0;i= PENDING_READ_LOCK && + brl_overlap(&locks[i], removed_lock)) { + DATA_BLOB data; + + if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { + continue; + } + last_notice = i; + data.data = (void *)&locks[i].notify_ptr; + data.length = sizeof(void *); + messaging_send(brl->messaging_ctx, locks[i].context.server, MSG_BRL_RETRY, &data); + } + } +} + + +/* + send notifications for all pending locks - the file is being closed by this + user +*/ +static void brl_notify_all(struct brl_context *brl, + struct lock_struct *locks, int count) +{ + int i; + for (i=0;ilock_type >= PENDING_READ_LOCK) { + brl_notify_unlock(brl, locks, count, &locks[i]); + } + } +} + + + /* Unlock a range of bytes. */ @@ -261,15 +393,92 @@ NTSTATUS brl_unlock(void *brl_ctx, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); for (i=0; icontext, &context) && lock->fnum == fnum && lock->start == start && - lock->size == size) { + lock->size == size && + lock->notify_ptr == NULL) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + struct lock_struct removed_lock = *lock; + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + + /* send notifications for any relevant pending locks */ + brl_notify_unlock(brl, locks, count, &removed_lock); + + dbuf.dsize = count * sizeof(*locks); + + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + + /* we didn't find it */ + status = NT_STATUS_RANGE_NOT_LOCKED; + + fail: + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + remove a pending lock. This is called when the caller has either + given up trying to establish a lock or when they have succeeded in + getting it. In either case they no longer need to be notified. +*/ +NTSTATUS brl_remove_pending(void *brl_ctx, + DATA_BLOB *file_key, + void *notify_ptr) +{ + struct brl_context *brl = brl_ctx; + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct *locks; + NTSTATUS status; + + kbuf.dptr = file_key->data; + kbuf.dsize = file_key->length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_RANGE_NOT_LOCKED; + } + + /* there are existing locks - find a match */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; inotify_ptr == notify_ptr && + lock->context.server == brl->server) { /* found it - delete it */ if (count == 1) { if (tdb_delete(brl->w->tdb, kbuf) != 0) { @@ -281,7 +490,8 @@ NTSTATUS brl_unlock(void *brl_ctx, memmove(&locks[i], &locks[i+1], sizeof(*locks)*((count-1) - i)); } - dbuf.dsize -= sizeof(*locks); + count--; + dbuf.dsize = count * sizeof(*locks); if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; goto fail; @@ -404,7 +614,13 @@ NTSTATUS brl_close(void *brl_ctx, status = NT_STATUS_INTERNAL_DB_CORRUPTION; } } else if (dcount != 0) { - dbuf.dsize -= dcount * sizeof(*locks); + /* tell all pending lock holders for this file that + they have a chance now. This is a bit indiscriminant, + but works OK */ + brl_notify_all(brl, locks, count); + + dbuf.dsize = count * sizeof(*locks); + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { status = NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 8ca5ad7b0b..b6ba073a99 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -21,6 +21,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_resolve.o \ ntvfs/posix/pvfs_shortname.o \ ntvfs/posix/pvfs_lock.o \ + ntvfs/posix/pvfs_wait.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index d7aca9df8b..548c5bd82c 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -44,6 +44,153 @@ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, offset, count, rw); } +/* this state structure holds information about a lock we are waiting on */ +struct pending_state { + struct pvfs_state *pvfs; + union smb_lock *lck; + struct pvfs_file *f; + struct smbsrv_request *req; + int pending_lock; + void *wait_handle; + time_t end_time; +}; + + +/* + a secondary attempt to setup a lock has failed - back out + the locks we did get and send an error +*/ +static void pvfs_lock_async_failed(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_file *f, + struct smb_lock_entry *locks, + int i, + NTSTATUS status) +{ + /* undo the locks we just did */ + for (i=i-1;i>=0;i--) { + brl_unlock(pvfs->brl_context, + &f->locking_key, + locks[i].pid, + f->fnum, + locks[i].offset, + locks[i].count); + } + req->async.status = status; + req->async.send_fn(req); +} + + +/* + called when we receive a pending lock notification. It means that + either our lock timed out or somoene else has unlocked a overlapping + range, so we should try the lock again. Note that on timeout we + do retry the lock, giving it a last chance. +*/ +static void pvfs_pending_lock_continue(void *private, BOOL timed_out) +{ + struct pending_state *pending = private; + struct pvfs_state *pvfs = pending->pvfs; + struct pvfs_file *f = pending->f; + struct smbsrv_request *req = pending->req; + union smb_lock *lck = pending->lck; + struct smb_lock_entry *locks; + enum brl_type rw; + NTSTATUS status; + int i; + + locks = lck->lockx.in.locks + lck->lockx.in.ulock_cnt; + + if (lck->lockx.in.mode & LOCKING_ANDX_SHARED_LOCK) { + rw = READ_LOCK; + } else { + rw = WRITE_LOCK; + } + + status = brl_lock(pvfs->brl_context, + &f->locking_key, + req->smbpid, + f->fnum, + locks[pending->pending_lock].offset, + locks[pending->pending_lock].count, + rw, NULL); + + /* if we have failed and timed out, or succeeded, then we + don't need the pending lock any more */ + if (NT_STATUS_IS_OK(status) || timed_out) { + NTSTATUS status2; + status2 = brl_remove_pending(pvfs->brl_context, &f->locking_key, pending); + if (!NT_STATUS_IS_OK(status2)) { + DEBUG(0,("pvfs_lock: failed to remove pending lock - %s\n", nt_errstr(status2))); + } + talloc_free(pending->wait_handle); + } + + if (!NT_STATUS_IS_OK(status)) { + if (timed_out) { + /* no more chances */ + pvfs_lock_async_failed(pvfs, req, f, locks, pending->pending_lock, status); + } + /* we can try again */ + return; + } + + /* if we haven't timed out yet, then we can do more pending locks */ + if (timed_out) { + pending = NULL; + } else { + if (rw == READ_LOCK) { + rw = PENDING_READ_LOCK; + } else { + rw = PENDING_WRITE_LOCK; + } + } + + /* we've now got the pending lock. try and get the rest, which might + lead to more pending locks */ + for (i=pending->pending_lock;ilockx.in.lock_cnt;i++) { + if (pending) { + pending->pending_lock = i; + } + + status = brl_lock(pvfs->brl_context, + &f->locking_key, + req->smbpid, + f->fnum, + locks[i].offset, + locks[i].count, + rw, pending); + if (!NT_STATUS_IS_OK(status)) { + if (pending) { + /* a timed lock failed - setup a wait message to handle + the pending lock notification or a timeout */ + pending->wait_handle = pvfs_wait_message(pvfs, req, MSG_BRL_RETRY, + pending->end_time, + pvfs_pending_lock_continue, + pending); + if (pending->wait_handle == NULL) { + pvfs_lock_async_failed(pvfs, req, f, locks, i, NT_STATUS_NO_MEMORY); + } + return; + } + pvfs_lock_async_failed(pvfs, req, f, locks, i, status); + return; + } + } + + brl_unlock(pvfs->brl_context, + &f->locking_key, + req->smbpid, + f->fnum, + lck->lock.in.offset, + lck->lock.in.count); + + /* we've managed to get all the locks. Tell the client */ + req->async.status = NT_STATUS_OK; + req->async.send_fn(req); +} + + /* lock or unlock a byte range */ @@ -55,6 +202,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, struct smb_lock_entry *locks; int i; enum brl_type rw; + struct pending_state *pending = NULL; f = pvfs_find_fd(pvfs, req, lck->generic.in.fnum); if (!f) { @@ -69,7 +217,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, f->fnum, lck->lock.in.offset, lck->lock.in.count, - WRITE_LOCK); + WRITE_LOCK, NULL); case RAW_LOCK_UNLOCK: return brl_unlock(pvfs->brl_context, @@ -88,11 +236,25 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } /* now the lockingX case, most common and also most complex */ + if (lck->lockx.in.timeout != 0) { + pending = talloc_p(req, struct pending_state); + if (pending == NULL) { + return NT_STATUS_NO_MEMORY; + } + + pending->pvfs = pvfs; + pending->lck = lck; + pending->f = f; + pending->req = req; + + /* round up to the nearest second */ + pending->end_time = time(NULL) + ((lck->lockx.in.timeout+999)/1000); + } if (lck->lockx.in.mode & LOCKING_ANDX_SHARED_LOCK) { - rw = READ_LOCK; + rw = pending? PENDING_READ_LOCK : READ_LOCK; } else { - rw = WRITE_LOCK; + rw = pending? PENDING_WRITE_LOCK : WRITE_LOCK; } if (lck->lockx.in.mode & @@ -125,14 +287,30 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, for (i=0;ilockx.in.lock_cnt;i++) { NTSTATUS status; + if (pending) { + pending->pending_lock = i; + } + status = brl_lock(pvfs->brl_context, &f->locking_key, locks[i].pid, f->fnum, locks[i].offset, locks[i].count, - rw); + rw, pending); if (!NT_STATUS_IS_OK(status)) { + if (pending) { + /* a timed lock failed - setup a wait message to handle + the pending lock notification or a timeout */ + pending->wait_handle = pvfs_wait_message(pvfs, req, MSG_BRL_RETRY, + pending->end_time, + pvfs_pending_lock_continue, + pending); + if (pending->wait_handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; + } /* undo the locks we just did */ for (i=i-1;i>=0;i--) { brl_unlock(pvfs->brl_context, diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 51526461e0..5798aa782f 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -96,9 +96,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, flags = O_CREAT | O_TRUNC; break; case NTCREATEX_DISP_OPEN: - case NTCREATEX_DISP_OVERWRITE: flags = 0; break; + case NTCREATEX_DISP_OVERWRITE: + flags = O_TRUNC; + break; case NTCREATEX_DISP_CREATE: flags = O_CREAT | O_EXCL; break; @@ -222,7 +224,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, if (!NT_STATUS_IS_OK(status)) { return status; } - + if (close(f->fd) != 0) { status = pvfs_map_errno(pvfs, errno); } else { diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c new file mode 100644 index 0000000000..1d6da6aaf8 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -0,0 +1,128 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - async request wait routines + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* the context for a single wait instance */ +struct pvfs_wait { + void (*handler)(void *, BOOL); + void *private; + struct timed_event *te; + int msg_type; + void *msg_ctx; + struct event_context *ev; +}; + + +/* + receive a completion message for a wait +*/ +static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, + servid_t src, DATA_BLOB *data) +{ + struct pvfs_wait *pwait = private; + + /* we need to check that this one is for us. This sender sends + the private pointer as the body of the message. This might + seem a little unusual, but as the pointer is guaranteed + unique for this server, it is a good token */ + if (data->length != sizeof(void *) || + *(void **)data->data != pwait->private) { + return; + } + + pwait->handler(pwait->private, False); +} + + +/* + receive a timeout on a message wait +*/ +static void pvfs_wait_timeout(struct event_context *ev, struct timed_event *te, time_t t) +{ + struct pvfs_wait *pwait = te->private; + pwait->handler(pwait->private, True); +} + + +/* + destroy a pending wait + */ +static int pvfs_wait_destructor(void *ptr) +{ + struct pvfs_wait *pwait = ptr; + messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait->private); + event_remove_timed(pwait->ev, pwait->te); + return 0; +} + +/* + setup a request to wait on a message of type msg_type, with a + timeout (given as an expiry time) + + the return value is a handle. To stop waiting talloc_free this + handle. +*/ +void *pvfs_wait_message(struct pvfs_state *pvfs, + struct smbsrv_request *req, + int msg_type, + time_t end_time, + void (*fn)(void *, BOOL), + void *private) +{ + struct timed_event te; + struct pvfs_wait *pwait; + + pwait = talloc_p(req, struct pvfs_wait); + if (pwait == NULL) { + return NULL; + } + + pwait->private = private; + pwait->handler = fn; + pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging_ctx; + pwait->ev = req->tcon->smb_conn->connection->event.ctx; + pwait->msg_type = msg_type; + + /* setup a timer */ + te.next_event = end_time; + te.handler = pvfs_wait_timeout; + te.private = pwait; + pwait->te = event_add_timed(pwait->ev, &te); + + /* register with the messaging subsystem for this message + type */ + messaging_register(pwait->msg_ctx, + pwait, + msg_type, + pvfs_wait_dispatch); + + /* tell the main smb server layer that we will be replying + asynchronously */ + req->control_flags |= REQ_CONTROL_ASYNC; + + /* make sure we cleanup the timer and message handler */ + talloc_set_destructor(pwait, pvfs_wait_destructor); + + return pwait; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 5e7a605c9f..6e6c8b4275 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -89,7 +89,8 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->brl_context = brl_init(pvfs, pvfs->tcon->smb_conn->connection->server_id, - pvfs->tcon->service); + pvfs->tcon->service, + pvfs->tcon->smb_conn->connection->messaging_ctx); if (pvfs->brl_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From 43a80e1d83dad9450014b2a7e0ad5a5e495f69ce Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Oct 2004 09:16:55 +0000 Subject: r3031: added support for lock cancelation, which effectively just triggers an early lock timeout added support for more of the bizarre special lock offset semantics of w2k3 (This used to be commit d5bfc910b1200fb283e26572dc57fcf93652fd32) --- source4/ntvfs/common/brlock.c | 19 +++++++++---- source4/ntvfs/posix/pvfs_lock.c | 59 ++++++++++++++++++++++++++++++++++++----- source4/ntvfs/posix/pvfs_open.c | 1 + source4/ntvfs/posix/vfs_posix.h | 4 +++ 4 files changed, 72 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 792ee52ad5..2da32891fb 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -117,8 +117,16 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx static BOOL brl_overlap(struct lock_struct *lck1, struct lock_struct *lck2) { - if (lck1->start >= (lck2->start + lck2->size) || - lck2->start >= (lck1->start + lck1->size)) { + /* this extra check is not redundent - it copes with locks + that go beyond the end of 64 bit file space */ + if (lck1->size != 0 && + lck1->start == lck2->start && + lck1->size == lck2->size) { + return True; + } + + if (lck1->start >= (lck2->start+lck2->size) || + lck2->start >= (lck1->start+lck1->size)) { return False; } return True; @@ -193,11 +201,12 @@ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *loc return NT_STATUS_FILE_LOCK_CONFLICT; } brl->last_lock_failure = *lock; - if (lock->start >= 0xEF000000) { + if (lock->start >= 0xEF000000 && + (lock->start >> 63) == 0) { /* amazing the little things you learn with a test suite. Locks beyond this offset (as a 64 bit - number!) always generate the conflict error - code. */ + number!) always generate the conflict error code, + unless the top bit is set */ return NT_STATUS_FILE_LOCK_CONFLICT; } return NT_STATUS_LOCK_NOT_GRANTED; diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 548c5bd82c..100fc50e55 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -45,7 +45,8 @@ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, } /* this state structure holds information about a lock we are waiting on */ -struct pending_state { +struct pvfs_pending_lock { + struct pvfs_pending_lock *next, *prev; struct pvfs_state *pvfs; union smb_lock *lck; struct pvfs_file *f; @@ -55,7 +56,6 @@ struct pending_state { time_t end_time; }; - /* a secondary attempt to setup a lock has failed - back out the locks we did get and send an error @@ -89,7 +89,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, */ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) { - struct pending_state *pending = private; + struct pvfs_pending_lock *pending = private; struct pvfs_state *pvfs = pending->pvfs; struct pvfs_file *f = pending->f; struct smbsrv_request *req = pending->req; @@ -107,6 +107,8 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) rw = WRITE_LOCK; } + DLIST_REMOVE(f->pending_list, pending); + status = brl_lock(pvfs->brl_context, &f->locking_key, req->smbpid, @@ -130,8 +132,10 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) if (timed_out) { /* no more chances */ pvfs_lock_async_failed(pvfs, req, f, locks, pending->pending_lock, status); + } else { + /* we can try again */ + DLIST_ADD(f->pending_list, pending); } - /* we can try again */ return; } @@ -170,6 +174,8 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) pending); if (pending->wait_handle == NULL) { pvfs_lock_async_failed(pvfs, req, f, locks, i, NT_STATUS_NO_MEMORY); + } else { + DLIST_ADD(f->pending_list, pending); } return; } @@ -191,6 +197,42 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) } +/* + cancel a set of locks +*/ +static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct smbsrv_request *req, union smb_lock *lck, + struct pvfs_file *f) +{ + struct pvfs_pending_lock *p; + + for (p=f->pending_list;p;p=p->next) { + /* check if the lock request matches exactly - you can only cancel with exact matches */ + if (p->lck->lockx.in.ulock_cnt == lck->lockx.in.ulock_cnt && + p->lck->lockx.in.lock_cnt == lck->lockx.in.lock_cnt && + p->lck->lockx.in.fnum == lck->lockx.in.fnum && + p->lck->lockx.in.mode == (lck->lockx.in.mode & ~LOCKING_ANDX_CANCEL_LOCK)) { + int i; + + for (i=0;ilockx.in.ulock_cnt + lck->lockx.in.lock_cnt;i++) { + if (p->lck->lockx.in.locks[i].pid != lck->lockx.in.locks[i].pid || + p->lck->lockx.in.locks[i].offset != lck->lockx.in.locks[i].offset || + p->lck->lockx.in.locks[i].count != lck->lockx.in.locks[i].count) { + break; + } + } + if (i < lck->lockx.in.ulock_cnt) continue; + + /* an exact match! we can cancel it, which is equivalent + to triggering the timeout early */ + pvfs_pending_lock_continue(p ,True); + return NT_STATUS_OK; + } + } + + return NT_STATUS_UNSUCCESSFUL; +} + + /* lock or unlock a byte range */ @@ -202,7 +244,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, struct smb_lock_entry *locks; int i; enum brl_type rw; - struct pending_state *pending = NULL; + struct pvfs_pending_lock *pending = NULL; f = pvfs_find_fd(pvfs, req, lck->generic.in.fnum); if (!f) { @@ -237,7 +279,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, /* now the lockingX case, most common and also most complex */ if (lck->lockx.in.timeout != 0) { - pending = talloc_p(req, struct pending_state); + pending = talloc_p(req, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; } @@ -257,6 +299,10 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, rw = pending? PENDING_WRITE_LOCK : WRITE_LOCK; } + if (lck->lockx.in.mode & LOCKING_ANDX_CANCEL_LOCK) { + return pvfs_lock_cancel(pvfs, req, lck, f); + } + if (lck->lockx.in.mode & (LOCKING_ANDX_OPLOCK_RELEASE | LOCKING_ANDX_CHANGE_LOCKTYPE | @@ -309,6 +355,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, if (pending->wait_handle == NULL) { return NT_STATUS_NO_MEMORY; } + DLIST_ADD(f->pending_list, pending); return NT_STATUS_OK; } /* undo the locks we just did */ diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5798aa782f..05c2bdda28 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -171,6 +171,7 @@ do_open: f->session = req->session; f->smbpid = req->smbpid; f->pvfs = pvfs; + f->pending_list = NULL; /* we must zero here to take account of padding */ ZERO_STRUCT(lock_context); diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index e83f0479a9..6aaa43a213 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -123,8 +123,12 @@ struct pvfs_file { /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; + + /* a list of pending locks - used for locking cancel operations */ + struct pvfs_pending_lock *pending_list; }; + struct pvfs_mangle_context { uint8_t char_flags[256]; /* -- cgit From 384f87bd38c1133c90e2a57775f139532574e3cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Oct 2004 11:47:13 +0000 Subject: r3034: - fixed a bug in message dispatch, when the dispatch function called messaging_deregister() - added a pvfs_lock_close_pending() hook to remove pending locks on file close - fixed the private ptr argument to messaging_deregister() in pvfs_wait - fixed a bug in continuing lock requests after a lock that is blocking a pending lock is removed - removed bogus brl_unlock() call in lock continue - corrected error code for LOCKING_ANDX_CHANGE_LOCKTYPE - expanded the lock cancel test suite to test lock cancel by unlock and by close - added a testsuite for LOCKING_ANDX_CHANGE_LOCKTYPE (This used to be commit 5ef80f034d4aa4dd6810532c63ad041bfc019cb8) --- source4/ntvfs/posix/pvfs_lock.c | 46 +++++++++++++++++++++++++++++------------ source4/ntvfs/posix/pvfs_open.c | 4 ++++ source4/ntvfs/posix/pvfs_wait.c | 2 +- 3 files changed, 38 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 100fc50e55..ead1371ebc 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -152,7 +152,7 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) /* we've now got the pending lock. try and get the rest, which might lead to more pending locks */ - for (i=pending->pending_lock;ilockx.in.lock_cnt;i++) { + for (i=pending->pending_lock+1;ilockx.in.lock_cnt;i++) { if (pending) { pending->pending_lock = i; } @@ -184,19 +184,36 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) } } - brl_unlock(pvfs->brl_context, - &f->locking_key, - req->smbpid, - f->fnum, - lck->lock.in.offset, - lck->lock.in.count); - /* we've managed to get all the locks. Tell the client */ req->async.status = NT_STATUS_OK; req->async.send_fn(req); } +/* + called when we close a file that might have pending locks +*/ +void pvfs_lock_close_pending(struct pvfs_state *pvfs, struct pvfs_file *f) +{ + struct pvfs_pending_lock *p, *next; + NTSTATUS status; + + for (p=f->pending_list;p;p=next) { + next = p->next; + DLIST_REMOVE(f->pending_list, p); + status = brl_remove_pending(pvfs->brl_context, &f->locking_key, p); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("pvfs_lock_close_pending: failed to remove pending lock - %s\n", + nt_errstr(status))); + } + talloc_free(p->wait_handle); + p->req->async.status = NT_STATUS_RANGE_NOT_LOCKED; + p->req->async.send_fn(p->req); + } + +} + + /* cancel a set of locks */ @@ -303,11 +320,14 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return pvfs_lock_cancel(pvfs, req, lck, f); } - if (lck->lockx.in.mode & - (LOCKING_ANDX_OPLOCK_RELEASE | - LOCKING_ANDX_CHANGE_LOCKTYPE | - LOCKING_ANDX_CANCEL_LOCK)) { - /* todo: need to add support for these */ + if (lck->lockx.in.mode & LOCKING_ANDX_CHANGE_LOCKTYPE) { + /* this seems to not be supported by any windows server, + or used by any clients */ + return NT_STATUS_UNSUCCESSFUL; + } + + if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) { + DEBUG(0,("received unexpected oplock break\n")); return NT_STATUS_NOT_IMPLEMENTED; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 05c2bdda28..429f519bca 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -52,6 +52,8 @@ static int pvfs_fd_destructor(void *p) { struct pvfs_file *f = p; + pvfs_lock_close_pending(f->pvfs, f); + brl_close(f->pvfs->brl_context, &f->locking_key, f->fnum); if (f->fd != -1) { @@ -221,6 +223,8 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } + pvfs_lock_close_pending(pvfs, f); + status = brl_close(pvfs->brl_context, &f->locking_key, f->fnum); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 1d6da6aaf8..5815b8edde 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -71,7 +71,7 @@ static void pvfs_wait_timeout(struct event_context *ev, struct timed_event *te, static int pvfs_wait_destructor(void *ptr) { struct pvfs_wait *pwait = ptr; - messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait->private); + messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); event_remove_timed(pwait->ev, pwait->te); return 0; } -- cgit From 8e8c6aef3c99931cdfe8d0bf8ca74616e0960014 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Oct 2004 12:06:21 +0000 Subject: r3035: if the ntvfs layers prior to us have said that we can't perform an operation asynchronously (such as the nbench module), then ignore lock timeouts, as they would make no sense (This used to be commit 2894dd0ac0ddd0ae5b4d536d5cff0690bbfab1a0) --- source4/ntvfs/posix/pvfs_lock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index ead1371ebc..e32fcb2e3a 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -295,7 +295,8 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } /* now the lockingX case, most common and also most complex */ - if (lck->lockx.in.timeout != 0) { + if (lck->lockx.in.timeout != 0 && + req->async.send_fn) { pending = talloc_p(req, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From 142d295aa8e70477c85d1835f2907f81c4c3c519 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Oct 2004 13:27:22 +0000 Subject: r3039: This solves the problem of async handlers in ntvfs backends not being in the right state when called. For example, when we use the unixuid handler in the chain of handlers, and a backend decides to continue a call asynchronously then we need to ensure that the continuation happens with the right security context. The solution is to add a new ntvfs operation ntvfs_async_setup(), which calls all the way down through the layers, setting up anything that is required, and takes a private pointer. The backend wanting to make a async calls can use ntvfs_async_setup() to ensure that the modules above it are called when doing async processing. (This used to be commit a256e71029727fa1659ade6257085df537308c7d) --- source4/ntvfs/cifs/vfs_cifs.c | 11 +++++++++++ source4/ntvfs/ipc/vfs_ipc.c | 11 +++++++++++ source4/ntvfs/nbench/vfs_nbench.c | 11 +++++++++++ source4/ntvfs/ntvfs.h | 6 +++++- source4/ntvfs/ntvfs_interface.c | 22 ++++++++++++++++++++++ source4/ntvfs/posix/pvfs_wait.c | 36 +++++++++++++++++++++++++++++++++--- source4/ntvfs/posix/vfs_posix.c | 1 + source4/ntvfs/simple/vfs_simple.c | 11 +++++++++++ source4/ntvfs/unixuid/vfs_unixuid.c | 15 +++++++++++++++ 9 files changed, 120 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 7c4a1d79d6..5b10e72411 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -563,6 +563,16 @@ static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + setup for an async call - nothing to do yet +*/ +static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + /* lock a byte range */ @@ -748,6 +758,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.search_close = cvfs_search_close; ops.trans = cvfs_trans; ops.logoff = cvfs_logoff; + ops.async_setup = cvfs_async_setup; if (lp_parm_bool(-1, "cifs", "maptrans2", False)) { ops.trans2 = cvfs_trans2; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 69fed6f86f..b37b3e917d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -571,6 +571,16 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + setup for an async call +*/ +static NTSTATUS ipc_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + /* lock a byte range */ @@ -795,6 +805,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.search_close = ipc_search_close; ops.trans = ipc_trans; ops.logoff = ipc_logoff; + ops.async_setup = ipc_async_setup; /* register ourselves with the NTVFS subsystem. */ ret = register_backend("ntvfs", &ops); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 06c237afb5..6203c21506 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -489,6 +489,16 @@ static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, return status; } +/* + async setup +*/ +static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + /* lock a byte range */ @@ -695,6 +705,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.search_close = nbench_search_close; ops.trans = nbench_trans; ops.logoff = nbench_logoff; + ops.async_setup = nbench_async_setup; /* we don't register a trans2 handler as we want to be able to log individual trans2 requests */ diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index bee10e3c38..c9fe276f54 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -112,7 +112,11 @@ struct ntvfs_ops { /* logoff - called when a vuid is closed */ NTSTATUS (*logoff)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req); + struct smbsrv_request *req); + + /* async_setup - called when a backend is processing a async request */ + NTSTATUS (*async_setup)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, void *private); }; struct ntvfs_module_context { diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 06cda11000..7ba1c0d6be 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -293,6 +293,17 @@ NTSTATUS ntvfs_logoff(struct smbsrv_request *req) return ntvfs->ops->logoff(ntvfs, req); } +/* async setup - called by a backend that wants to setup any state for + a async request */ +NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->async_setup) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->async_setup(ntvfs, req, private); +} + /* initial setup */ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) @@ -564,3 +575,14 @@ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, } return ntvfs->next->ops->logoff(ntvfs->next, req); } + +/* async_setup - called when setting up for a async request */ +NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + if (!ntvfs->next || !ntvfs->next->ops->async_setup) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->async_setup(ntvfs->next, req, private); +} diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 5815b8edde..2a4a1d286b 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -31,8 +31,22 @@ struct pvfs_wait { int msg_type; void *msg_ctx; struct event_context *ev; + struct smbsrv_request *req; + BOOL timed_out; }; +/* + called from the ntvfs layer when we have requested setup of an async + call. this ensures that async calls runs with the right state of + previous ntvfs handlers in the chain (such as security context) +*/ +NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, void *private) +{ + struct pvfs_wait *pwait = private; + pwait->handler(pwait->private, pwait->timed_out); + return NT_STATUS_OK; +} /* receive a completion message for a wait @@ -41,6 +55,7 @@ static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, servid_t src, DATA_BLOB *data) { struct pvfs_wait *pwait = private; + struct smbsrv_request *req; /* we need to check that this one is for us. This sender sends the private pointer as the body of the message. This might @@ -50,8 +65,16 @@ static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, *(void **)data->data != pwait->private) { return; } - - pwait->handler(pwait->private, False); + pwait->timed_out = False; + req = pwait->req; + + /* the extra reference here is to ensure that the req + structure is not destroyed when the async request reply is + sent, which would cause problems with the other ntvfs + modules above us */ + talloc_increase_ref_count(req); + ntvfs_async_setup(pwait->req, pwait); + talloc_free(req); } @@ -61,7 +84,13 @@ static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, static void pvfs_wait_timeout(struct event_context *ev, struct timed_event *te, time_t t) { struct pvfs_wait *pwait = te->private; - pwait->handler(pwait->private, True); + struct smbsrv_request *req = pwait->req; + + pwait->timed_out = True; + + talloc_increase_ref_count(req); + ntvfs_async_setup(pwait->req, pwait); + talloc_free(req); } @@ -103,6 +132,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging_ctx; pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; + pwait->req = req; /* setup a timer */ te.next_event = end_time; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 6e6c8b4275..e989f8de67 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -237,6 +237,7 @@ NTSTATUS ntvfs_posix_init(void) ops.search_close = pvfs_search_close; ops.trans = pvfs_trans; ops.logoff = pvfs_logoff; + ops.async_setup = pvfs_async_setup; /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 7f5d447a09..7ebc040608 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -622,6 +622,16 @@ static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } +/* + setup for an async call +*/ +static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + return NT_STATUS_OK; +} + /* lock a byte range */ @@ -999,6 +1009,7 @@ NTSTATUS ntvfs_simple_init(void) ops.search_close = svfs_search_close; ops.trans = svfs_trans; ops.logoff = svfs_logoff; + ops.async_setup = svfs_async_setup; /* register ourselves with the NTVFS subsystem. We register under names 'simple' diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 542b011c67..d0060bf11d 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -624,6 +624,20 @@ static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs, return status; } +/* + async setup +*/ +static NTSTATUS unixuid_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, async_setup, (ntvfs, req, private)); + + return status; +} + /* lock a byte range */ @@ -767,6 +781,7 @@ NTSTATUS ntvfs_unixuid_init(void) ops.search_close = unixuid_search_close; ops.trans = unixuid_trans; ops.logoff = unixuid_logoff; + ops.async_setup = unixuid_async_setup; ops.name = "unixuid"; -- cgit From 31403d548e95ee6047009b78ed72e7144ece199a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Oct 2004 15:18:05 +0000 Subject: r3043: Use binding strings for specifying endpoints. The property for specifying a endpoint is now also 'endpoint' instead of 'endpoints'. The default endpoint (if none is specified) is still "ncacn_np:[\\pipe\\ifacename]", where ifacename is the name of the interface. Examples: [ uuid(60a15ec5-4de8-11d7-a637-005056a20182), endpoint("ncacn_np:[\\pipe\\rpcecho]", "ncacn_ip_tcp:") ] interface rpcecho { void dummy(); } dcerpc_binding is now converted to ep_description in the server, but I hope to completely eliminate ep_description later on. The eventual goal of all these changes is to make it easier to add transports as I'm going to add support for ncalrpc (local RPC over named pipes) and ncacn_unix_stream (Unix sockets). (This used to be commit f3da7c8b443a29b0c656c687a277384ae1353792) --- source4/ntvfs/ipc/vfs_ipc.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b37b3e917d..8c32a78512 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -227,9 +227,6 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } - while (p->pipe_name[0] == '\\') { - p->pipe_name++; - } p->ipc_state = 0x5ff; /* @@ -310,8 +307,6 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - fname += 4; - status = ipc_open_generic(ntvfs, req, fname, &p); if (!NT_STATUS_IS_OK(status)) { return status; -- cgit From 2c081d2c47452acff3115637bbd16f780e23b76a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Oct 2004 16:07:08 +0000 Subject: r3046: \\PIPE\\ is internal (not actually included on the wire) (This used to be commit 7771b5d8fa3db759487474eb7172df45bb3221ae) --- source4/ntvfs/ipc/vfs_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 8c32a78512..238467a746 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -215,7 +215,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - p->pipe_name = talloc_strdup(p, fname); + p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); if (!p->pipe_name) { talloc_free(p); return NT_STATUS_NO_MEMORY; -- cgit From 06fe5d6cd92bbf87f80c3df305d136760d0f91d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Oct 2004 16:25:36 +0000 Subject: r3047: Always include a \ again before the pipe name we're opening. Without a backslash works, but is not like Windows does it. (This used to be commit f6deb3d065e1a88f92bcb8a4a138453650c97b0b) --- source4/ntvfs/ipc/vfs_ipc.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 238467a746..760cf07100 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -215,6 +215,8 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } + while (fname[0] == '\\') fname++; + p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); if (!p->pipe_name) { talloc_free(p); @@ -240,6 +242,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, finalised for Samba4 */ + printf("FINDING: %s\n", p->pipe_name); ep_description.type = ENDPOINT_SMB; ep_description.info.smb_pipe = p->pipe_name; @@ -303,10 +306,6 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, NTSTATUS status; const char *fname = oi->openx.in.fname; - if (strncasecmp(fname, "PIPE\\", 5) != 0) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - status = ipc_open_generic(ntvfs, req, fname, &p); if (!NT_STATUS_IS_OK(status)) { return status; -- cgit From 2b8aa720f47804f783679388f40a9345eff897b9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Oct 2004 06:32:26 +0000 Subject: r3055: use talloc_zero_p() (This used to be commit 7bea9afeed219efa51aa8268af96f782f23f2400) --- source4/ntvfs/simple/vfs_simple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 7ebc040608..f72d557b58 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -799,7 +799,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } - search = talloc_zero(private, sizeof(struct search_state)); + search = talloc_zero_p(private, struct search_state); if (!search) { return NT_STATUS_NO_MEMORY; } -- cgit From cf1b85348a0fc5bf4788291109c9dca9e95eb9c2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Oct 2004 06:39:51 +0000 Subject: r3056: added a id -> pointer data structure (a type of radix tree). This is an extremely efficient way of mapping from an integer handle (such as an open file handle) to a pointer (such as the structure containing the open file information). The code is taken from lib/idr.c in the 2.6 Linux kernel, and is very fast and space efficient. By using talloc it even has auto cleanup. This commit converts the handling of open file handles and open directory search handles to use the idtree routines. In combination with talloc destructors, this simplifies the structure handling in the pvfs backend a lot. For example, we no longer need to keep a linked list of open directory searches at all, and we no longer need to do linear scans of the list of open files on most operations. The end result is that the pvfs code is now extremely scalable. You can have 10s of thousands of open files and open searches and the code still runs very fast. I have also added a small optimisation into the file close path, to avoid looking in the byte range locking database if we know that there are no locks outstanding. (This used to be commit 16835a0ef91a16fa01145b773aad8d43da215dbf) --- source4/ntvfs/common/idtree.c | 360 ++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_lock.c | 64 ++++--- source4/ntvfs/posix/pvfs_open.c | 63 +++---- source4/ntvfs/posix/pvfs_search.c | 93 ++++------ source4/ntvfs/posix/vfs_posix.c | 15 +- source4/ntvfs/posix/vfs_posix.h | 28 ++- 7 files changed, 494 insertions(+), 130 deletions(-) create mode 100644 source4/ntvfs/common/idtree.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/idtree.c b/source4/ntvfs/common/idtree.c new file mode 100644 index 0000000000..80f7df97a0 --- /dev/null +++ b/source4/ntvfs/common/idtree.c @@ -0,0 +1,360 @@ +/* + Unix SMB/CIFS implementation. + + very efficient functions to manage mapping a id (such as a fnum) to + a pointer. This is used for fnum and search id allocation. + + Copyright (C) Andrew Tridgell 2004 + + This code is derived from lib/idr.c in the 2.6 Linux kernel, which was + written by Jim Houston jim.houston@ccur.com, and is + Copyright (C) 2002 by Concurrent Computer Corporation + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + see the section marked "public interface" below for documentation +*/ + +#include "includes.h" + +#define IDR_BITS 5 +#define IDR_FULL 0xfffffffful +#define TOP_LEVEL_FULL (IDR_FULL >> 30) +#define IDR_SIZE (1 << IDR_BITS) +#define IDR_MASK ((1 << IDR_BITS)-1) +#define MAX_ID_SHIFT (sizeof(int)*8 - 1) +#define MAX_ID_BIT (1U << MAX_ID_SHIFT) +#define MAX_ID_MASK (MAX_ID_BIT - 1) +#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS +#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL + +#define set_bit(bit, v) (v) |= (1<<(bit)) +#define clear_bit(bit, v) (v) &= ~(1<<(bit)) + +struct idr_layer { + uint32_t bitmap; + struct idr_layer *ary[IDR_SIZE]; + int count; +}; + +struct idr { + struct idr_layer *top; + struct idr_layer *id_free; + int layers; + int id_free_cnt; +}; + +static struct idr_layer *alloc_layer(struct idr *idp) +{ + struct idr_layer *p; + + if (!(p = idp->id_free)) + return NULL; + idp->id_free = p->ary[0]; + idp->id_free_cnt--; + p->ary[0] = NULL; + return p; +} + +static int find_next_bit(uint32_t bm, int maxid, int n) +{ + while (nary[0] = idp->id_free; + idp->id_free = p; + idp->id_free_cnt++; +} + +static int idr_pre_get(struct idr *idp) +{ + while (idp->id_free_cnt < IDR_FREE_MAX) { + struct idr_layer *new = talloc_zero_p(idp, struct idr_layer); + if(new == NULL) + return (0); + free_layer(idp, new); + } + return 1; +} + +static int sub_alloc(struct idr *idp, void *ptr, int *starting_id) +{ + int n, m, sh; + struct idr_layer *p, *new; + struct idr_layer *pa[MAX_LEVEL]; + int l, id; + uint32_t bm; + + id = *starting_id; + p = idp->top; + l = idp->layers; + pa[l--] = NULL; + while (1) { + /* + * We run around this while until we reach the leaf node... + */ + n = (id >> (IDR_BITS*l)) & IDR_MASK; + bm = ~p->bitmap; + m = find_next_bit(bm, IDR_SIZE, n); + if (m == IDR_SIZE) { + /* no space available go back to previous layer. */ + l++; + id = (id | ((1 << (IDR_BITS*l))-1)) + 1; + if (!(p = pa[l])) { + *starting_id = id; + return -2; + } + continue; + } + if (m != n) { + sh = IDR_BITS*l; + id = ((id >> sh) ^ n ^ m) << sh; + } + if ((id >= MAX_ID_BIT) || (id < 0)) + return -1; + if (l == 0) + break; + /* + * Create the layer below if it is missing. + */ + if (!p->ary[m]) { + if (!(new = alloc_layer(idp))) + return -1; + p->ary[m] = new; + p->count++; + } + pa[l--] = p; + p = p->ary[m]; + } + /* + * We have reached the leaf node, plant the + * users pointer and return the raw id. + */ + p->ary[m] = (struct idr_layer *)ptr; + set_bit(m, p->bitmap); + p->count++; + /* + * If this layer is full mark the bit in the layer above + * to show that this part of the radix tree is full. + * This may complete the layer above and require walking + * up the radix tree. + */ + n = id; + while (p->bitmap == IDR_FULL) { + if (!(p = pa[++l])) + break; + n = n >> IDR_BITS; + set_bit((n & IDR_MASK), p->bitmap); + } + return(id); +} + +static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) +{ + struct idr_layer *p, *new; + int layers, v, id; + + idr_pre_get(idp); + + id = starting_id; +build_up: + p = idp->top; + layers = idp->layers; + if (!p) { + if (!(p = alloc_layer(idp))) + return -1; + layers = 1; + } + /* + * Add a new layer to the top of the tree if the requested + * id is larger than the currently allocated space. + */ + while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) { + layers++; + if (!p->count) + continue; + if (!(new = alloc_layer(idp))) { + /* + * The allocation failed. If we built part of + * the structure tear it down. + */ + for (new = p; p && p != idp->top; new = p) { + p = p->ary[0]; + new->ary[0] = NULL; + new->bitmap = new->count = 0; + free_layer(idp, new); + } + return -1; + } + new->ary[0] = p; + new->count = 1; + if (p->bitmap == IDR_FULL) + set_bit(0, new->bitmap); + p = new; + } + idp->top = p; + idp->layers = layers; + v = sub_alloc(idp, ptr, &id); + if (v == -2) + goto build_up; + return(v); +} + +static void sub_remove(struct idr *idp, int shift, int id) +{ + struct idr_layer *p = idp->top; + struct idr_layer **pa[MAX_LEVEL]; + struct idr_layer ***paa = &pa[0]; + + *paa = NULL; + *++paa = &idp->top; + + while ((shift > 0) && p) { + int n = (id >> shift) & IDR_MASK; + clear_bit(n, p->bitmap); + *++paa = &p->ary[n]; + p = p->ary[n]; + shift -= IDR_BITS; + } + if (p != NULL) { + int n = id & IDR_MASK; + clear_bit(n, p->bitmap); + p->ary[n] = NULL; + while(*paa && ! --((**paa)->count)){ + free_layer(idp, **paa); + **paa-- = NULL; + } + if ( ! *paa ) + idp->layers = 0; + } +} + +static void *_idr_find(struct idr *idp, int id) +{ + int n; + struct idr_layer *p; + + n = idp->layers * IDR_BITS; + p = idp->top; + /* + * This tests to see if bits outside the current tree are + * present. If so, tain't one of ours! + */ + if ((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS)) + return NULL; + + /* Mask off upper bits we don't use for the search. */ + id &= MAX_ID_MASK; + + while (n > 0 && p) { + n -= IDR_BITS; + p = p->ary[(id >> n) & IDR_MASK]; + } + return((void *)p); +} + +static void _idr_remove(struct idr *idp, int id) +{ + struct idr_layer *p; + + if (_idr_find(idp, id) == NULL) { + DEBUG(0,("WARNING: attempt to remove non-existant id %d in idtree\n", + id)); + return; + } + + /* Mask off upper bits we don't use for the search. */ + id &= MAX_ID_MASK; + + sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); + if ( idp->top && idp->top->count == 1 && + (idp->layers > 1) && + idp->top->ary[0]) { + /* We can drop a layer */ + p = idp->top->ary[0]; + idp->top->bitmap = idp->top->count = 0; + free_layer(idp, idp->top); + idp->top = p; + --idp->layers; + } + while (idp->id_free_cnt >= IDR_FREE_MAX) { + p = alloc_layer(idp); + talloc_free(p); + return; + } +} + +/************************************************************************ + this is the public interface +**************************************************************************/ + +/* + initialise a idr tree. The context return value must be passed to + all subsequent idr calls. To destroy the idr tree use talloc_free() + on this context + */ +void *idr_init(TALLOC_CTX *mem_ctx) +{ + return talloc_zero_p(mem_ctx, struct idr); +} + +/* + allocate the next available id, and assign 'ptr' into its slot. + you can retrieve later this pointer using idr_find() +*/ +int idr_get_new(void *idp, void *ptr, int limit) +{ + int ret = idr_get_new_above_int((struct idr *)idp, ptr, 0); + if (ret >= limit) { + idr_remove(idp, ret); + return -1; + } + return ret; +} + +/* + allocate a new id, giving the first available value greater than or + equal to the given starting id +*/ +int idr_get_new_above(void *idp, void *ptr, int starting_id, int limit) +{ + int ret = idr_get_new_above_int((struct idr *)idp, ptr, starting_id); + if (ret >= limit) { + idr_remove(idp, ret); + return -1; + } + return ret; +} + +/* + find a pointer value previously set with idr_get_new given an id +*/ +void *idr_find(void *idp, int id) +{ + return _idr_find((struct idr *)idp, id); +} + +/* + remove an id from the idr tree +*/ +void idr_remove(void *idp, int id) +{ + return _idr_remove((struct idr *)idp, id); +} diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index b6ba073a99..732e896d2b 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -22,6 +22,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_shortname.o \ ntvfs/posix/pvfs_lock.o \ ntvfs/posix/pvfs_wait.o \ + ntvfs/common/idtree.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index e32fcb2e3a..f52e68eeb1 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -75,6 +75,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, f->fnum, locks[i].offset, locks[i].count); + f->lock_count--; } req->async.status = status; req->async.send_fn(req); @@ -117,6 +118,10 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) locks[pending->pending_lock].count, rw, NULL); + if (NT_STATUS_IS_OK(status)) { + f->lock_count++; + } + /* if we have failed and timed out, or succeeded, then we don't need the pending lock any more */ if (NT_STATUS_IS_OK(status) || timed_out) { @@ -182,6 +187,8 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) pvfs_lock_async_failed(pvfs, req, f, locks, i, status); return; } + + f->lock_count++; } /* we've managed to get all the locks. Tell the client */ @@ -191,26 +198,28 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) /* - called when we close a file that might have pending locks + called when we close a file that might have locks */ -void pvfs_lock_close_pending(struct pvfs_state *pvfs, struct pvfs_file *f) +void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) { struct pvfs_pending_lock *p, *next; - NTSTATUS status; + if (f->lock_count || f->pending_list) { + DEBUG(5,("pvfs_lock: removing %.0f locks on close\n", + (double)f->lock_count)); + brl_close(f->pvfs->brl_context, &f->locking_key, f->fnum); + f->lock_count = 0; + } + + /* reply to all the pending lock requests, telling them the + lock failed */ for (p=f->pending_list;p;p=next) { next = p->next; DLIST_REMOVE(f->pending_list, p); - status = brl_remove_pending(pvfs->brl_context, &f->locking_key, p); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("pvfs_lock_close_pending: failed to remove pending lock - %s\n", - nt_errstr(status))); - } talloc_free(p->wait_handle); p->req->async.status = NT_STATUS_RANGE_NOT_LOCKED; p->req->async.send_fn(p->req); } - } @@ -262,6 +271,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, int i; enum brl_type rw; struct pvfs_pending_lock *pending = NULL; + NTSTATUS status; f = pvfs_find_fd(pvfs, req, lck->generic.in.fnum); if (!f) { @@ -270,21 +280,29 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, switch (lck->generic.level) { case RAW_LOCK_LOCK: - return brl_lock(pvfs->brl_context, - &f->locking_key, - req->smbpid, - f->fnum, - lck->lock.in.offset, - lck->lock.in.count, - WRITE_LOCK, NULL); - - case RAW_LOCK_UNLOCK: - return brl_unlock(pvfs->brl_context, + status = brl_lock(pvfs->brl_context, &f->locking_key, req->smbpid, f->fnum, lck->lock.in.offset, - lck->lock.in.count); + lck->lock.in.count, + WRITE_LOCK, NULL); + if (NT_STATUS_IS_OK(status)) { + f->lock_count++; + } + return status; + + case RAW_LOCK_UNLOCK: + status = brl_unlock(pvfs->brl_context, + &f->locking_key, + req->smbpid, + f->fnum, + lck->lock.in.offset, + lck->lock.in.count); + if (NT_STATUS_IS_OK(status)) { + f->lock_count--; + } + return status; case RAW_LOCK_GENERIC: return NT_STATUS_INVALID_LEVEL; @@ -337,7 +355,6 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, locks = lck->lockx.in.locks; for (i=0;ilockx.in.ulock_cnt;i++) { - NTSTATUS status; status = brl_unlock(pvfs->brl_context, &f->locking_key, locks[i].pid, @@ -347,13 +364,12 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, if (!NT_STATUS_IS_OK(status)) { return status; } + f->lock_count--; } locks += i; for (i=0;ilockx.in.lock_cnt;i++) { - NTSTATUS status; - if (pending) { pending->pending_lock = i; } @@ -387,9 +403,11 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, f->fnum, locks[i].offset, locks[i].count); + f->lock_count--; } return status; } + f->lock_count++; } return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 429f519bca..c255558369 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -31,16 +31,19 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, struct smbsrv_request *req, uint16_t fnum) { 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; - } + + f = idr_find(pvfs->idtree_fnum, fnum); + if (f == NULL) { + return NULL; } - return NULL; + + if (req->session != f->session) { + DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n", + fnum)); + return NULL; + } + + return f; } /* @@ -52,14 +55,15 @@ static int pvfs_fd_destructor(void *p) { struct pvfs_file *f = p; - pvfs_lock_close_pending(f->pvfs, f); - - brl_close(f->pvfs->brl_context, &f->locking_key, f->fnum); + pvfs_lock_close(f->pvfs, f); if (f->fd != -1) { close(f->fd); f->fd = -1; } + + idr_remove(f->pvfs->idtree_fnum, f->fnum); + return 0; } @@ -80,6 +84,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, dev_t device; ino_t inode; } lock_context; + int fnum; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(req, io, ntvfs); @@ -147,6 +152,17 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } } + f = talloc_p(pvfs, struct pvfs_file); + if (f == NULL) { + return NT_STATUS_NO_MEMORY; + } + + fnum = idr_get_new(pvfs->idtree_fnum, f, 0x10000); + if (fnum == -1) { + talloc_free(f); + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + do_open: fd = open(name->full_name, flags, 0644); if (fd == -1) { @@ -155,25 +171,20 @@ do_open: return pvfs_map_errno(pvfs,errno); } - f = talloc_p(pvfs, struct pvfs_file); - if (f == NULL) { - close(fd); - return NT_STATUS_NO_MEMORY; - } - /* re-resolve the open fd */ status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { return status; } - f->fnum = fd; + f->fnum = fnum; f->fd = fd; f->name = talloc_steal(f, name); f->session = req->session; f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; + f->lock_count = 0; /* we must zero here to take account of padding */ ZERO_STRUCT(lock_context); @@ -223,22 +234,16 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - pvfs_lock_close_pending(pvfs, f); - - status = brl_close(pvfs->brl_context, &f->locking_key, f->fnum); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if (close(f->fd) != 0) { status = pvfs_map_errno(pvfs, errno); } else { status = NT_STATUS_OK; } - - talloc_set_destructor(f, NULL); + f->fd = -1; DLIST_REMOVE(pvfs->open_files, f); + + /* the destructor takes care of the rest */ talloc_free(f); return status; @@ -257,7 +262,6 @@ NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, 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); } @@ -279,7 +283,6 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, 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); } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 07f2a0f127..7b0da321d3 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -23,6 +23,17 @@ #include "include/includes.h" #include "vfs_posix.h" + +/* + destroy an open search +*/ +static int pvfs_search_destructor(void *ptr) +{ + struct pvfs_search_state *search = ptr; + idr_remove(search->pvfs->idtree_search, search->handle); + return 0; +} + /* fill in a single search result for a given info level */ @@ -224,32 +235,6 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -/* - return the next available search handle -*/ -static NTSTATUS pvfs_next_search_handle(struct pvfs_state *pvfs, uint16_t *handle, - uint_t max_handles) -{ - struct pvfs_search_state *search; - - if (pvfs->search.num_active_searches >= max_handles) { - return NT_STATUS_INSUFFICIENT_RESOURCES; - } - - (*handle) = (pvfs->search.next_search_handle) & (max_handles-1); -again: - for (search=pvfs->search.open_searches;search;search=search->next) { - if (*handle == search->handle) { - *handle = ((*handle)+1) & (max_handles-1); - goto again; - } - } - pvfs->search.next_search_handle = ((*handle)+1) & (max_handles-1); - - return NT_STATUS_OK; -} - - /* list files in a directory matching a wildcard pattern - old SMBsearch interface */ @@ -266,6 +251,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, const char *pattern; NTSTATUS status; struct pvfs_filename *name; + int id; search_attrib = io->search_first.in.search_attrib; pattern = io->search_first.in.pattern; @@ -301,15 +287,19 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, /* we need to give a handle back to the client so it can continue a search */ - status = pvfs_next_search_handle(pvfs, &search->handle, 0x100); - if (!NT_STATUS_IS_OK(status)) { - return status; + id = idr_get_new(pvfs->idtree_search, search, 0x100); + if (id == -1) { + return NT_STATUS_INSUFFICIENT_RESOURCES; } - + + search->pvfs = pvfs; + search->handle = id; search->dir = dir; search->current_index = 0; search->search_attrib = search_attrib; + talloc_set_destructor(search, pvfs_search_destructor); + status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { @@ -323,9 +313,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, return STATUS_NO_MORE_FILES; } - pvfs->search.num_active_searches++; talloc_steal(pvfs, search); - DLIST_ADD(pvfs->search.open_searches, search); return NT_STATUS_OK; } @@ -346,11 +334,8 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, handle = io->search_next.in.id.handle; max_count = io->search_next.in.max_count; - for (search=pvfs->search.open_searches; search; search = search->next) { - if (search->handle == handle) break; - } - - if (!search) { + search = idr_find(pvfs->idtree_search, handle); + if (search == NULL) { /* we didn't find the search handle */ return NT_STATUS_INVALID_HANDLE; } @@ -369,7 +354,6 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, /* not matching any entries means end of search */ if (reply_count == 0) { - DLIST_REMOVE(pvfs->search.open_searches, search); talloc_free(search); } @@ -392,6 +376,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, const char *pattern; NTSTATUS status; struct pvfs_filename *name; + int id; if (io->generic.level >= RAW_SEARCH_SEARCH) { return pvfs_search_first_old(ntvfs, req, io, search_private, callback); @@ -430,17 +415,19 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, return status; } - /* we need to give a handle back to the client so it - can continue a search */ - status = pvfs_next_search_handle(pvfs, &search->handle, 0x10000); - if (!NT_STATUS_IS_OK(status)) { - return status; + id = idr_get_new(pvfs->idtree_search, search, 0x10000); + if (id == -1) { + return NT_STATUS_INSUFFICIENT_RESOURCES; } - + + search->pvfs = pvfs; + search->handle = id; search->dir = dir; search->current_index = 0; search->search_attrib = search_attrib; + talloc_set_destructor(search, pvfs_search_destructor); + status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { @@ -463,9 +450,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, io->t2ffirst.out.end_of_search)) { talloc_free(search); } else { - pvfs->search.num_active_searches++; talloc_steal(pvfs, search); - DLIST_ADD(pvfs->search.open_searches, search); } return NT_STATUS_OK; @@ -491,11 +476,8 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, handle = io->t2fnext.in.handle; - for (search=pvfs->search.open_searches; search; search = search->next) { - if (search->handle == handle) break; - } - - if (!search) { + search = idr_find(pvfs->idtree_search, handle); + if (search == NULL) { /* we didn't find the search handle */ return NT_STATUS_INVALID_HANDLE; } @@ -544,7 +526,6 @@ found: if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && io->t2fnext.out.end_of_search)) { - DLIST_REMOVE(pvfs->search.open_searches, search); talloc_free(search); } @@ -565,16 +546,12 @@ NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs, handle = io->findclose.in.handle; } - for (search=pvfs->search.open_searches; search; search = search->next) { - if (search->handle == handle) break; - } - - if (!search) { + search = idr_find(pvfs->idtree_search, handle); + if (search == NULL) { /* we didn't find the search handle */ return NT_STATUS_INVALID_HANDLE; } - DLIST_REMOVE(pvfs->search.open_searches, search); talloc_free(search); return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e989f8de67..8aa028919c 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -61,11 +61,10 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, char *base_directory; NTSTATUS status; - pvfs = talloc_p(tcon, struct pvfs_state); + pvfs = talloc_zero_p(tcon, struct pvfs_state); if (pvfs == NULL) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(pvfs); /* for simplicity of path construction, remove any trailing slash now */ base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); @@ -95,6 +94,18 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + /* allocate the fnum id -> ptr tree */ + pvfs->idtree_fnum = idr_init(pvfs); + if (pvfs->idtree_fnum == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* allocate the search handle -> ptr tree */ + pvfs->idtree_search = idr_init(pvfs); + if (pvfs->idtree_search == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = pvfs_mangle_init(pvfs); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 6aaa43a213..ae601c60c7 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -32,27 +32,17 @@ struct pvfs_state { const char *share_name; uint_t flags; - struct { - /* a linked list of open searches */ - struct pvfs_search_state *open_searches; - - /* search handles are returned to the clients so they - can continue searches */ - uint16_t next_search_handle; - - /* count of active searches */ - uint_t num_active_searches; - - /* during trans2 search continuations we need to use - the initial search attributes */ - uint16_t search_attrib; - } search; - struct pvfs_file *open_files; struct pvfs_mangle_context *mangle_ctx; void *brl_context; + + /* an id tree mapping open search ID to a pvfs_search_state structure */ + void *idtree_search; + + /* an id tree mapping open file handle -> struct pvfs_file */ + void *idtree_fnum; }; @@ -95,7 +85,7 @@ struct pvfs_dir { /* the state of a search started with pvfs_search_first() */ struct pvfs_search_state { - struct pvfs_search_state *next, *prev; + struct pvfs_state *pvfs; uint16_t handle; uint_t current_index; uint16_t search_attrib; @@ -126,6 +116,10 @@ struct pvfs_file { /* a list of pending locks - used for locking cancel operations */ struct pvfs_pending_lock *pending_list; + + /* a count of active locks - used to avoid calling brl_close on + file close */ + uint64_t lock_count; }; -- cgit From b2b8282b8cc1774ac9cbef9a31ac23705ca45ac2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Oct 2004 07:08:35 +0000 Subject: r3057: - moved the idtree.c code into lib/ - converted the tid handling to use a idtree instead of bitmaps (This used to be commit 4220914179d10132057216650b65ed7f7679717e) --- source4/ntvfs/common/idtree.c | 360 ------------------------------------------ source4/ntvfs/posix/config.mk | 1 - 2 files changed, 361 deletions(-) delete mode 100644 source4/ntvfs/common/idtree.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/idtree.c b/source4/ntvfs/common/idtree.c deleted file mode 100644 index 80f7df97a0..0000000000 --- a/source4/ntvfs/common/idtree.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - very efficient functions to manage mapping a id (such as a fnum) to - a pointer. This is used for fnum and search id allocation. - - Copyright (C) Andrew Tridgell 2004 - - This code is derived from lib/idr.c in the 2.6 Linux kernel, which was - written by Jim Houston jim.houston@ccur.com, and is - Copyright (C) 2002 by Concurrent Computer Corporation - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* - see the section marked "public interface" below for documentation -*/ - -#include "includes.h" - -#define IDR_BITS 5 -#define IDR_FULL 0xfffffffful -#define TOP_LEVEL_FULL (IDR_FULL >> 30) -#define IDR_SIZE (1 << IDR_BITS) -#define IDR_MASK ((1 << IDR_BITS)-1) -#define MAX_ID_SHIFT (sizeof(int)*8 - 1) -#define MAX_ID_BIT (1U << MAX_ID_SHIFT) -#define MAX_ID_MASK (MAX_ID_BIT - 1) -#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS -#define IDR_FREE_MAX MAX_LEVEL + MAX_LEVEL - -#define set_bit(bit, v) (v) |= (1<<(bit)) -#define clear_bit(bit, v) (v) &= ~(1<<(bit)) - -struct idr_layer { - uint32_t bitmap; - struct idr_layer *ary[IDR_SIZE]; - int count; -}; - -struct idr { - struct idr_layer *top; - struct idr_layer *id_free; - int layers; - int id_free_cnt; -}; - -static struct idr_layer *alloc_layer(struct idr *idp) -{ - struct idr_layer *p; - - if (!(p = idp->id_free)) - return NULL; - idp->id_free = p->ary[0]; - idp->id_free_cnt--; - p->ary[0] = NULL; - return p; -} - -static int find_next_bit(uint32_t bm, int maxid, int n) -{ - while (nary[0] = idp->id_free; - idp->id_free = p; - idp->id_free_cnt++; -} - -static int idr_pre_get(struct idr *idp) -{ - while (idp->id_free_cnt < IDR_FREE_MAX) { - struct idr_layer *new = talloc_zero_p(idp, struct idr_layer); - if(new == NULL) - return (0); - free_layer(idp, new); - } - return 1; -} - -static int sub_alloc(struct idr *idp, void *ptr, int *starting_id) -{ - int n, m, sh; - struct idr_layer *p, *new; - struct idr_layer *pa[MAX_LEVEL]; - int l, id; - uint32_t bm; - - id = *starting_id; - p = idp->top; - l = idp->layers; - pa[l--] = NULL; - while (1) { - /* - * We run around this while until we reach the leaf node... - */ - n = (id >> (IDR_BITS*l)) & IDR_MASK; - bm = ~p->bitmap; - m = find_next_bit(bm, IDR_SIZE, n); - if (m == IDR_SIZE) { - /* no space available go back to previous layer. */ - l++; - id = (id | ((1 << (IDR_BITS*l))-1)) + 1; - if (!(p = pa[l])) { - *starting_id = id; - return -2; - } - continue; - } - if (m != n) { - sh = IDR_BITS*l; - id = ((id >> sh) ^ n ^ m) << sh; - } - if ((id >= MAX_ID_BIT) || (id < 0)) - return -1; - if (l == 0) - break; - /* - * Create the layer below if it is missing. - */ - if (!p->ary[m]) { - if (!(new = alloc_layer(idp))) - return -1; - p->ary[m] = new; - p->count++; - } - pa[l--] = p; - p = p->ary[m]; - } - /* - * We have reached the leaf node, plant the - * users pointer and return the raw id. - */ - p->ary[m] = (struct idr_layer *)ptr; - set_bit(m, p->bitmap); - p->count++; - /* - * If this layer is full mark the bit in the layer above - * to show that this part of the radix tree is full. - * This may complete the layer above and require walking - * up the radix tree. - */ - n = id; - while (p->bitmap == IDR_FULL) { - if (!(p = pa[++l])) - break; - n = n >> IDR_BITS; - set_bit((n & IDR_MASK), p->bitmap); - } - return(id); -} - -static int idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id) -{ - struct idr_layer *p, *new; - int layers, v, id; - - idr_pre_get(idp); - - id = starting_id; -build_up: - p = idp->top; - layers = idp->layers; - if (!p) { - if (!(p = alloc_layer(idp))) - return -1; - layers = 1; - } - /* - * Add a new layer to the top of the tree if the requested - * id is larger than the currently allocated space. - */ - while ((layers < MAX_LEVEL) && (id >= (1 << (layers*IDR_BITS)))) { - layers++; - if (!p->count) - continue; - if (!(new = alloc_layer(idp))) { - /* - * The allocation failed. If we built part of - * the structure tear it down. - */ - for (new = p; p && p != idp->top; new = p) { - p = p->ary[0]; - new->ary[0] = NULL; - new->bitmap = new->count = 0; - free_layer(idp, new); - } - return -1; - } - new->ary[0] = p; - new->count = 1; - if (p->bitmap == IDR_FULL) - set_bit(0, new->bitmap); - p = new; - } - idp->top = p; - idp->layers = layers; - v = sub_alloc(idp, ptr, &id); - if (v == -2) - goto build_up; - return(v); -} - -static void sub_remove(struct idr *idp, int shift, int id) -{ - struct idr_layer *p = idp->top; - struct idr_layer **pa[MAX_LEVEL]; - struct idr_layer ***paa = &pa[0]; - - *paa = NULL; - *++paa = &idp->top; - - while ((shift > 0) && p) { - int n = (id >> shift) & IDR_MASK; - clear_bit(n, p->bitmap); - *++paa = &p->ary[n]; - p = p->ary[n]; - shift -= IDR_BITS; - } - if (p != NULL) { - int n = id & IDR_MASK; - clear_bit(n, p->bitmap); - p->ary[n] = NULL; - while(*paa && ! --((**paa)->count)){ - free_layer(idp, **paa); - **paa-- = NULL; - } - if ( ! *paa ) - idp->layers = 0; - } -} - -static void *_idr_find(struct idr *idp, int id) -{ - int n; - struct idr_layer *p; - - n = idp->layers * IDR_BITS; - p = idp->top; - /* - * This tests to see if bits outside the current tree are - * present. If so, tain't one of ours! - */ - if ((id & ~(~0 << MAX_ID_SHIFT)) >> (n + IDR_BITS)) - return NULL; - - /* Mask off upper bits we don't use for the search. */ - id &= MAX_ID_MASK; - - while (n > 0 && p) { - n -= IDR_BITS; - p = p->ary[(id >> n) & IDR_MASK]; - } - return((void *)p); -} - -static void _idr_remove(struct idr *idp, int id) -{ - struct idr_layer *p; - - if (_idr_find(idp, id) == NULL) { - DEBUG(0,("WARNING: attempt to remove non-existant id %d in idtree\n", - id)); - return; - } - - /* Mask off upper bits we don't use for the search. */ - id &= MAX_ID_MASK; - - sub_remove(idp, (idp->layers - 1) * IDR_BITS, id); - if ( idp->top && idp->top->count == 1 && - (idp->layers > 1) && - idp->top->ary[0]) { - /* We can drop a layer */ - p = idp->top->ary[0]; - idp->top->bitmap = idp->top->count = 0; - free_layer(idp, idp->top); - idp->top = p; - --idp->layers; - } - while (idp->id_free_cnt >= IDR_FREE_MAX) { - p = alloc_layer(idp); - talloc_free(p); - return; - } -} - -/************************************************************************ - this is the public interface -**************************************************************************/ - -/* - initialise a idr tree. The context return value must be passed to - all subsequent idr calls. To destroy the idr tree use talloc_free() - on this context - */ -void *idr_init(TALLOC_CTX *mem_ctx) -{ - return talloc_zero_p(mem_ctx, struct idr); -} - -/* - allocate the next available id, and assign 'ptr' into its slot. - you can retrieve later this pointer using idr_find() -*/ -int idr_get_new(void *idp, void *ptr, int limit) -{ - int ret = idr_get_new_above_int((struct idr *)idp, ptr, 0); - if (ret >= limit) { - idr_remove(idp, ret); - return -1; - } - return ret; -} - -/* - allocate a new id, giving the first available value greater than or - equal to the given starting id -*/ -int idr_get_new_above(void *idp, void *ptr, int starting_id, int limit) -{ - int ret = idr_get_new_above_int((struct idr *)idp, ptr, starting_id); - if (ret >= limit) { - idr_remove(idp, ret); - return -1; - } - return ret; -} - -/* - find a pointer value previously set with idr_get_new given an id -*/ -void *idr_find(void *idp, int id) -{ - return _idr_find((struct idr *)idp, id); -} - -/* - remove an id from the idr tree -*/ -void idr_remove(void *idp, int id) -{ - return _idr_remove((struct idr *)idp, id); -} diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 732e896d2b..b6ba073a99 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -22,7 +22,6 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_shortname.o \ ntvfs/posix/pvfs_lock.o \ ntvfs/posix/pvfs_wait.o \ - ntvfs/common/idtree.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix ################################################ -- cgit From 72093ce62f1e09db86452720fe8280ad66824cde Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 19 Oct 2004 12:06:01 +0000 Subject: r3064: - use UINT8_MAX and UINT16_MAX instead of hex values for idr_get_new() limits - change idr_get_new() to use > instead of >= in the limit check (This used to be commit 834b09929bcb8aabdd151b7c2306001497cabdb4) --- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/posix/pvfs_search.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c255558369..fb81c86bcc 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -157,7 +157,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new(pvfs->idtree_fnum, f, 0x10000); + fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); if (fnum == -1) { talloc_free(f); return NT_STATUS_TOO_MANY_OPENED_FILES; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 7b0da321d3..1464609e98 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -287,7 +287,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, /* we need to give a handle back to the client so it can continue a search */ - id = idr_get_new(pvfs->idtree_search, search, 0x100); + id = idr_get_new(pvfs->idtree_search, search, UINT8_MAX); if (id == -1) { return NT_STATUS_INSUFFICIENT_RESOURCES; } @@ -415,7 +415,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, return status; } - id = idr_get_new(pvfs->idtree_search, search, 0x10000); + id = idr_get_new(pvfs->idtree_search, search, UINT16_MAX); if (id == -1) { return NT_STATUS_INSUFFICIENT_RESOURCES; } -- cgit From 20d17b80571f0d0265c99c1ccdc21910c2eed043 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Oct 2004 08:28:31 +0000 Subject: r3081: several updates to ntvfs and server side async request handling in preparation for the full share modes and ntcreatex code that I am working on. highlights include: - changed the way a backend determines if it is allowed to process a request asynchronously. The previous method of looking at the send_fn caused problems when an intermediate ntvfs module disabled it, and the caller then wanted to finished processing using this function. The new method is a REQ_CONTROL_MAY_ASYNC flag in req->control_flags, which is also a bit easier to read - fixed 2 bugs in the readbraw server code. One related to trying to answer a readbraw with smb signing (which can't work, and crashed our signing code), the second related to error handling, which attempted to send a normal SMB error packet, when readbraw must send a 0 read reply (as it has no header) - added several more ntvfs_generic.c generic mapping functions. This means that backends no longer need to implement such esoteric functions as SMBwriteunlock() if they don't want to. The backend can just request the mapping layer turn it into a write followed by an unlock. This makes the backends considerably simpler as they only need to implement one style of each function for lock, read, write, open etc, rather than the full host of functions that SMB provides. A backend can still choose to implement them individually, of course, and the CIFS backend does that. - simplified the generic structures to make them identical to the principal call for several common SMB calls (such as RAW_WRITE_GENERIC now being an alias for RAW_WRITE_WRITEX). - started rewriting the pvfs_open() code in preparation for the full ntcreatex semantics. - in pvfs_open and ipc_open, initially allocate the open file structure as a child of the request, so on error we don't need to clean up. Then when we are going to succeed the open steal the pointer into the long term backend context. This makes for much simpler error handling (and fixes some bugs) - use a destructor in the ipc backend to make sure that everthing is cleaned up on receive error conditions. - switched the ipc backend to using idtree for fnum allocation - in the ntvfs_generic mapping routines, use a allocated secondary structure not a stack structure to ensure the request pointer remains valid even if the backend replies async. (This used to be commit 3457c1836c09c82956697eb21627dfa2ed37682e) --- source4/ntvfs/cifs/vfs_cifs.c | 36 +-- source4/ntvfs/ipc/vfs_ipc.c | 171 +++++--------- source4/ntvfs/nbench/vfs_nbench.c | 4 +- source4/ntvfs/ntvfs_generic.c | 483 ++++++++++++++++++++++++++++++-------- source4/ntvfs/posix/pvfs_lock.c | 43 +--- source4/ntvfs/posix/pvfs_open.c | 201 ++++++++++++---- source4/ntvfs/posix/pvfs_read.c | 7 +- source4/ntvfs/posix/pvfs_write.c | 84 +++---- 8 files changed, 656 insertions(+), 373 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 5b10e72411..feacc063b4 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -214,7 +214,7 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, /* see if the front end will allow us to perform this function asynchronously. */ - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_unlink(private->tree, unl); } @@ -245,7 +245,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, /* see if the front end will allow us to perform this function asynchronously. */ - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_ioctl(private->tree, req, io); } @@ -263,7 +263,7 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_chkpath(private->tree, cp); } @@ -292,7 +292,7 @@ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_pathinfo(private->tree, req, info); } @@ -321,7 +321,7 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_fileinfo(private->tree, req, info); } @@ -340,7 +340,7 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_setpathinfo(private->tree, st); } @@ -370,7 +370,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_open(private->tree, req, io); } @@ -388,7 +388,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_mkdir(private->tree, md); } @@ -406,7 +406,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_rmdir(private->tree, rd); } c_req = smb_raw_rmdir_send(private->tree, rd); @@ -423,7 +423,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_rename(private->tree, ren); } @@ -461,7 +461,7 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_read(private->tree, rd); } @@ -490,7 +490,7 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_write(private->tree, wr); } @@ -526,7 +526,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_close(private->tree, io); } @@ -544,7 +544,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_exit(private->tree->session); } @@ -582,7 +582,7 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_lock(private->tree, lck); } @@ -600,7 +600,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_setfileinfo(private->tree, info); } c_req = smb_raw_setfileinfo_send(private->tree, info); @@ -629,7 +629,7 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_fsinfo(private->tree, req, fs); } @@ -698,7 +698,7 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!req->async.send_fn) { + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_trans2(private->tree, req, trans2); } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 760cf07100..f4eb007235 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -31,13 +31,12 @@ ipc$ connection. It needs to keep information about all open pipes */ struct ipc_private { - - uint16_t next_fnum; - uint16_t num_open; + void *idtree_fnum; /* a list of open pipes */ struct pipe_state { struct pipe_state *next, *prev; + struct ipc_private *private; const char *pipe_name; uint16_t fnum; struct dcesrv_connection *dce_conn; @@ -54,56 +53,12 @@ struct ipc_private { }; -/* - find the next fnum available on this connection -*/ -static uint16_t find_next_fnum(struct ipc_private *ipc) -{ - struct pipe_state *p; - uint32_t ret; - - if (ipc->num_open == 0xFFFF) { - return 0; - } - -again: - ret = ipc->next_fnum++; - - for (p=ipc->pipe_list; p; p=p->next) { - if (p->fnum == ret) { - goto again; - } - } - - return ret; -} - - -/* - shutdown a single pipe. Called on a close or disconnect -*/ -static void pipe_shutdown(struct ipc_private *private, struct pipe_state *p) -{ - talloc_free(p->dce_conn); - DLIST_REMOVE(private->pipe_list, p); - talloc_destroy(p); -} - - /* find a open pipe give a file descriptor */ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t fnum) { - struct pipe_state *p; - - for (p=private->pipe_list; p; p=p->next) { - if (p->fnum == fnum) { - return p; - } - } - - return NULL; + return idr_find(private->idtree_fnum, fnum); } @@ -127,8 +82,11 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; private->pipe_list = NULL; - private->next_fnum = 1; - private->num_open = 0; + + private->idtree_fnum = idr_init(private); + if (private->idtree_fnum == NULL) { + return NT_STATUS_NO_MEMORY; + } return NT_STATUS_OK; } @@ -143,7 +101,7 @@ static NTSTATUS ipc_disconnect(struct ntvfs_module_context *ntvfs, /* close any pipes that are open. Discard any unread data */ while (private->pipe_list) { - pipe_shutdown(private, private->pipe_list); + talloc_free(private->pipe_list); } return NT_STATUS_OK; @@ -196,6 +154,18 @@ static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs, } +/* + destroy a open pipe structure +*/ +static int ipc_fd_destructor(void *ptr) +{ + struct pipe_state *p = ptr; + idr_remove(p->private->idtree_fnum, p->fnum); + DLIST_REMOVE(p->private->pipe_list, p); + talloc_free(p->dce_conn); + return 0; +} + /* open a file backend - used for MSRPC pipes @@ -209,8 +179,9 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, struct dcesrv_ep_description ep_description; struct auth_session_info *session_info = NULL; struct ipc_private *private = ntvfs->private_data; + int fnum; - p = talloc_p(private, struct pipe_state); + p = talloc_p(req, struct pipe_state); if (!p) { return NT_STATUS_NO_MEMORY; } @@ -219,16 +190,15 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); if (!p->pipe_name) { - talloc_free(p); return NT_STATUS_NO_MEMORY; } - p->fnum = find_next_fnum(private); - if (p->fnum == 0) { - talloc_free(p); + fnum = idr_get_new(private->idtree_fnum, p, UINT16_MAX); + if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } + p->fnum = fnum; p->ipc_state = 0x5ff; /* @@ -241,8 +211,6 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, will need to do that once the credentials infrastructure is finalised for Samba4 */ - - printf("FINDING: %s\n", p->pipe_name); ep_description.type = ENDPOINT_SMB; ep_description.info.smb_pipe = p->pipe_name; @@ -250,7 +218,6 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, if (req->session) { /* The session info is refcount-increased in the dcesrv_endpoint_search_connect() function */ - session_info = req->session->session_info; } @@ -259,19 +226,22 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, session_info, &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { - talloc_free(p); + idr_remove(private->idtree_fnum, p->fnum); return status; } - private->num_open++; - DLIST_ADD(private->pipe_list, p); p->smbpid = req->smbpid; p->session = req->session; + p->private = private; *ps = p; + talloc_steal(private, p); + + talloc_set_destructor(p, ipc_fd_destructor); + return NT_STATUS_OK; } @@ -390,21 +360,14 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, struct pipe_state *p; NTSTATUS status; - switch (rd->generic.level) { - case RAW_READ_READ: - fnum = rd->read.in.fnum; - data.length = rd->read.in.count; - data.data = rd->read.out.data; - break; - case RAW_READ_READX: - fnum = rd->readx.in.fnum; - data.length = rd->readx.in.maxcnt; - data.data = rd->readx.out.data; - break; - default: - return NT_STATUS_NOT_SUPPORTED; + if (rd->generic.level != RAW_READ_GENERIC) { + return ntvfs_map_read(req, rd, ntvfs); } + fnum = rd->readx.in.fnum; + data.length = rd->readx.in.maxcnt; + data.data = rd->readx.out.data; + p = pipe_state_find(private, fnum); if (!p) { return NT_STATUS_INVALID_HANDLE; @@ -415,18 +378,9 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, return status; } - switch (rd->generic.level) { - case RAW_READ_READ: - rd->read.out.nread = data.length; - break; - case RAW_READ_READX: - rd->readx.out.remaining = 0; - rd->readx.out.compaction_mode = 0; - rd->readx.out.nread = data.length; - break; - default: - return NT_STATUS_NOT_SUPPORTED; - } + rd->readx.out.remaining = 0; + rd->readx.out.compaction_mode = 0; + rd->readx.out.nread = data.length; return status; } @@ -443,23 +397,14 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, struct pipe_state *p; NTSTATUS status; - switch (wr->generic.level) { - case RAW_WRITE_WRITE: - fnum = wr->write.in.fnum; - data.data = discard_const_p(void, wr->write.in.data); - data.length = wr->write.in.count; - break; - - case RAW_WRITE_WRITEX: - fnum = wr->writex.in.fnum; - data.data = discard_const_p(void, wr->writex.in.data); - data.length = wr->writex.in.count; - break; - - default: - return NT_STATUS_NOT_SUPPORTED; + if (wr->generic.level != RAW_WRITE_GENERIC) { + return ntvfs_map_write(req, wr, ntvfs); } + fnum = wr->writex.in.fnum; + data.data = discard_const_p(void, wr->writex.in.data); + data.length = wr->writex.in.count; + p = pipe_state_find(private, fnum); if (!p) { return NT_STATUS_INVALID_HANDLE; @@ -470,17 +415,8 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, return status; } - switch (wr->generic.level) { - case RAW_WRITE_WRITE: - wr->write.out.nwritten = data.length; - break; - case RAW_WRITE_WRITEX: - wr->writex.out.nwritten = data.length; - wr->writex.out.remaining = 0; - break; - default: - return NT_STATUS_NOT_SUPPORTED; - } + wr->writex.out.nwritten = data.length; + wr->writex.out.remaining = 0; return NT_STATUS_OK; } @@ -513,7 +449,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, struct pipe_state *p; if (io->generic.level != RAW_CLOSE_CLOSE) { - return NT_STATUS_ACCESS_DENIED; + return ntvfs_map_close(req, io, ntvfs); } p = pipe_state_find(private, io->close.in.fnum); @@ -521,8 +457,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - pipe_shutdown(private, p); - private->num_open--; + talloc_free(p); return NT_STATUS_OK; } @@ -539,7 +474,7 @@ static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs, for (p=private->pipe_list; p; p=next) { next = p->next; if (p->smbpid == req->smbpid) { - pipe_shutdown(private, p); + talloc_free(p); } } @@ -558,7 +493,7 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, for (p=private->pipe_list; p; p=next) { next = p->next; if (p->session == req->session) { - pipe_shutdown(private, p); + talloc_free(p); } } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 6203c21506..482f0208a2 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -59,10 +59,8 @@ static void nbench_log(struct nbench_private *private, status code and any result parameters much harder. */ #define PASS_THRU_REQ(ntvfs, req, op, args) do { \ - void *send_fn_saved = req->async.send_fn; \ - req->async.send_fn = NULL; \ + req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; \ status = ntvfs_next_##op args; \ - req->async.send_fn = send_fn_saved; \ } while (0) diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 9e1d653465..b6f3d8e603 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -3,7 +3,7 @@ NTVFS generic level mapping code - Copyright (C) Andrew Tridgell 2003 + Copyright (C) Andrew Tridgell 2003-2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,7 +34,8 @@ #include "includes.h" /* - see if a filename ends in EXE COM DLL or SYM. This is needed for the DENY_DOS mapping for OpenX + see if a filename ends in EXE COM DLL or SYM. This is needed for the + DENY_DOS mapping for OpenX */ static BOOL is_exe_file(const char *fname) { @@ -61,125 +62,133 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, struct ntvfs_module_context *ntvfs) { NTSTATUS status; - union smb_open io2; + union smb_open *io2; - if (io->generic.level == RAW_OPEN_GENERIC) { - return NT_STATUS_INVALID_LEVEL; + io2 = talloc_p(req, union smb_open); + if (io2 == NULL) { + return NT_STATUS_NO_MEMORY; } + /* must be synchronous, or we won't be called to do the + translation */ + req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + switch (io->generic.level) { + case RAW_OPEN_GENERIC: + return NT_STATUS_INVALID_LEVEL; + case RAW_OPEN_OPENX: - ZERO_STRUCT(io2.generic.in); - io2.generic.level = RAW_OPEN_GENERIC; + ZERO_STRUCT(io2->generic.in); + io2->generic.level = RAW_OPEN_GENERIC; if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) { - io2.generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; } if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { - io2.generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; } switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { case OPENX_MODE_ACCESS_READ: - io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; break; case OPENX_MODE_ACCESS_WRITE: - io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: - io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS; break; } switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { case OPENX_MODE_DENY_READ: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; break; case OPENX_MODE_DENY_WRITE: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; break; case OPENX_MODE_DENY_ALL: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; case OPENX_MODE_DENY_NONE: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; break; case OPENX_MODE_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ if (is_exe_file(io->openx.in.fname)) { - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; } else { if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == OPENX_MODE_ACCESS_READ) { - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; } else { - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; } } break; case OPENX_MODE_DENY_FCB: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; } switch (io->openx.in.open_func) { case (OPENX_OPEN_FUNC_FAIL): - io2.generic.in.open_disposition = NTCREATEX_DISP_CREATE; + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; break; case (OPENX_OPEN_FUNC_OPEN): - io2.generic.in.open_disposition = NTCREATEX_DISP_OPEN; + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; break; case (OPENX_OPEN_FUNC_TRUNC): - io2.generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; break; case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): - io2.generic.in.open_disposition = NTCREATEX_DISP_CREATE; + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; break; case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): - io2.generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; break; case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): - io2.generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; break; } - io2.generic.in.alloc_size = io->openx.in.size; - io2.generic.in.file_attr = io->openx.in.file_attrs; - io2.generic.in.fname = io->openx.in.fname; + io2->generic.in.alloc_size = io->openx.in.size; + io2->generic.in.file_attr = io->openx.in.file_attrs; + io2->generic.in.fname = io->openx.in.fname; - status = ntvfs->ops->open(ntvfs, req, &io2); + status = ntvfs->ops->open(ntvfs, req, io2); if (!NT_STATUS_IS_OK(status)) { return status; } ZERO_STRUCT(io->openx.out); - io->openx.out.fnum = io2.generic.out.fnum; - io->openx.out.attrib = io2.generic.out.attrib; - io->openx.out.write_time = nt_time_to_unix(io2.generic.out.write_time); - io->openx.out.size = io2.generic.out.size; + io->openx.out.fnum = io2->generic.out.fnum; + io->openx.out.attrib = io2->generic.out.attrib; + io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->openx.out.size = io2->generic.out.size; return NT_STATUS_OK; case RAW_OPEN_OPEN: - ZERO_STRUCT(io2.generic.in); - io2.generic.level = RAW_OPEN_GENERIC; - io2.generic.in.file_attr = io->open.in.search_attrs; - io2.generic.in.fname = io->open.in.fname; - io2.generic.in.open_disposition = NTCREATEX_DISP_OPEN; + ZERO_STRUCT(io2->generic.in); + io2->generic.level = RAW_OPEN_GENERIC; + io2->generic.in.file_attr = io->open.in.search_attrs; + io2->generic.in.fname = io->open.in.fname; + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; DEBUG(9,("ntvfs_map_open(OPEN): mapping flags=0x%x\n", io->open.in.flags)); switch (io->open.in.flags & OPEN_FLAGS_MODE_MASK) { case OPEN_FLAGS_OPEN_READ: - io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; io->open.out.rmode = DOS_OPEN_RDONLY; break; case OPEN_FLAGS_OPEN_WRITE: - io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; io->open.out.rmode = DOS_OPEN_WRONLY; break; case OPEN_FLAGS_OPEN_RDWR: case 0xf: /* FCB mode */ - io2.generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; io->open.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ break; @@ -194,31 +203,31 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, /* DENY_DOS is quite strange - it depends on the filename! */ /* REWRITE: is this necessary for OPEN? */ if (is_exe_file(io->open.in.fname)) { - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; } else { if ((io->open.in.flags & OPEN_FLAGS_MODE_MASK) == OPEN_FLAGS_OPEN_READ) { - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; } else { - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; } } break; case OPEN_FLAGS_DENY_ALL: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; case OPEN_FLAGS_DENY_WRITE: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; break; case OPEN_FLAGS_DENY_READ: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; break; case OPEN_FLAGS_DENY_NONE: - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE; break; case 0x70: /* FCB mode */ - io2.generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; default: DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", @@ -226,18 +235,18 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, return NT_STATUS_INVALID_PARAMETER; } DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", - io->open.in.flags, io2.generic.in.access_mask, io2.generic.in.share_access)); + io->open.in.flags, io2->generic.in.access_mask, io2->generic.in.share_access)); - status = ntvfs->ops->open(ntvfs, req, &io2); + status = ntvfs->ops->open(ntvfs, req, io2); if (!NT_STATUS_IS_OK(status)) { return status; } ZERO_STRUCT(io->openx.out); - io->open.out.fnum = io2.generic.out.fnum; - io->open.out.attrib = io2.generic.out.attrib; - io->open.out.write_time = nt_time_to_unix(io2.generic.out.write_time); - io->open.out.size = io2.generic.out.size; + io->open.out.fnum = io2->generic.out.fnum; + io->open.out.attrib = io2->generic.out.attrib; + io->open.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->open.out.size = io2->generic.out.size; io->open.out.rmode = DOS_OPEN_RDWR; return NT_STATUS_OK; @@ -254,16 +263,21 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, struct ntvfs_module_context *ntvfs) { NTSTATUS status; - union smb_fsinfo fs2; + union smb_fsinfo *fs2; + + fs2 = talloc_p(req, union smb_fsinfo); + if (fs2 == NULL) { + return NT_STATUS_NO_MEMORY; + } if (fs->generic.level == RAW_QFS_GENERIC) { return NT_STATUS_INVALID_LEVEL; } /* ask the backend for the generic info */ - fs2.generic.level = RAW_QFS_GENERIC; + fs2->generic.level = RAW_QFS_GENERIC; - status = ntvfs->ops->fsinfo(ntvfs, req, &fs2); + status = ntvfs->ops->fsinfo(ntvfs, req, fs2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -279,7 +293,7 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, /* we need to scale the sizes to fit */ for (bpunit=64; bpunit<0x10000; bpunit *= 2) { - if (fs2.generic.out.blocks_total * (double)fs2.generic.out.block_size < bpunit * 512 * 65535.0) { + if (fs2->generic.out.blocks_total * (double)fs2->generic.out.block_size < bpunit * 512 * 65535.0) { break; } } @@ -287,9 +301,9 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, fs->dskattr.out.blocks_per_unit = bpunit; fs->dskattr.out.block_size = 512; fs->dskattr.out.units_total = - (fs2.generic.out.blocks_total * (double)fs2.generic.out.block_size) / (bpunit * 512); + (fs2->generic.out.blocks_total * (double)fs2->generic.out.block_size) / (bpunit * 512); fs->dskattr.out.units_free = - (fs2.generic.out.blocks_free * (double)fs2.generic.out.block_size) / (bpunit * 512); + (fs2->generic.out.blocks_free * (double)fs2->generic.out.block_size) / (bpunit * 512); /* we must return a maximum of 2G to old DOS systems, or they get very confused */ if (bpunit > 64 && req->smb_conn->negotiate.protocol <= PROTOCOL_LANMAN2) { @@ -301,63 +315,63 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, } case RAW_QFS_ALLOCATION: - fs->allocation.out.fs_id = fs2.generic.out.fs_id; - fs->allocation.out.total_alloc_units = fs2.generic.out.blocks_total; - fs->allocation.out.avail_alloc_units = fs2.generic.out.blocks_free; + fs->allocation.out.fs_id = fs2->generic.out.fs_id; + fs->allocation.out.total_alloc_units = fs2->generic.out.blocks_total; + fs->allocation.out.avail_alloc_units = fs2->generic.out.blocks_free; fs->allocation.out.sectors_per_unit = 1; - fs->allocation.out.bytes_per_sector = fs2.generic.out.block_size; + fs->allocation.out.bytes_per_sector = fs2->generic.out.block_size; return NT_STATUS_OK; case RAW_QFS_VOLUME: - fs->volume.out.serial_number = fs2.generic.out.serial_number; - fs->volume.out.volume_name.s = fs2.generic.out.volume_name; + fs->volume.out.serial_number = fs2->generic.out.serial_number; + fs->volume.out.volume_name.s = fs2->generic.out.volume_name; return NT_STATUS_OK; case RAW_QFS_VOLUME_INFO: case RAW_QFS_VOLUME_INFORMATION: - fs->volume_info.out.create_time = fs2.generic.out.create_time; - fs->volume_info.out.serial_number = fs2.generic.out.serial_number; - fs->volume_info.out.volume_name.s = fs2.generic.out.volume_name; + fs->volume_info.out.create_time = fs2->generic.out.create_time; + fs->volume_info.out.serial_number = fs2->generic.out.serial_number; + fs->volume_info.out.volume_name.s = fs2->generic.out.volume_name; return NT_STATUS_OK; case RAW_QFS_SIZE_INFO: case RAW_QFS_SIZE_INFORMATION: - fs->size_info.out.total_alloc_units = fs2.generic.out.blocks_total; - fs->size_info.out.avail_alloc_units = fs2.generic.out.blocks_free; + fs->size_info.out.total_alloc_units = fs2->generic.out.blocks_total; + fs->size_info.out.avail_alloc_units = fs2->generic.out.blocks_free; fs->size_info.out.sectors_per_unit = 1; - fs->size_info.out.bytes_per_sector = fs2.generic.out.block_size; + fs->size_info.out.bytes_per_sector = fs2->generic.out.block_size; return NT_STATUS_OK; case RAW_QFS_DEVICE_INFO: case RAW_QFS_DEVICE_INFORMATION: - fs->device_info.out.device_type = fs2.generic.out.device_type; - fs->device_info.out.characteristics = fs2.generic.out.device_characteristics; + fs->device_info.out.device_type = fs2->generic.out.device_type; + fs->device_info.out.characteristics = fs2->generic.out.device_characteristics; return NT_STATUS_OK; case RAW_QFS_ATTRIBUTE_INFO: case RAW_QFS_ATTRIBUTE_INFORMATION: - fs->attribute_info.out.fs_attr = fs2.generic.out.fs_attr; - fs->attribute_info.out.max_file_component_length = fs2.generic.out.max_file_component_length; - fs->attribute_info.out.fs_type.s = fs2.generic.out.fs_type; + fs->attribute_info.out.fs_attr = fs2->generic.out.fs_attr; + fs->attribute_info.out.max_file_component_length = fs2->generic.out.max_file_component_length; + fs->attribute_info.out.fs_type.s = fs2->generic.out.fs_type; return NT_STATUS_OK; case RAW_QFS_QUOTA_INFORMATION: ZERO_STRUCT(fs->quota_information.out.unknown); - fs->quota_information.out.quota_soft = fs2.generic.out.quota_soft; - fs->quota_information.out.quota_hard = fs2.generic.out.quota_hard; - fs->quota_information.out.quota_flags = fs2.generic.out.quota_flags; + fs->quota_information.out.quota_soft = fs2->generic.out.quota_soft; + fs->quota_information.out.quota_hard = fs2->generic.out.quota_hard; + fs->quota_information.out.quota_flags = fs2->generic.out.quota_flags; return NT_STATUS_OK; case RAW_QFS_FULL_SIZE_INFORMATION: - fs->full_size_information.out.total_alloc_units = fs2.generic.out.blocks_total; - fs->full_size_information.out.call_avail_alloc_units = fs2.generic.out.blocks_free; - fs->full_size_information.out.actual_avail_alloc_units = fs2.generic.out.blocks_free; + fs->full_size_information.out.total_alloc_units = fs2->generic.out.blocks_total; + fs->full_size_information.out.call_avail_alloc_units = fs2->generic.out.blocks_free; + fs->full_size_information.out.actual_avail_alloc_units = fs2->generic.out.blocks_free; fs->full_size_information.out.sectors_per_unit = 1; - fs->full_size_information.out.bytes_per_sector = fs2.generic.out.block_size; + fs->full_size_information.out.bytes_per_sector = fs2->generic.out.block_size; return NT_STATUS_OK; case RAW_QFS_OBJECTID_INFORMATION: - fs->objectid_information.out.guid = fs2.generic.out.guid; + fs->objectid_information.out.guid = fs2->generic.out.guid; ZERO_STRUCT(fs->objectid_information.out.unknown); return NT_STATUS_OK; } @@ -370,7 +384,8 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, /* NTVFS fileinfo generic to any mapper */ -NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, union smb_fileinfo *info2) +NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, + union smb_fileinfo *info2) { int i; /* and convert it to the required level using results in info2 */ @@ -596,21 +611,26 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf struct ntvfs_module_context *ntvfs) { NTSTATUS status; - union smb_fileinfo info2; + union smb_fileinfo *info2; + + info2 = talloc_p(req, union smb_fileinfo); + if (info2 == NULL) { + return NT_STATUS_NO_MEMORY; + } if (info->generic.level == RAW_FILEINFO_GENERIC) { return NT_STATUS_INVALID_LEVEL; } /* ask the backend for the generic info */ - info2.generic.level = RAW_FILEINFO_GENERIC; - info2.generic.in.fnum = info->generic.in.fnum; + info2->generic.level = RAW_FILEINFO_GENERIC; + info2->generic.in.fnum = info->generic.in.fnum; - status = ntvfs->ops->qfileinfo(ntvfs, req, &info2); + status = ntvfs->ops->qfileinfo(ntvfs, req, info2); if (!NT_STATUS_IS_OK(status)) { return status; } - return ntvfs_map_fileinfo(req, info, &info2); + return ntvfs_map_fileinfo(req, info, info2); } /* @@ -620,19 +640,286 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf struct ntvfs_module_context *ntvfs) { NTSTATUS status; - union smb_fileinfo info2; + union smb_fileinfo *info2; + + info2 = talloc_p(req, union smb_fileinfo); + if (info2 == NULL) { + return NT_STATUS_NO_MEMORY; + } if (info->generic.level == RAW_FILEINFO_GENERIC) { return NT_STATUS_INVALID_LEVEL; } /* ask the backend for the generic info */ - info2.generic.level = RAW_FILEINFO_GENERIC; - info2.generic.in.fname = info->generic.in.fname; + info2->generic.level = RAW_FILEINFO_GENERIC; + info2->generic.in.fname = info->generic.in.fname; + + /* must be synchronous, or we won't be called to do the + translation */ + req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; - status = ntvfs->ops->qpathinfo(ntvfs, req, &info2); + status = ntvfs->ops->qpathinfo(ntvfs, req, info2); if (!NT_STATUS_IS_OK(status)) { return status; } - return ntvfs_map_fileinfo(req, info, &info2); + return ntvfs_map_fileinfo(req, info, info2); +} + + +/* + NTVFS lock generic to any mapper +*/ +NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck, + struct ntvfs_module_context *ntvfs) +{ + union smb_lock *lck2; + struct smb_lock_entry *locks; + + lck2 = talloc_p(req, union smb_lock); + if (lck2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + locks = talloc_array_p(lck2, struct smb_lock_entry, 1); + if (locks == NULL) { + return NT_STATUS_NO_MEMORY; + } + + switch (lck->generic.level) { + case RAW_LOCK_LOCKX: + return NT_STATUS_INVALID_LEVEL; + + case RAW_LOCK_LOCK: + lck2->generic.in.ulock_cnt = 0; + lck2->generic.in.lock_cnt = 1; + break; + + case RAW_LOCK_UNLOCK: + lck2->generic.in.ulock_cnt = 1; + lck2->generic.in.lock_cnt = 0; + break; + } + + lck2->generic.level = RAW_LOCK_GENERIC; + lck2->generic.in.fnum = lck->lock.in.fnum; + lck2->generic.in.mode = 0; + lck2->generic.in.timeout = 0; + lck2->generic.in.locks = locks; + locks->pid = req->smbpid; + locks->offset = lck->lock.in.offset; + locks->count = lck->lock.in.count; + + return ntvfs->ops->lock(ntvfs, req, lck2); +} + + +/* + NTVFS write generic to any mapper +*/ +NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, + struct ntvfs_module_context *ntvfs) +{ + union smb_write *wr2; + union smb_lock *lck; + union smb_close *cl; + NTSTATUS status; + + wr2 = talloc_p(req, union smb_write); + if (wr2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + wr2->generic.level = RAW_WRITE_GENERIC; + + /* we can't map asynchronously */ + req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + + switch (wr->generic.level) { + case RAW_WRITE_WRITEX: + status = NT_STATUS_INVALID_LEVEL; + break; + + case RAW_WRITE_WRITE: + wr2->generic.in.fnum = wr->write.in.fnum; + wr2->generic.in.offset = wr->write.in.offset; + wr2->generic.in.wmode = 0; + wr2->generic.in.remaining = wr->write.in.remaining; + wr2->generic.in.count = wr->write.in.count; + wr2->generic.in.data = wr->write.in.data; + status = ntvfs->ops->write(ntvfs, req, wr2); + wr->write.out.nwritten = wr2->generic.out.nwritten; + break; + + case RAW_WRITE_WRITEUNLOCK: + lck = talloc_p(wr2, union smb_lock); + if (lck == NULL) { + return NT_STATUS_NO_MEMORY; + } + + wr2->generic.in.fnum = wr->writeunlock.in.fnum; + wr2->generic.in.offset = wr->writeunlock.in.offset; + wr2->generic.in.wmode = 0; + wr2->generic.in.remaining = wr->writeunlock.in.remaining; + wr2->generic.in.count = wr->writeunlock.in.count; + wr2->generic.in.data = wr->writeunlock.in.data; + + lck->unlock.level = RAW_LOCK_UNLOCK; + lck->unlock.in.fnum = wr->writeunlock.in.fnum; + lck->unlock.in.count = wr->writeunlock.in.count; + lck->unlock.in.offset = wr->writeunlock.in.offset; + + status = ntvfs->ops->write(ntvfs, req, wr2); + + wr->writeunlock.out.nwritten = wr2->generic.out.nwritten; + + if (NT_STATUS_IS_OK(status)) { + status = ntvfs->ops->lock(ntvfs, req, lck); + } + break; + + case RAW_WRITE_WRITECLOSE: + cl = talloc_p(wr2, union smb_close); + if (cl == NULL) { + return NT_STATUS_NO_MEMORY; + } + + wr2->generic.in.fnum = wr->writeclose.in.fnum; + wr2->generic.in.offset = wr->writeclose.in.offset; + wr2->generic.in.wmode = 0; + wr2->generic.in.remaining = 0; + wr2->generic.in.count = wr->writeclose.in.count; + wr2->generic.in.data = wr->writeclose.in.data; + + cl->close.level = RAW_CLOSE_CLOSE; + cl->close.in.fnum = wr->writeclose.in.fnum; + cl->close.in.write_time = wr->writeclose.in.mtime; + + status = ntvfs->ops->write(ntvfs, req, wr2); + wr->writeclose.out.nwritten = wr2->generic.out.nwritten; + + if (NT_STATUS_IS_OK(status)) { + status = ntvfs->ops->close(ntvfs, req, cl); + } + break; + + case RAW_WRITE_SPLWRITE: + wr2->generic.in.fnum = wr->splwrite.in.fnum; + wr2->generic.in.offset = 0; + wr2->generic.in.wmode = 0; + wr2->generic.in.remaining = 0; + wr2->generic.in.count = wr->splwrite.in.count; + wr2->generic.in.data = wr->splwrite.in.data; + status = ntvfs->ops->write(ntvfs, req, wr2); + break; + } + + + return status; +} + + +/* + NTVFS read generic to any mapper +*/ +NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, + struct ntvfs_module_context *ntvfs) +{ + union smb_read *rd2; + union smb_lock *lck; + NTSTATUS status; + + rd2 = talloc_p(req, union smb_read); + if (rd2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + rd2->generic.level = RAW_READ_GENERIC; + + /* we can't map asynchronously */ + req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + + switch (rd->generic.level) { + case RAW_READ_READX: + status = NT_STATUS_INVALID_LEVEL; + break; + + case RAW_READ_READ: + rd2->generic.in.fnum = rd->read.in.fnum; + rd2->generic.in.offset = rd->read.in.offset; + rd2->generic.in.mincnt = rd->read.in.count; + rd2->generic.in.maxcnt = rd->read.in.count; + rd2->generic.in.remaining = rd->read.in.remaining; + rd2->generic.out.data = rd->read.out.data; + status = ntvfs->ops->read(ntvfs, req, rd2); + rd->read.out.nread = rd2->generic.out.nread; + break; + + case RAW_READ_READBRAW: + rd2->generic.in.fnum = rd->readbraw.in.fnum; + rd2->generic.in.offset = rd->readbraw.in.offset; + rd2->generic.in.mincnt = rd->readbraw.in.mincnt; + rd2->generic.in.maxcnt = rd->readbraw.in.maxcnt; + rd2->generic.in.remaining = 0; + rd2->generic.out.data = rd->readbraw.out.data; + status = ntvfs->ops->read(ntvfs, req, rd2); + rd->readbraw.out.nread = rd2->generic.out.nread; + break; + + case RAW_READ_LOCKREAD: + lck = talloc_p(rd2, union smb_lock); + if (lck == NULL) { + return NT_STATUS_NO_MEMORY; + } + + rd2->generic.in.fnum = rd->lockread.in.fnum; + rd2->generic.in.offset = rd->lockread.in.offset; + rd2->generic.in.mincnt = rd->lockread.in.count; + rd2->generic.in.maxcnt = rd->lockread.in.count; + rd2->generic.in.remaining = rd->lockread.in.remaining; + rd2->generic.out.data = rd->lockread.out.data; + + lck->lock.level = RAW_LOCK_LOCK; + lck->lock.in.fnum = rd->lockread.in.fnum; + lck->lock.in.count = rd->lockread.in.count; + lck->lock.in.offset = rd->lockread.in.offset; + + status = ntvfs->ops->lock(ntvfs, req, lck); + + if (NT_STATUS_IS_OK(status)) { + status = ntvfs->ops->read(ntvfs, req, rd2); + rd->lockread.out.nread = rd2->generic.out.nread; + } + break; + } + + + return status; +} + + +/* + NTVFS close generic to any mapper +*/ +NTSTATUS ntvfs_map_close(struct smbsrv_request *req, union smb_close *cl, + struct ntvfs_module_context *ntvfs) +{ + union smb_close *cl2; + + cl2 = talloc_p(req, union smb_close); + if (cl2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + switch (cl2->generic.level) { + case RAW_CLOSE_CLOSE: + return NT_STATUS_INVALID_LEVEL; + + case RAW_CLOSE_SPLCLOSE: + cl2->close.level = RAW_CLOSE_CLOSE; + cl2->close.in.fnum = cl->splclose.in.fnum; + break; + } + + return ntvfs->ops->close(ntvfs, req, cl2); } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index f52e68eeb1..4a4da34b60 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -273,48 +273,21 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, struct pvfs_pending_lock *pending = NULL; NTSTATUS status; - f = pvfs_find_fd(pvfs, req, lck->generic.in.fnum); + if (lck->generic.level != RAW_LOCK_GENERIC) { + return ntvfs_map_lock(req, lck, ntvfs); + } + + f = pvfs_find_fd(pvfs, req, lck->lockx.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } - switch (lck->generic.level) { - case RAW_LOCK_LOCK: - status = brl_lock(pvfs->brl_context, - &f->locking_key, - req->smbpid, - f->fnum, - lck->lock.in.offset, - lck->lock.in.count, - WRITE_LOCK, NULL); - if (NT_STATUS_IS_OK(status)) { - f->lock_count++; - } - return status; - - case RAW_LOCK_UNLOCK: - status = brl_unlock(pvfs->brl_context, - &f->locking_key, - req->smbpid, - f->fnum, - lck->lock.in.offset, - lck->lock.in.count); - if (NT_STATUS_IS_OK(status)) { - f->lock_count--; - } - return status; - - case RAW_LOCK_GENERIC: - return NT_STATUS_INVALID_LEVEL; - - case RAW_LOCK_LOCKX: - /* fall through to the most complex case */ - break; + if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + return NT_STATUS_FILE_IS_A_DIRECTORY; } - /* now the lockingX case, most common and also most complex */ if (lck->lockx.in.timeout != 0 && - req->async.send_fn) { + (req->control_flags & REQ_CONTROL_MAY_ASYNC)) { pending = talloc_p(req, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index fb81c86bcc..eb5b94e753 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -46,6 +46,120 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, return f; } + +/* + cleanup a open directory handle +*/ +static int pvfs_dir_fd_destructor(void *p) +{ + struct pvfs_file *f = p; + DLIST_REMOVE(f->pvfs->open_files, f); + idr_remove(f->pvfs->idtree_fnum, f->fnum); + return 0; +} + + +/* + open a directory +*/ +static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + union smb_open *io) +{ + struct pvfs_file *f; + int fnum; + NTSTATUS status; + + /* if the client says it must be a directory, and it isn't, + then fail */ + if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + f = talloc_p(req, struct pvfs_file); + if (f == NULL) { + return NT_STATUS_NO_MEMORY; + } + + fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + if (fnum == -1) { + talloc_free(f); + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + + f->fnum = fnum; + f->fd = -1; + f->name = talloc_steal(f, name); + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->locking_key = data_blob(NULL, 0); + + /* setup a destructor to avoid leaks on abnormal termination */ + talloc_set_destructor(f, pvfs_dir_fd_destructor); + + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_OPEN_IF: + break; + + case NTCREATEX_DISP_OPEN: + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + break; + + case NTCREATEX_DISP_CREATE: + if (name->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + break; + + case NTCREATEX_DISP_OVERWRITE_IF: + case NTCREATEX_DISP_OVERWRITE: + case NTCREATEX_DISP_SUPERSEDE: + default: + return NT_STATUS_INVALID_PARAMETER; + } + + if (!name->exists) { + if (mkdir(name->full_name, 0755) == -1) { + return pvfs_map_errno(pvfs,errno); + } + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + DLIST_ADD(pvfs->open_files, f); + + /* the open succeeded, keep this handle permanently */ + talloc_steal(pvfs, f); + + ZERO_STRUCT(io->generic.out); + + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.fnum = f->fnum; + io->generic.out.alloc_size = 0; + io->generic.out.size = 0; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.is_directory = 1; + + return NT_STATUS_OK; +} + + /* by using a destructor we make sure that abnormal cleanup will not leak file descriptors (assuming at least the top level pointer is freed, which @@ -55,6 +169,8 @@ static int pvfs_fd_destructor(void *p) { struct pvfs_file *f = p; + DLIST_REMOVE(f->pvfs->open_files, f); + pvfs_lock_close(f->pvfs, f); if (f->fd != -1) { @@ -97,83 +213,79 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + /* directory opens are handled separately */ + if ((name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) || + (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { + return pvfs_open_directory(pvfs, req, name, io); + } + + switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + flags = O_TRUNC; + break; + case NTCREATEX_DISP_OVERWRITE_IF: flags = O_CREAT | O_TRUNC; break; + case NTCREATEX_DISP_OPEN: + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } flags = 0; break; + case NTCREATEX_DISP_OVERWRITE: + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } flags = O_TRUNC; break; + case NTCREATEX_DISP_CREATE: + if (name->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } flags = O_CREAT | O_EXCL; break; + case NTCREATEX_DISP_OPEN_IF: flags = O_CREAT; break; - default: - flags = 0; - break; - } - - flags |= O_RDWR; - -/* we need to do this differently to support systems without O_DIRECTORY */ -#ifndef O_DIRECTORY -#define O_DIRECTORY 0 -#endif - if (name->exists && - (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) && - !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { - return NT_STATUS_NOT_A_DIRECTORY; + default: + return NT_STATUS_INVALID_PARAMETER; } - if ((name->exists && name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) || - (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { - flags = O_RDONLY | O_DIRECTORY; - if (pvfs->flags & PVFS_FLAG_READONLY) { - goto do_open; - } - switch (io->generic.in.open_disposition) { - case NTCREATEX_DISP_CREATE: - if (mkdir(name->full_name, 0755) == -1) { - return pvfs_map_errno(pvfs,errno); - } - break; - case NTCREATEX_DISP_OPEN_IF: - if (mkdir(name->full_name, 0755) == -1 && errno != EEXIST) { - return pvfs_map_errno(pvfs,errno); - } - break; - } - } + flags |= O_RDWR; - f = talloc_p(pvfs, struct pvfs_file); + f = talloc_p(req, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; } fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); if (fnum == -1) { - talloc_free(f); return NT_STATUS_TOO_MANY_OPENED_FILES; } -do_open: fd = open(name->full_name, flags, 0644); if (fd == -1) { - if (errno == 0) + if (errno == 0) { errno = ENOENT; - return pvfs_map_errno(pvfs,errno); + } + idr_remove(pvfs->idtree_fnum, fnum); + return pvfs_map_errno(pvfs, errno); } /* re-resolve the open fd */ status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); return status; } @@ -210,6 +322,9 @@ do_open: io->generic.out.attrib = name->dos.attrib; io->generic.out.is_directory = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)?1:0; + /* success - keep the file handle */ + talloc_steal(pvfs, f); + return NT_STATUS_OK; } @@ -225,8 +340,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (io->generic.level != RAW_CLOSE_CLOSE) { - /* we need a mapping function */ - return NT_STATUS_INVALID_LEVEL; + return ntvfs_map_close(req, io, ntvfs); } f = pvfs_find_fd(pvfs, req, io->close.in.fnum); @@ -234,15 +348,14 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (close(f->fd) != 0) { + if (f->fd != -1 && + close(f->fd) != 0) { status = pvfs_map_errno(pvfs, errno); } else { status = NT_STATUS_OK; } f->fd = -1; - DLIST_REMOVE(pvfs->open_files, f); - /* the destructor takes care of the rest */ talloc_free(f); diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 24142a81ee..7256fd8e16 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -35,15 +35,18 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (rd->generic.level != RAW_READ_READX) { - return NT_STATUS_NOT_SUPPORTED; + return ntvfs_map_read(req, rd, ntvfs); } - f = pvfs_find_fd(pvfs, req, rd->readx.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } + if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + status = pvfs_check_lock(pvfs, f, req->smbpid, rd->readx.in.offset, rd->readx.in.maxcnt, diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 80a3dae3a7..8bbb4f8605 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -35,63 +35,37 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, struct pvfs_file *f; NTSTATUS status; - switch (wr->generic.level) { - case RAW_WRITE_WRITEX: - f = pvfs_find_fd(pvfs, req, wr->writex.in.fnum); - if (!f) { - return NT_STATUS_INVALID_HANDLE; - } - status = pvfs_check_lock(pvfs, f, req->smbpid, - wr->writex.in.offset, - wr->writex.in.count, - WRITE_LOCK); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - ret = pwrite(f->fd, - wr->writex.in.data, - wr->writex.in.count, - wr->writex.in.offset); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - wr->writex.out.nwritten = ret; - wr->writex.out.remaining = 0; /* should fill this in? */ - - return NT_STATUS_OK; - - case RAW_WRITE_WRITE: - f = pvfs_find_fd(pvfs, req, wr->write.in.fnum); - if (!f) { - return NT_STATUS_INVALID_HANDLE; - } - if (wr->write.in.count == 0) { - /* a truncate! */ - ret = ftruncate(f->fd, wr->write.in.offset); - } else { - status = pvfs_check_lock(pvfs, f, req->smbpid, - wr->write.in.offset, - wr->write.in.count, - WRITE_LOCK); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + if (wr->generic.level != RAW_WRITE_WRITEX) { + return ntvfs_map_write(req, wr, ntvfs); + } - ret = pwrite(f->fd, - wr->write.in.data, - wr->write.in.count, - wr->write.in.offset); - } - if (ret == -1) { - return pvfs_map_errno(pvfs, errno); - } - - wr->write.out.nwritten = ret; + f = pvfs_find_fd(pvfs, req, wr->writex.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } - return NT_STATUS_OK; + if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + return NT_STATUS_FILE_IS_A_DIRECTORY; } - return NT_STATUS_NOT_SUPPORTED; + status = pvfs_check_lock(pvfs, f, req->smbpid, + wr->writex.in.offset, + wr->writex.in.count, + WRITE_LOCK); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ret = pwrite(f->fd, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; } -- cgit From 4b14c8a09f009e2fae6af601fb3effd200c06196 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Oct 2004 11:08:58 +0000 Subject: r3082: added a "cifs:mapgeneric" option, which tells the cifs backend to use the ntvfs_generic mapping functions rather than sending the exact function asked for. This allows the generic mapping functions to be tested by comparing the behaviour of smbtorture against two cifs backend shares, one using "cifs:mapgeneric = true" and the other "cifs:mapgeneric = False" (This used to be commit c240c6bca5e10f1acbff45b0ed41c4c1ebcaae96) --- source4/ntvfs/cifs/vfs_cifs.c | 55 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index feacc063b4..07cfb912bd 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,7 +32,7 @@ struct cvfs_private { struct smbcli_tree *tree; struct smbcli_transport *transport; struct smbsrv_tcon *tcon; - /*const struct ntvfs_ops *ops;*/ + BOOL map_generic; }; @@ -152,6 +152,8 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, private->transport->event.ctx = event_context_merge(tcon->smb_conn->connection->event.ctx, private->transport->event.ctx); talloc_reference(private, private->transport->event.ctx); + private->map_generic = lp_parm_bool(req->tcon->service, + "cifs", "mapgeneric", False); return NT_STATUS_OK; } @@ -370,6 +372,11 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + if (io->generic.level != RAW_OPEN_GENERIC && + private->map_generic) { + return ntvfs_map_open(req, io, ntvfs); + } + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_open(private->tree, req, io); } @@ -461,6 +468,11 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + if (rd->generic.level != RAW_READ_GENERIC && + private->map_generic) { + return ntvfs_map_read(req, rd, ntvfs); + } + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_read(private->tree, rd); } @@ -490,6 +502,11 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + if (wr->generic.level != RAW_WRITE_GENERIC && + private->map_generic) { + return ntvfs_map_write(req, wr, ntvfs); + } + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_write(private->tree, wr); } @@ -503,18 +520,36 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, seek in a file */ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct smbsrv_request *req, struct smb_seek *io) { - return NT_STATUS_NOT_SUPPORTED; + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + return smb_raw_seek(private->tree, io); + } + + c_req = smb_raw_seek_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; } /* flush a file */ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) + struct smbsrv_request *req, struct smb_flush *io) { - return NT_STATUS_OK; + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + return smb_raw_flush(private->tree, io); + } + + c_req = smb_raw_flush_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; } /* @@ -526,6 +561,11 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + if (io->generic.level != RAW_CLOSE_GENERIC && + private->map_generic) { + return ntvfs_map_close(req, io, ntvfs); + } + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_close(private->tree, io); } @@ -582,6 +622,11 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + if (lck->generic.level != RAW_LOCK_GENERIC && + private->map_generic) { + return ntvfs_map_lock(req, lck, ntvfs); + } + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_lock(private->tree, lck); } -- cgit From 2e4c8c01591496b5fb44f0d7e2ce082a9795c2f3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Oct 2004 11:10:51 +0000 Subject: r3083: fixed a couple of generic mapping errors found with RAW-* and cifs:mapgeneric (This used to be commit 76329798ff7f804bf4d7e6e9c1bb4c4dc7b9bb01) --- source4/ntvfs/ntvfs_generic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index b6f3d8e603..d4c163844f 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -773,7 +773,8 @@ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, wr->writeunlock.out.nwritten = wr2->generic.out.nwritten; - if (NT_STATUS_IS_OK(status)) { + if (NT_STATUS_IS_OK(status) && + lck->unlock.in.count != 0) { status = ntvfs->ops->lock(ntvfs, req, lck); } break; @@ -798,7 +799,8 @@ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, status = ntvfs->ops->write(ntvfs, req, wr2); wr->writeclose.out.nwritten = wr2->generic.out.nwritten; - if (NT_STATUS_IS_OK(status)) { + if (NT_STATUS_IS_OK(status) && + wr2->generic.in.count != 0) { status = ntvfs->ops->close(ntvfs, req, cl); } break; -- cgit From 042a045025f53f89b87d253cd22678a8060c7711 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Oct 2004 12:08:40 +0000 Subject: r3086: fixed smbpid handling in the cifs backend (This used to be commit fbc6949e95df6ea70ca9892099efb537ded97287) --- source4/ntvfs/cifs/vfs_cifs.c | 52 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 07cfb912bd..37c0ed64d1 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -42,6 +42,8 @@ struct async_info { void *parms; }; +#define SETUP_PID private->tree->session->pid = SVAL(req->in.hdr, HDR_PID) + /* an idle function to cope with messages from the smbd client while waiting for a reply from the server @@ -136,7 +138,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, } private->transport = private->tree->session->transport; - private->tree->session->pid = SVAL(req->in.hdr, HDR_PID); + SETUP_PID; private->tcon = req->tcon; tcon->fs_type = talloc_strdup(tcon, "NTFS"); @@ -209,11 +211,13 @@ static void async_simple(struct smbcli_request *c_req) The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct smbsrv_request *req, struct smb_unlink *unl) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + /* see if the front end will allow us to perform this function asynchronously. */ if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { @@ -245,6 +249,8 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + /* see if the front end will allow us to perform this function asynchronously. */ if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { @@ -265,6 +271,8 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_chkpath(private->tree, cp); } @@ -294,6 +302,8 @@ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_pathinfo(private->tree, req, info); } @@ -323,6 +333,8 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_fileinfo(private->tree, req, info); } @@ -342,6 +354,8 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_setpathinfo(private->tree, st); } @@ -372,6 +386,8 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (io->generic.level != RAW_OPEN_GENERIC && private->map_generic) { return ntvfs_map_open(req, io, ntvfs); @@ -395,6 +411,8 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_mkdir(private->tree, md); } @@ -413,6 +431,8 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_rmdir(private->tree, rd); } @@ -430,6 +450,8 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_rename(private->tree, ren); } @@ -468,6 +490,8 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (rd->generic.level != RAW_READ_GENERIC && private->map_generic) { return ntvfs_map_read(req, rd, ntvfs); @@ -502,6 +526,8 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (wr->generic.level != RAW_WRITE_GENERIC && private->map_generic) { return ntvfs_map_write(req, wr, ntvfs); @@ -525,6 +551,8 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_seek(private->tree, io); } @@ -543,6 +571,8 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_flush(private->tree, io); } @@ -561,6 +591,8 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (io->generic.level != RAW_CLOSE_GENERIC && private->map_generic) { return ntvfs_map_close(req, io, ntvfs); @@ -584,6 +616,8 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_exit(private->tree->session); } @@ -622,6 +656,8 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (lck->generic.level != RAW_LOCK_GENERIC && private->map_generic) { return ntvfs_map_lock(req, lck, ntvfs); @@ -645,6 +681,8 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_setfileinfo(private->tree, info); } @@ -674,6 +712,8 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_fsinfo(private->tree, req, fs); } @@ -702,6 +742,8 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; + SETUP_PID; + return smb_raw_search_first(private->tree, req, io, search_private, callback); } @@ -713,6 +755,8 @@ static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; + SETUP_PID; + return smb_raw_search_next(private->tree, req, io, search_private, callback); } @@ -722,6 +766,8 @@ static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; + SETUP_PID; + return smb_raw_search_close(private->tree, io); } @@ -743,6 +789,8 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + SETUP_PID; + if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { return smb_raw_trans2(private->tree, req, trans2); } -- cgit From 82a56fae9954dcc12f7c531a44cc9344281acb85 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Oct 2004 12:24:31 +0000 Subject: r3087: fixed a typo (This used to be commit 3791b97694f052b0b7e170e07c21f7a5739d74dd) --- source4/ntvfs/ntvfs_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index d4c163844f..0be4e5fd8e 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -913,7 +913,7 @@ NTSTATUS ntvfs_map_close(struct smbsrv_request *req, union smb_close *cl, return NT_STATUS_NO_MEMORY; } - switch (cl2->generic.level) { + switch (cl->generic.level) { case RAW_CLOSE_CLOSE: return NT_STATUS_INVALID_LEVEL; -- cgit From 4b95dd55164784f8f05e4f1cde16bfaac1e30468 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Oct 2004 06:34:17 +0000 Subject: r3106: don't call a tree disconnect in the cifs backend, as during a smbd server shutdown we don't want a synchronous operation which may block to be called, thus delaying the shutdown. (This used to be commit 5882f7305fa850c39088e85eefd311c8ede15597) --- source4/ntvfs/cifs/vfs_cifs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 37c0ed64d1..1a0f1f2f71 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -168,8 +168,7 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; - smb_tree_disconnect(private->tree); - talloc_free(private->tree); + talloc_free(private); return NT_STATUS_OK; } -- cgit From d33ae23165f4a5c07d41c9049ece4de5c0bb62f4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Oct 2004 06:36:14 +0000 Subject: r3107: slight tweak to the openx -> ntcreatex mapping routine. This mapping can never be perfect, as openx can do things that ntcreatex can't, but with this tweak we get close (the BASE-DENY1 test passes completely, for example) (This used to be commit 88112b9677b3c9ca97d349905c95516c6f29c8a7) --- source4/ntvfs/ntvfs_generic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 0be4e5fd8e..ceb7900935 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -96,7 +96,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_ALL_ACCESS; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; break; } @@ -201,7 +201,6 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch(io->open.in.flags & OPEN_FLAGS_DENY_MASK) { case OPEN_FLAGS_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ - /* REWRITE: is this necessary for OPEN? */ if (is_exe_file(io->open.in.fname)) { io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; } else { -- cgit From ac989eda6d981ce47c7b345d5397450a3706f4d7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Oct 2004 12:47:02 +0000 Subject: r3114: - More work on merging the various structs that describe endpoints - Add protocol sequence to dcerpc transports (will be used later on) - Add more transports to the list (This used to be commit ab110192e6e2c1e5a3b2befe7b61158744f15d18) --- source4/ntvfs/ipc/vfs_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index f4eb007235..8b1c9d2d8d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -211,7 +211,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, will need to do that once the credentials infrastructure is finalised for Samba4 */ - ep_description.type = ENDPOINT_SMB; + ep_description.type = NCACN_NP; ep_description.info.smb_pipe = p->pipe_name; /* tell the RPC layer the session_info */ -- cgit From a9081b527b33d536ca36d61ad2f7f34a6e6e69e5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Oct 2004 17:40:55 +0000 Subject: r3118: Eliminate struct dcesrv_ep_description and replace it with struct dcerpc_binding. (This used to be commit 2046e14cf8d010d4e715124859df2c1c3c782266) --- source4/ntvfs/ipc/vfs_ipc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 8b1c9d2d8d..dc50f1671e 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -176,7 +176,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, { struct pipe_state *p; NTSTATUS status; - struct dcesrv_ep_description ep_description; + struct dcerpc_binding ep_description; struct auth_session_info *session_info = NULL; struct ipc_private *private = ntvfs->private_data; int fnum; @@ -211,8 +211,10 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, will need to do that once the credentials infrastructure is finalised for Samba4 */ - ep_description.type = NCACN_NP; - ep_description.info.smb_pipe = p->pipe_name; + ep_description.transport = NCACN_NP; + ep_description.options = talloc_array_p(req, char *, 2); + ep_description.options[0] = p->pipe_name; + ep_description.options[1] = NULL; /* tell the RPC layer the session_info */ if (req->session) { -- cgit From 1ec644619d9607758cf090ea904eb2d84500481c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 01:14:49 +0000 Subject: r3126: in the brlock code I had used a void* for the brl context as I didn't want to expose the brl context structure outside the brlock.c code. Instead, I now use "struct brl_context *" and rely on C being happy to pass around pointers to unknown structures as long as they are not dereferenced. I will be interested to see how the build farm likes this. (This used to be commit cb155c8ad837285c5a7f5b104968239df0b65fd2) --- source4/ntvfs/common/brlock.c | 23 +++++++++-------------- source4/ntvfs/posix/vfs_posix.h | 2 +- 2 files changed, 10 insertions(+), 15 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 2da32891fb..607947615e 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -71,8 +71,8 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, - void *messaging_ctx) +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, + void *messaging_ctx) { char *path; struct brl_context *brl; @@ -97,7 +97,7 @@ void *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, brl->messaging_ctx = messaging_ctx; ZERO_STRUCT(brl->last_lock_failure); - return (void *)brl; + return brl; } @@ -219,7 +219,7 @@ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *loc someone else closing an overlapping lock range) a messaging notification is sent, identified by the notify_ptr */ -NTSTATUS brl_lock(void *brl_ctx, +NTSTATUS brl_lock(struct brl_context *brl, DATA_BLOB *file_key, uint16_t smbpid, uint16_t fnum, @@ -227,7 +227,6 @@ NTSTATUS brl_lock(void *brl_ctx, enum brl_type lock_type, void *notify_ptr) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; @@ -248,7 +247,7 @@ NTSTATUS brl_lock(void *brl_ctx, preventing the real lock gets removed */ if (lock_type >= PENDING_READ_LOCK) { enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); - status = brl_lock(brl_ctx, file_key, smbpid, fnum, start, size, rw, NULL); + status = brl_lock(brl, file_key, smbpid, fnum, start, size, rw, NULL); if (NT_STATUS_IS_OK(status)) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_OK; @@ -368,13 +367,12 @@ static void brl_notify_all(struct brl_context *brl, /* Unlock a range of bytes. */ -NTSTATUS brl_unlock(void *brl_ctx, +NTSTATUS brl_unlock(struct brl_context *brl, DATA_BLOB *file_key, uint16_t smbpid, uint16_t fnum, uint64_t start, uint64_t size) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct *locks; @@ -456,11 +454,10 @@ NTSTATUS brl_unlock(void *brl_ctx, given up trying to establish a lock or when they have succeeded in getting it. In either case they no longer need to be notified. */ -NTSTATUS brl_remove_pending(void *brl_ctx, +NTSTATUS brl_remove_pending(struct brl_context *brl, DATA_BLOB *file_key, void *notify_ptr) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct *locks; @@ -526,14 +523,13 @@ NTSTATUS brl_remove_pending(void *brl_ctx, /* Test if we are allowed to perform IO on a region of an open file */ -NTSTATUS brl_locktest(void *brl_ctx, +NTSTATUS brl_locktest(struct brl_context *brl, DATA_BLOB *file_key, uint16_t fnum, uint16 smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; @@ -573,10 +569,9 @@ NTSTATUS brl_locktest(void *brl_ctx, /* Remove any locks associated with a open file. */ -NTSTATUS brl_close(void *brl_ctx, +NTSTATUS brl_close(struct brl_context *brl, DATA_BLOB *file_key, int fnum) { - struct brl_context *brl = brl_ctx; TDB_DATA kbuf, dbuf; int count, i, dcount=0; struct lock_struct *locks; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index ae601c60c7..a0aacf3786 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -36,7 +36,7 @@ struct pvfs_state { struct pvfs_mangle_context *mangle_ctx; - void *brl_context; + struct brl_context *brl_context; /* an id tree mapping open search ID to a pvfs_search_state structure */ void *idtree_search; -- cgit From 1cd1b172d52a1fb336cd001ac0ca2fbf7e26a9a3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 01:19:07 +0000 Subject: r3127: added the initial code for the open files database. Doesn't do anything yet, but will soon be the core of the shares modes code. (This used to be commit ad1edabf95c6c331aac4f0caa7d31193e26bc176) --- source4/ntvfs/common/opendb.c | 145 ++++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/vfs_posix.c | 8 +++ source4/ntvfs/posix/vfs_posix.h | 1 + 4 files changed, 155 insertions(+) create mode 100644 source4/ntvfs/common/opendb.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c new file mode 100644 index 0000000000..cf0177e333 --- /dev/null +++ b/source4/ntvfs/common/opendb.c @@ -0,0 +1,145 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + this is the open files database. It implements shared storage of + what files are open between server instances, and implements the rules + of shared access to files. + + The caller needs to provide a file_key, which specifies what file + they are talking about. This needs to be a unique key across all + filesystems, and is usually implemented in terms of a device/inode + pair. + + Before any operations can be performed the caller needs to establish + a lock on the record associated with file_key. That is done by + calling odb_lock(). The caller releases this lock by calling + talloc_free() on the returned handle. + + All other operations on a record are done by passing the odb_lock() + handle back to this module. The handle contains internal + intformation about what file_key is being operated on. +*/ + +#include "includes.h" + +struct odb_context { + struct tdb_wrap *w; + servid_t server; + uint16_t tid; + void *messaging_ctx; +}; + +/* + the database is indexed by a file_key, and contains entries of the + following form +*/ +struct odb_entry { + servid_t server; + uint16_t tid; + uint16_t fnum; + uint32_t share_access; + uint32_t desired_access; + uint32_t create_options; +}; + + +/* + an odb lock handle. You must obtain one of these using odb_lock() before doing + any other operations. +*/ +struct odb_lock { + struct odb_context *odb; + TDB_DATA key; +}; + +/* + Open up the openfiles.tdb database. Close it down using + talloc_free(). We need the messaging_ctx to allow for pending open + notifications. +*/ +struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, + void *messaging_ctx) +{ + char *path; + struct odb_context *odb; + + odb = talloc_p(mem_ctx, struct odb_context); + if (odb == NULL) { + return NULL; + } + + path = lock_path(odb, "openfiles.tdb"); + odb->w = tdb_wrap_open(odb, path, 0, + TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, 0600); + talloc_free(path); + if (odb->w == NULL) { + talloc_free(odb); + return NULL; + } + + odb->server = server; + odb->tid = tid; + odb->messaging_ctx = messaging_ctx; + + return odb; +} + +/* + destroy a lock on the database +*/ +static int odb_lock_destructor(void *ptr) +{ + struct odb_lock *lck = ptr; + tdb_chainunlock(lck->odb->w->tdb, lck->key); + return 0; +} + +/* + get a lock on a entry in the odb. This call returns a lock handle, + which the caller should unlock using talloc_free(). +*/ +struct odb_lock *odb_lock(struct odb_context *odb, DATA_BLOB *file_key) +{ + struct odb_lock *lck; + + lck = talloc_p(odb, struct odb_lock); + if (lck == NULL) { + return NULL; + } + + lck->odb = odb; + lck->key.dptr = talloc_memdup(lck, file_key->data, file_key->length); + lck->key.dsize = file_key->length; + if (lck->key.dptr == NULL) { + talloc_free(lck); + return NULL; + } + + if (tdb_chainlock(odb->w->tdb, lck->key) != 0) { + talloc_free(lck); + return NULL; + } + + talloc_set_destructor(lck, odb_lock_destructor); + + return lck; +} diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index b6ba073a99..0d6f295097 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -22,6 +22,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_shortname.o \ ntvfs/posix/pvfs_lock.o \ ntvfs/posix/pvfs_wait.o \ + ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 8aa028919c..383dbf7a16 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -94,6 +94,14 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + pvfs->odb_context = odb_init(pvfs, + pvfs->tcon->smb_conn->connection->server_id, + pvfs->tcon->service, + pvfs->tcon->smb_conn->connection->messaging_ctx); + if (pvfs->odb_context == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + /* allocate the fnum id -> ptr tree */ pvfs->idtree_fnum = idr_init(pvfs); if (pvfs->idtree_fnum == NULL) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index a0aacf3786..5b6685b753 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -37,6 +37,7 @@ struct pvfs_state { struct pvfs_mangle_context *mangle_ctx; struct brl_context *brl_context; + struct odb_context *odb_context; /* an id tree mapping open search ID to a pvfs_search_state structure */ void *idtree_search; -- cgit From e51ae38d7b921f05ee3094ce68dfdd05bb8a5099 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 22 Oct 2004 04:48:24 +0000 Subject: r3129: typo (This used to be commit f9dfd5ff1fcfd21fee9b08993b5fe6a6fae7f9d5) --- source4/ntvfs/common/opendb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index cf0177e333..63d3eacf8e 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -35,7 +35,7 @@ All other operations on a record are done by passing the odb_lock() handle back to this module. The handle contains internal - intformation about what file_key is being operated on. + information about what file_key is being operated on. */ #include "includes.h" -- cgit From 651f3903f0a380a951bfe5bf80322f1ab2330705 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 06:49:27 +0000 Subject: r3131: - make map_nt_error_from_unix() return NT_STATUS_UNSUCCESSFUL if errno is 0 - more consistent checking for system call return values in simple backend (This used to be commit 375a9a1347abf0b917cf94ea0cabcdea37d60e98) --- source4/ntvfs/simple/vfs_simple.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index f72d557b58..faf8f17b78 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -262,8 +262,6 @@ static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); if (stat(unix_path, &st) == -1) { DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); - if (errno == 0) - errno = ENOENT; return map_nt_error_from_unix(errno); } DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); @@ -290,8 +288,6 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, } if (fstat(info->generic.in.fnum, &st) == -1) { - if (errno == 0) - errno = ENOENT; return map_nt_error_from_unix(errno); } @@ -372,15 +368,11 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, do_open: fd = open(unix_path, flags, 0644); if (fd == -1) { - if (errno == 0) - errno = ENOENT; return map_nt_error_from_unix(errno); } if (fstat(fd, &st) == -1) { DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); - if (errno == 0) - errno = ENOENT; close(fd); return map_nt_error_from_unix(errno); } @@ -465,7 +457,7 @@ static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, unix_path1 = svfs_unix_path(ntvfs, req, ren->rename.in.pattern1); unix_path2 = svfs_unix_path(ntvfs, req, ren->rename.in.pattern2); - if (rename(unix_path1, unix_path2) != 0) { + if (rename(unix_path1, unix_path2) == -1) { return map_nt_error_from_unix(errno); } @@ -593,7 +585,7 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (close(io->close.in.fnum) != 0) { + if (close(io->close.in.fnum) == -1) { return map_nt_error_from_unix(errno); } @@ -669,7 +661,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: if (ftruncate(info->end_of_file_info.file.fnum, - info->end_of_file_info.in.size) != 0) { + info->end_of_file_info.in.size) == -1) { return map_nt_error_from_unix(errno); } break; @@ -752,7 +744,7 @@ static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, return ntvfs_map_fsattr(req, fs, ntvfs); } - if (stat(private->connectpath, &st) != 0) { + if (stat(private->connectpath, &st) == -1) { return map_nt_error_from_unix(errno); } -- cgit From 6e8867bff5ac95a7f509e3fdc60183cc64d921eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 06:53:18 +0000 Subject: r3132: - fixed a type conflict found by talloc_array_p() - use struct idr_context * in ipc code (This used to be commit c33cdd0d550fcaf78573e73b50ffe530ea6d9b17) --- source4/ntvfs/ipc/vfs_ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index dc50f1671e..2109fb829e 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -31,7 +31,7 @@ ipc$ connection. It needs to keep information about all open pipes */ struct ipc_private { - void *idtree_fnum; + struct idr_context *idtree_fnum; /* a list of open pipes */ struct pipe_state { @@ -212,7 +212,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, finalised for Samba4 */ ep_description.transport = NCACN_NP; - ep_description.options = talloc_array_p(req, char *, 2); + ep_description.options = talloc_array_p(req, const char *, 2); ep_description.options[0] = p->pipe_name; ep_description.options[1] = NULL; -- cgit From f71e7ae1e34510081c393f5ae73a279e8c4d0641 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 06:55:18 +0000 Subject: r3133: - more consistent error checking in rename and setfileinfo - add paranoid checking of device/inode change during open to detect race conditions (This used to be commit 043361fed487ed494fa497ffde1007b3f3bc0c29) --- source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_resolve.c | 19 +++++++++++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 51393c9499..80b6a510b0 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -62,7 +62,7 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - if (rename(name1->full_name, name2->full_name) != 0) { + if (rename(name1->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 97068c3d03..5b86cd3a73 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -364,10 +364,29 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, struct pvfs_filename *name) { + dev_t device; + ino_t inode; + + if (name->exists) { + device = name->st.st_dev; + inode = name->st.st_ino; + } + if (fstat(fd, &name->st) == -1) { return NT_STATUS_INVALID_HANDLE; } + if (name->exists && + (device != name->st.st_dev || inode != name->st.st_ino)) { + /* the file we are looking at has changed! this could + be someone trying to exploit a race + condition. Certainly we don't want to continue + operating on this file */ + DEBUG(0,("pvfs: WARNING: file '%s' changed during resole - failing\n", + name->full_name)); + return NT_STATUS_UNEXPECTED_IO_ERROR; + } + name->exists = True; return pvfs_fill_dos_info(pvfs, name); diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index f1d5d14089..8892c92c3c 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -43,7 +43,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: if (ftruncate(f->fd, - info->end_of_file_info.in.size) != 0) { + info->end_of_file_info.in.size) == -1) { return pvfs_map_errno(pvfs, errno); } break; -- cgit From 020b38656016d3adeeaa9b09d41ea0c29f686ed4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Oct 2004 07:01:32 +0000 Subject: r3135: split the "create new" logic out from the "open existing" logic in pvfs_open, and handle the various race conditions that are inherent in cifs on unix, so we do the best we can when the race happens. the ntcreatex code is really starting to take shape now (This used to be commit 395c3815b468ae55de9a1135e478711f0e7d8cfc) --- source4/ntvfs/common/opendb.c | 5 +- source4/ntvfs/posix/pvfs_open.c | 213 +++++++++++++++++++++++++++++++++++----- source4/ntvfs/posix/vfs_posix.h | 4 +- 3 files changed, 191 insertions(+), 31 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 63d3eacf8e..3b80145414 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -117,11 +117,12 @@ static int odb_lock_destructor(void *ptr) get a lock on a entry in the odb. This call returns a lock handle, which the caller should unlock using talloc_free(). */ -struct odb_lock *odb_lock(struct odb_context *odb, DATA_BLOB *file_key) +struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, + struct odb_context *odb, DATA_BLOB *file_key) { struct odb_lock *lck; - lck = talloc_p(odb, struct odb_lock); + lck = talloc_p(mem_ctx, struct odb_lock); if (lck == NULL) { return NULL; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index eb5b94e753..a16fbbe891 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -183,10 +183,133 @@ static int pvfs_fd_destructor(void *p) return 0; } + +/* + form the lock context used for byte range locking and opendb + locking. Note that we must zero here to take account of + possible padding on some architectures +*/ +static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, + TALLOC_CTX *mem_ctx, DATA_BLOB *key) +{ + struct { + dev_t device; + ino_t inode; + } lock_context; + ZERO_STRUCT(lock_context); + + lock_context.device = name->st.st_dev; + lock_context.inode = name->st.st_ino; + + *key = data_blob_talloc(mem_ctx, &lock_context, sizeof(lock_context)); + if (key->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + + +/* + create a new file +*/ +static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + union smb_open *io) +{ + struct pvfs_file *f; + NTSTATUS status; + int flags, fnum, fd; + struct odb_lock *lck; + + flags = O_RDWR; + + f = talloc_p(req, struct pvfs_file); + if (f == NULL) { + return NT_STATUS_NO_MEMORY; + } + + fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + if (fnum == -1) { + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + + /* create the file */ + fd = open(name->full_name, flags | O_CREAT | O_EXCL, 0644); + if (fd == -1) { + idr_remove(pvfs->idtree_fnum, fnum); + return pvfs_map_errno(pvfs, errno); + } + + /* re-resolve the open fd */ + status = pvfs_resolve_name_fd(pvfs, fd, name); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + return status; + } + + /* form the lock context used for byte range locking and + opendb locking */ + status = pvfs_locking_key(name, f, &f->locking_key); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + return status; + } + + /* grab a lock on the open file record */ + lck = odb_lock(req, pvfs->odb_context, &f->locking_key); + if (lck == NULL) { + DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", + name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + idr_remove(pvfs->idtree_fnum, fnum); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + f->fnum = fnum; + f->fd = fd; + f->name = talloc_steal(f, name); + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + + DLIST_ADD(pvfs->open_files, f); + + /* setup a destructor to avoid file descriptor leaks on + abnormal termination */ + talloc_set_destructor(f, pvfs_fd_destructor); + + ZERO_STRUCT(io->generic.out); + + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.fnum = f->fnum; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.create_action = NTCREATEX_ACTION_CREATED; + io->generic.out.is_directory = 0; + io->generic.out.file_type = FILE_TYPE_DISK; + + /* success - keep the file handle */ + talloc_steal(pvfs, f); + + /* release the opendb lock (in case a chained request + blocks) */ + talloc_free(lck); + + return NT_STATUS_OK; +} + + /* open a file - TODO: this is a temporary implementation derived from the simple backend - its purpose is to allow other tests to run */ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_open *io) @@ -196,12 +319,14 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; struct pvfs_file *f; NTSTATUS status; - struct { - dev_t device; - ino_t inode; - } lock_context; int fnum; + struct odb_lock *lck; + /* use the generic mapping code to avoid implementing all the + different open calls. This won't allow openx to work + perfectly as the mapping code has no way of knowing if two + opens are on the same connection, so this will need to + change eventually */ if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(req, io, ntvfs); } @@ -229,7 +354,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, break; case NTCREATEX_DISP_OVERWRITE_IF: - flags = O_CREAT | O_TRUNC; + flags = O_TRUNC; break; case NTCREATEX_DISP_OPEN: @@ -250,11 +375,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, if (name->exists) { return NT_STATUS_OBJECT_NAME_COLLISION; } - flags = O_CREAT | O_EXCL; + flags = 0; break; case NTCREATEX_DISP_OPEN_IF: - flags = O_CREAT; + flags = 0; break; default: @@ -263,32 +388,67 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, flags |= O_RDWR; + /* handle creating a new file separately */ + if (!name->exists) { + status = pvfs_create_file(pvfs, req, name, io); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + return status; + } + + /* we've hit a race - the file was created during this call */ + if (io->generic.in.open_disposition == NTCREATEX_DISP_CREATE) { + return status; + } + + /* try re-resolving the name */ + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* fall through to a normal open */ + } + f = talloc_p(req, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; + /* form the lock context used for byte range locking and + opendb locking */ + status = pvfs_locking_key(name, f, &f->locking_key); + if (!NT_STATUS_IS_OK(status)) { + return status; } - fd = open(name->full_name, flags, 0644); + /* get a lock on this file before the actual open */ + lck = odb_lock(req, pvfs->odb_context, &f->locking_key); + if (lck == NULL) { + DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", + name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* do the actual open */ + fd = open(name->full_name, flags); if (fd == -1) { - if (errno == 0) { - errno = ENOENT; - } - idr_remove(pvfs->idtree_fnum, fnum); return pvfs_map_errno(pvfs, errno); } /* re-resolve the open fd */ status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); return status; } + /* allocate a fnum */ + fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + if (fnum == -1) { + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + f->fnum = fnum; f->fd = fd; f->name = talloc_steal(f, name); @@ -298,18 +458,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->pending_list = NULL; f->lock_count = 0; - /* we must zero here to take account of padding */ - ZERO_STRUCT(lock_context); - lock_context.device = name->st.st_dev; - lock_context.inode = name->st.st_ino; - f->locking_key = data_blob_talloc(f, &lock_context, sizeof(lock_context)); + DLIST_ADD(pvfs->open_files, f); /* setup a destructor to avoid file descriptor leaks on abnormal termination */ talloc_set_destructor(f, pvfs_fd_destructor); - DLIST_ADD(pvfs->open_files, f); - ZERO_STRUCT(io->generic.out); io->generic.out.create_time = name->dos.create_time; @@ -320,11 +474,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, io->generic.out.alloc_size = name->dos.alloc_size; io->generic.out.size = name->st.st_size; io->generic.out.attrib = name->dos.attrib; - io->generic.out.is_directory = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)?1:0; + io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; + io->generic.out.is_directory = 0; + io->generic.out.file_type = FILE_TYPE_DISK; /* success - keep the file handle */ talloc_steal(pvfs, f); + /* unlock the locking database */ + talloc_free(lck); + return NT_STATUS_OK; } @@ -349,7 +508,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, } if (f->fd != -1 && - close(f->fd) != 0) { + close(f->fd) == -1) { status = pvfs_map_errno(pvfs, errno); } else { status = NT_STATUS_OK; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 5b6685b753..59924b0b1b 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -40,10 +40,10 @@ struct pvfs_state { struct odb_context *odb_context; /* an id tree mapping open search ID to a pvfs_search_state structure */ - void *idtree_search; + struct idr_context *idtree_search; /* an id tree mapping open file handle -> struct pvfs_file */ - void *idtree_fnum; + struct idr_context *idtree_fnum; }; -- cgit From c785ca65040d985599bba6736af55240eae894aa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 23 Oct 2004 06:22:57 +0000 Subject: r3142: fill in all the ntcreatex response fields explicitly, rather than zeroing. This makes it clearer what bits are not yet implemented (and is more valgrind friendly) (This used to be commit 18b471327b596f3ea8f6a7b39ba0a83b2584ed0b) --- source4/ntvfs/posix/pvfs_open.c | 76 ++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 35 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a16fbbe891..482f71b9a3 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -70,6 +70,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, struct pvfs_file *f; int fnum; NTSTATUS status; + uint32_t create_action; /* if the client says it must be a directory, and it isn't, then fail */ @@ -133,6 +134,9 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, if (!NT_STATUS_IS_OK(status)) { return status; } + create_action = NTCREATEX_ACTION_CREATED; + } else { + create_action = NTCREATEX_ACTION_EXISTED; } if (!name->exists) { @@ -144,17 +148,19 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* the open succeeded, keep this handle permanently */ talloc_steal(pvfs, f); - ZERO_STRUCT(io->generic.out); - - io->generic.out.create_time = name->dos.create_time; - io->generic.out.access_time = name->dos.access_time; - io->generic.out.write_time = name->dos.write_time; - io->generic.out.change_time = name->dos.change_time; - io->generic.out.fnum = f->fnum; - io->generic.out.alloc_size = 0; - io->generic.out.size = 0; - io->generic.out.attrib = name->dos.attrib; - io->generic.out.is_directory = 1; + io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.fnum = f->fnum; + io->generic.out.create_action = create_action; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.alloc_size = 0; + io->generic.out.size = 0; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 1; return NT_STATUS_OK; } @@ -283,19 +289,19 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, abnormal termination */ talloc_set_destructor(f, pvfs_fd_destructor); - ZERO_STRUCT(io->generic.out); - - io->generic.out.create_time = name->dos.create_time; - io->generic.out.access_time = name->dos.access_time; - io->generic.out.write_time = name->dos.write_time; - io->generic.out.change_time = name->dos.change_time; - io->generic.out.fnum = f->fnum; - io->generic.out.alloc_size = name->dos.alloc_size; - io->generic.out.size = name->st.st_size; - io->generic.out.attrib = name->dos.attrib; + io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_CREATED; - io->generic.out.is_directory = 0; - io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 0; /* success - keep the file handle */ talloc_steal(pvfs, f); @@ -464,19 +470,19 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, abnormal termination */ talloc_set_destructor(f, pvfs_fd_destructor); - ZERO_STRUCT(io->generic.out); - - io->generic.out.create_time = name->dos.create_time; - io->generic.out.access_time = name->dos.access_time; - io->generic.out.write_time = name->dos.write_time; - io->generic.out.change_time = name->dos.change_time; - io->generic.out.fnum = f->fnum; - io->generic.out.alloc_size = name->dos.alloc_size; - io->generic.out.size = name->st.st_size; - io->generic.out.attrib = name->dos.attrib; + io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; - io->generic.out.is_directory = 0; - io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 0; /* success - keep the file handle */ talloc_steal(pvfs, f); -- cgit From 3d5f3e39e5786612a2aa24ec98264c52907e67f2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Oct 2004 08:31:41 +0000 Subject: r3147: added basic share modes support for pvfs (or more precisely, ntcreatex share_access support). This is enough for us to pass the BASE-DENY2 test, but is a long way from fully correct share modes. (This used to be commit b5a6dd3cbf28a3a3b3a3656042ac8f50fca29e1c) --- source4/ntvfs/common/opendb.c | 139 ++++++++++++++++++++++++++++++++++++++- source4/ntvfs/posix/pvfs_open.c | 131 +++++++++++++++++++++++++----------- source4/ntvfs/posix/pvfs_read.c | 4 ++ source4/ntvfs/posix/pvfs_write.c | 4 ++ source4/ntvfs/posix/vfs_posix.h | 4 ++ 5 files changed, 241 insertions(+), 41 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 3b80145414..f074c31f6e 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -56,8 +56,8 @@ struct odb_entry { uint16_t tid; uint16_t fnum; uint32_t share_access; - uint32_t desired_access; uint32_t create_options; + uint32_t access_mask; }; @@ -144,3 +144,140 @@ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, return lck; } + + +/* + determine if two odb_entry structures conflict +*/ +static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) +{ + uint32_t m1, m2; + + m1 = e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA); + m2 = e2->share_access & + (NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ); + + if ((m1 & m2) != m1) { + return True; + } + + m1 = e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA); + m2 = e1->share_access & + (NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ); + + if ((m1 & m2) != m1) { + return True; + } + + return False; +} + +/* + register an open file in the open files database. This implements the share_access + rules +*/ +NTSTATUS odb_open_file(struct odb_lock *lck, uint16_t fnum, + uint32_t share_access, uint32_t create_options, + uint32_t access_mask) +{ + struct odb_context *odb = lck->odb; + TDB_DATA dbuf; + struct odb_entry e; + char *tp; + int i, count; + struct odb_entry *elist; + + dbuf = tdb_fetch(odb->w->tdb, lck->key); + + e.server = odb->server; + e.tid = odb->tid; + e.fnum = fnum; + e.share_access = share_access; + e.create_options = create_options; + e.access_mask = access_mask; + + /* check the existing file opens to see if they + conflict */ + elist = (struct odb_entry *)dbuf.dptr; + count = dbuf.dsize / sizeof(struct odb_entry); + + for (i=0;iw->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { + free(dbuf.dptr); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + free(dbuf.dptr); + return NT_STATUS_OK; +} + + +/* + remove a opendb entry +*/ +NTSTATUS odb_close_file(struct odb_lock *lck, uint16_t fnum) +{ + struct odb_context *odb = lck->odb; + TDB_DATA dbuf; + struct odb_entry *elist; + int i, count; + NTSTATUS status; + + dbuf = tdb_fetch(odb->w->tdb, lck->key); + + if (dbuf.dptr == NULL) { + return NT_STATUS_UNSUCCESSFUL; + } + + elist = (struct odb_entry *)dbuf.dptr; + count = dbuf.dsize / sizeof(struct odb_entry); + + /* find the entry, and delete it */ + for (i=0;iserver == elist[i].server && + odb->tid == elist[i].tid) { + if (i < count-1) { + memmove(elist+i, elist+i+1, count - (i+1)); + } + break; + } + } + + status = NT_STATUS_OK; + + if (i == count) { + status = NT_STATUS_UNSUCCESSFUL; + } else if (count == 1) { + if (tdb_delete(odb->w->tdb, lck->key) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } else { + dbuf.dsize = (count-1) * sizeof(struct odb_entry); + if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + free(dbuf.dptr); + + return status; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 482f71b9a3..90de303a9d 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -78,30 +78,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_NOT_A_DIRECTORY; } - f = talloc_p(req, struct pvfs_file); - if (f == NULL) { - return NT_STATUS_NO_MEMORY; - } - - fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); - if (fnum == -1) { - talloc_free(f); - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - - f->fnum = fnum; - f->fd = -1; - f->name = talloc_steal(f, name); - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; - f->pending_list = NULL; - f->lock_count = 0; - f->locking_key = data_blob(NULL, 0); - - /* setup a destructor to avoid leaks on abnormal termination */ - talloc_set_destructor(f, pvfs_dir_fd_destructor); - switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_OPEN_IF: break; @@ -125,6 +101,38 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_INVALID_PARAMETER; } + f = talloc_p(req, struct pvfs_file); + if (f == NULL) { + return NT_STATUS_NO_MEMORY; + } + + f->fnum = fnum; + f->fd = -1; + f->name = talloc_steal(f, name); + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->locking_key = data_blob(NULL, 0); + f->create_options = io->generic.in.create_options; + f->share_access = io->generic.in.share_access; + + fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + if (fnum == -1) { + talloc_free(f); + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + + DLIST_ADD(pvfs->open_files, f); + + /* TODO: should we check in the opendb? Do directory opens + follow the share_access rules? */ + + + /* setup a destructor to avoid leaks on abnormal termination */ + talloc_set_destructor(f, pvfs_dir_fd_destructor); + if (!name->exists) { if (mkdir(name->full_name, 0755) == -1) { return pvfs_map_errno(pvfs,errno); @@ -143,8 +151,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - DLIST_ADD(pvfs->open_files, f); - /* the open succeeded, keep this handle permanently */ talloc_steal(pvfs, f); @@ -174,6 +180,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, static int pvfs_fd_destructor(void *p) { struct pvfs_file *f = p; + struct odb_lock *lck; + NTSTATUS status; DLIST_REMOVE(f->pvfs->open_files, f); @@ -186,6 +194,18 @@ static int pvfs_fd_destructor(void *p) idr_remove(f->pvfs->idtree_fnum, f->fnum); + lck = odb_lock(f, f->pvfs->odb_context, &f->locking_key); + if (lck == NULL) { + DEBUG(0,("Unabled to lock opendb for close\n")); + return 0; + } + + status = odb_close_file(lck, f->fnum); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unabled to remove opendb entry for '%s' - %s\n", + f->name->full_name, nt_errstr(status))); + } + return 0; } @@ -228,7 +248,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, NTSTATUS status; int flags, fnum, fd; struct odb_lock *lck; - + uint32_t create_options = io->generic.in.create_options; + uint32_t share_access = io->generic.in.share_access; + uint32_t access_mask = io->generic.in.access_mask; + flags = O_RDWR; f = talloc_p(req, struct pvfs_file); @@ -252,6 +275,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, fnum); + close(fd); return status; } @@ -260,6 +284,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, status = pvfs_locking_key(name, f, &f->locking_key); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, fnum); + close(fd); return status; } @@ -271,9 +296,18 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* we were supposed to do a blocking lock, so something is badly wrong! */ idr_remove(pvfs->idtree_fnum, fnum); + close(fd); return NT_STATUS_INTERNAL_DB_CORRUPTION; } + status = odb_open_file(lck, fnum, share_access, create_options, access_mask); + if (!NT_STATUS_IS_OK(status)) { + /* bad news, we must have hit a race */ + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; + } + f->fnum = fnum; f->fd = fd; f->name = talloc_steal(f, name); @@ -282,6 +316,9 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->pvfs = pvfs; f->pending_list = NULL; f->lock_count = 0; + f->create_options = io->generic.in.create_options; + f->share_access = io->generic.in.share_access; + f->access_mask = io->generic.in.access_mask; DLIST_ADD(pvfs->open_files, f); @@ -306,10 +343,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* success - keep the file handle */ talloc_steal(pvfs, f); - /* release the opendb lock (in case a chained request - blocks) */ - talloc_free(lck); - return NT_STATUS_OK; } @@ -327,6 +360,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, NTSTATUS status; int fnum; struct odb_lock *lck; + uint32_t create_options; + uint32_t share_access; + uint32_t access_mask; /* use the generic mapping code to avoid implementing all the different open calls. This won't allow openx to work @@ -420,10 +456,17 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } + /* allocate a fnum */ + fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + if (fnum == -1) { + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f, &f->locking_key); if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); return status; } @@ -434,9 +477,21 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ + idr_remove(pvfs->idtree_fnum, fnum); return NT_STATUS_INTERNAL_DB_CORRUPTION; } + create_options = io->generic.in.create_options; + share_access = io->generic.in.share_access; + access_mask = io->generic.in.access_mask; + + /* see if we are allowed to open at the same time as existing opens */ + status = odb_open_file(lck, fnum, share_access, create_options, access_mask); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + return status; + } + /* do the actual open */ fd = open(name->full_name, flags); if (fd == -1) { @@ -446,15 +501,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* re-resolve the open fd */ status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { + close(fd); + idr_remove(pvfs->idtree_fnum, fnum); return status; } - /* allocate a fnum */ - fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - f->fnum = fnum; f->fd = fd; f->name = talloc_steal(f, name); @@ -463,6 +514,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->pvfs = pvfs; f->pending_list = NULL; f->lock_count = 0; + f->create_options = io->generic.in.create_options; + f->share_access = io->generic.in.share_access; + f->access_mask = io->generic.in.access_mask; DLIST_ADD(pvfs->open_files, f); @@ -487,9 +541,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* success - keep the file handle */ talloc_steal(pvfs, f); - /* unlock the locking database */ - talloc_free(lck); - return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 7256fd8e16..530fb82798 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -47,6 +47,10 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } + if (!(f->access_mask & SA_RIGHT_FILE_READ_DATA)) { + return NT_STATUS_ACCESS_VIOLATION; + } + status = pvfs_check_lock(pvfs, f, req->smbpid, rd->readx.in.offset, rd->readx.in.maxcnt, diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 8bbb4f8605..a7b7084a08 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -48,6 +48,10 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } + if (!(f->access_mask & SA_RIGHT_FILE_WRITE_DATA)) { + return NT_STATUS_ACCESS_VIOLATION; + } + status = pvfs_check_lock(pvfs, f, req->smbpid, wr->writex.in.offset, wr->writex.in.count, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 59924b0b1b..0bd01f5377 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -121,6 +121,10 @@ struct pvfs_file { /* a count of active locks - used to avoid calling brl_close on file close */ uint64_t lock_count; + + uint32_t create_options; + uint32_t share_access; + uint32_t access_mask; }; -- cgit From d5817271384ff74b3d0577d675476c28ccc0074b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Oct 2004 12:39:15 +0000 Subject: r3153: pvfs now passes the first 9 of the BASE-DELETE tests (This used to be commit f8041feaebc9170763ce04d2dd90cfc1c7889c21) --- source4/ntvfs/common/opendb.c | 56 +++++++++++++++++- source4/ntvfs/posix/pvfs_open.c | 102 ++++++++++++++++++++++++--------- source4/ntvfs/posix/pvfs_setfileinfo.c | 13 +++++ 3 files changed, 143 insertions(+), 28 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index f074c31f6e..3def23f190 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -169,6 +169,17 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) return True; } + if ((e1->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) || + (e2->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + return True; + } + + if ((e1->access_mask & STD_RIGHT_DELETE_ACCESS) && + !(e2->share_access & NTCREATEX_SHARE_ACCESS_DELETE)) { + return True; + } + + return False; } @@ -256,7 +267,8 @@ NTSTATUS odb_close_file(struct odb_lock *lck, uint16_t fnum) odb->server == elist[i].server && odb->tid == elist[i].tid) { if (i < count-1) { - memmove(elist+i, elist+i+1, count - (i+1)); + memmove(elist+i, elist+i+1, + (count - (i+1)) * sizeof(struct odb_entry)); } break; } @@ -281,3 +293,45 @@ NTSTATUS odb_close_file(struct odb_lock *lck, uint16_t fnum) return status; } + + +/* + update create options on an open file +*/ +NTSTATUS odb_set_create_options(struct odb_lock *lck, + uint16_t fnum, uint32_t create_options) +{ + struct odb_context *odb = lck->odb; + TDB_DATA dbuf; + struct odb_entry *elist; + int i, count; + NTSTATUS status; + + dbuf = tdb_fetch(odb->w->tdb, lck->key); + if (dbuf.dptr == NULL) { + return NT_STATUS_UNSUCCESSFUL; + } + + elist = (struct odb_entry *)dbuf.dptr; + count = dbuf.dsize / sizeof(struct odb_entry); + + /* find the entry, and modify it */ + for (i=0;iserver == elist[i].server && + odb->tid == elist[i].tid) { + elist[i].create_options = create_options; + break; + } + } + + if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } else { + status = NT_STATUS_OK; + } + + free(dbuf.dptr); + + return status; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 90de303a9d..7c1e164575 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -55,6 +55,14 @@ static int pvfs_dir_fd_destructor(void *p) struct pvfs_file *f = p; DLIST_REMOVE(f->pvfs->open_files, f); idr_remove(f->pvfs->idtree_fnum, f->fnum); + + if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (rmdir(f->name->full_name) != 0) { + DEBUG(0,("pvfs_close: failed to rmdir '%s'\n", + f->name->full_name)); + } + } + return 0; } @@ -106,6 +114,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } + fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + if (fnum == -1) { + talloc_free(f); + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + f->fnum = fnum; f->fd = -1; f->name = talloc_steal(f, name); @@ -118,12 +132,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; - fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); - if (fnum == -1) { - talloc_free(f); - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - DLIST_ADD(pvfs->open_files, f); /* TODO: should we check in the opendb? Do directory opens @@ -196,16 +204,23 @@ static int pvfs_fd_destructor(void *p) lck = odb_lock(f, f->pvfs->odb_context, &f->locking_key); if (lck == NULL) { - DEBUG(0,("Unabled to lock opendb for close\n")); + DEBUG(0,("Unable to lock opendb for close\n")); return 0; } status = odb_close_file(lck, f->fnum); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Unabled to remove opendb entry for '%s' - %s\n", + DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", f->name->full_name, nt_errstr(status))); } + if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (unlink(f->name->full_name) != 0) { + DEBUG(0,("pvfs_close: failed to delete '%s'\n", + f->name->full_name)); + } + } + return 0; } @@ -386,6 +401,15 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return pvfs_open_directory(pvfs, req, name, io); } + create_options = io->generic.in.create_options; + share_access = io->generic.in.share_access; + access_mask = io->generic.in.access_mask; + + /* certain create options are not allowed */ + if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + !(share_access & NTCREATEX_SHARE_ACCESS_DELETE)) { + return NT_STATUS_INVALID_PARAMETER; + } switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: @@ -481,10 +505,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - create_options = io->generic.in.create_options; - share_access = io->generic.in.share_access; - access_mask = io->generic.in.access_mask; - /* see if we are allowed to open at the same time as existing opens */ status = odb_open_file(lck, fnum, share_access, create_options, access_mask); if (!NT_STATUS_IS_OK(status)) { @@ -492,22 +512,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } - /* do the actual open */ - fd = open(name->full_name, flags); - if (fd == -1) { - return pvfs_map_errno(pvfs, errno); - } - - /* re-resolve the open fd */ - status = pvfs_resolve_name_fd(pvfs, fd, name); - if (!NT_STATUS_IS_OK(status)) { - close(fd); - idr_remove(pvfs->idtree_fnum, fnum); - return status; - } - f->fnum = fnum; - f->fd = fd; + f->fd = -1; f->name = talloc_steal(f, name); f->session = req->session; f->smbpid = req->smbpid; @@ -524,6 +530,20 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, abnormal termination */ talloc_set_destructor(f, pvfs_fd_destructor); + /* do the actual open */ + fd = open(name->full_name, flags); + if (fd == -1) { + return pvfs_map_errno(pvfs, errno); + } + + f->fd = fd; + + /* re-resolve the open fd */ + status = pvfs_resolve_name_fd(pvfs, fd, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + io->generic.out.oplock_level = NO_OPLOCK; io->generic.out.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; @@ -619,3 +639,31 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } + + +/* + change the create options on an already open file +*/ +NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_file *f, uint32_t create_options) +{ + struct odb_lock *lck; + NTSTATUS status; + + if (f->create_options == create_options) { + return NT_STATUS_OK; + } + + lck = odb_lock(req, pvfs->odb_context, &f->locking_key); + if (lck == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = odb_set_create_options(lck, f->fnum, create_options); + if (NT_STATUS_IS_OK(status)) { + f->create_options = create_options; + } + + return status; +} diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 8892c92c3c..0de87b8584 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -33,6 +33,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct utimbuf unix_times; struct pvfs_file *f; + uint32_t create_options; f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); if (!f) { @@ -65,6 +66,18 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } break; + case RAW_SFILEINFO_DISPOSITION_INFO: + if (!(f->access_mask & STD_RIGHT_DELETE_ACCESS)) { + return NT_STATUS_ACCESS_DENIED; + } + create_options = f->create_options; + if (info->disposition_info.in.delete_on_close) { + create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + } else { + create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + } + return pvfs_change_create_options(pvfs, req, f, create_options); } + return NT_STATUS_OK; } -- cgit From 2a16fd5453a47bc456ae831c0eab58a102d96bd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Oct 2004 12:53:13 +0000 Subject: r3154: pvfs now passes all of BASE-DELETE (This used to be commit abbfca1401818edd896493ab9c875224e3b7e0e7) --- source4/ntvfs/posix/pvfs_open.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 7c1e164575..95990f6332 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -266,6 +266,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t create_options = io->generic.in.create_options; uint32_t share_access = io->generic.in.share_access; uint32_t access_mask = io->generic.in.access_mask; + mode_t mode; + + if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && + (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + return NT_STATUS_CANNOT_DELETE; + } flags = O_RDWR; @@ -279,8 +285,14 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } + if (io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) { + mode = 0444; + } else { + mode = 0644; + } + /* create the file */ - fd = open(name->full_name, flags | O_CREAT | O_EXCL, 0644); + fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode); if (fd == -1) { idr_remove(pvfs->idtree_fnum, fnum); return pvfs_map_errno(pvfs, errno); @@ -407,7 +419,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* certain create options are not allowed */ if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - !(share_access & NTCREATEX_SHARE_ACCESS_DELETE)) { + !(access_mask & STD_RIGHT_DELETE_ACCESS)) { return NT_STATUS_INVALID_PARAMETER; } @@ -475,6 +487,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* fall through to a normal open */ } + if ((name->dos.attrib & FILE_ATTRIBUTE_READONLY) && + (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + return NT_STATUS_CANNOT_DELETE; + } + f = talloc_p(req, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; @@ -655,6 +672,11 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, return NT_STATUS_OK; } + if ((f->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && + (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + return NT_STATUS_CANNOT_DELETE; + } + lck = odb_lock(req, pvfs->odb_context, &f->locking_key); if (lck == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; -- cgit From 5ea5d5c2355eb0789131cd5d9ffffc5b004b02c8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Oct 2004 13:40:49 +0000 Subject: r3159: use easy to recognise file handle numbers for new file, old file and directory in pvfs_open, to make analysing sniffs easy (This used to be commit 5c16ed02542f7e143d66f4ba8d166bb6882bf53a) --- source4/ntvfs/posix/pvfs_open.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 95990f6332..44a09fe25d 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -23,6 +23,12 @@ #include "include/includes.h" #include "vfs_posix.h" +/* + create file handles with convenient numbers for sniffers +*/ +#define PVFS_MIN_FILE_FNUM 0x100 +#define PVFS_MIN_NEW_FNUM 0x200 +#define PVFS_MIN_DIR_FNUM 0x1000 /* find open file handle given fnum @@ -114,7 +120,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); if (fnum == -1) { talloc_free(f); return NT_STATUS_TOO_MANY_OPENED_FILES; @@ -202,6 +208,13 @@ static int pvfs_fd_destructor(void *p) idr_remove(f->pvfs->idtree_fnum, f->fnum); + if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (unlink(f->name->full_name) != 0) { + DEBUG(0,("pvfs_close: failed to delete '%s'\n", + f->name->full_name)); + } + } + lck = odb_lock(f, f->pvfs->odb_context, &f->locking_key); if (lck == NULL) { DEBUG(0,("Unable to lock opendb for close\n")); @@ -214,12 +227,7 @@ static int pvfs_fd_destructor(void *p) f->name->full_name, nt_errstr(status))); } - if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { - if (unlink(f->name->full_name) != 0) { - DEBUG(0,("pvfs_close: failed to delete '%s'\n", - f->name->full_name)); - } - } + talloc_free(lck); return 0; } @@ -280,7 +288,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_NEW_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } @@ -498,7 +506,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* allocate a fnum */ - fnum = idr_get_new(pvfs->idtree_fnum, f, UINT16_MAX); + fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_FILE_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } -- cgit From 36e32628468ca4b84f06d45698771a6903b5c47f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Oct 2004 13:41:27 +0000 Subject: r3160: recognise RAW_SFILEINFO_DISPOSITION_INFORMATION (fixes temporary files from excel) (This used to be commit 1c05147f7103127c11b06bb0a812970577ace5f6) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 0de87b8584..74b0ed85c5 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -48,6 +48,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } break; + case RAW_SFILEINFO_SETATTRE: unix_times.actime = info->setattre.in.access_time; unix_times.modtime = info->setattre.in.write_time; @@ -66,7 +67,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } break; + case RAW_SFILEINFO_DISPOSITION_INFO: + case RAW_SFILEINFO_DISPOSITION_INFORMATION: if (!(f->access_mask & STD_RIGHT_DELETE_ACCESS)) { return NT_STATUS_ACCESS_DENIED; } -- cgit From 62e58ea7180e265ffe79b998e7488f20909d3fa0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Oct 2004 14:18:03 +0000 Subject: r3161: pvfs now passes the RAW-SEEK test (This used to be commit a953d4a42c8fa3fe930c319d5157fc406a1035da) --- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_open.c | 6 +++ source4/ntvfs/posix/pvfs_qfileinfo.c | 6 ++- source4/ntvfs/posix/pvfs_read.c | 2 + source4/ntvfs/posix/pvfs_seek.c | 62 +++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 67 ++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_write.c | 2 + source4/ntvfs/posix/vfs_posix.c | 20 ---------- source4/ntvfs/posix/vfs_posix.h | 4 ++ 9 files changed, 149 insertions(+), 21 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_seek.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 0d6f295097..8d28bd5a44 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -22,6 +22,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_shortname.o \ ntvfs/posix/pvfs_lock.o \ ntvfs/posix/pvfs_wait.o \ + ntvfs/posix/pvfs_seek.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 44a09fe25d..e587ebbf95 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -137,6 +137,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->locking_key = data_blob(NULL, 0); f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; + f->seek_offset = 0; + f->position = 0; DLIST_ADD(pvfs->open_files, f); @@ -354,6 +356,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; f->access_mask = io->generic.in.access_mask; + f->seek_offset = 0; + f->position = 0; DLIST_ADD(pvfs->open_files, f); @@ -548,6 +552,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; f->access_mask = io->generic.in.access_mask; + f->seek_offset = 0; + f->position = 0; DLIST_ADD(pvfs->open_files, f); diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 78d0983bf6..1a6ff0ae26 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -127,5 +127,9 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, return status; } - return pvfs_map_fileinfo(pvfs, req, f->name, info); + status = pvfs_map_fileinfo(pvfs, req, f->name, info); + + info->generic.out.position = f->position; + + return status; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 530fb82798..eb821d1f31 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -67,6 +67,8 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } + f->position = f->seek_offset = rd->readx.in.offset + ret; + rd->readx.out.nread = ret; rd->readx.out.remaining = 0; /* should fill this in? */ rd->readx.out.compaction_mode = 0; diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c new file mode 100644 index 0000000000..f965e584ee --- /dev/null +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -0,0 +1,62 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - seek + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + seek in a file +*/ +NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + NTSTATUS status; + + f = pvfs_find_fd(pvfs, req, io->in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + status = NT_STATUS_OK; + + switch (io->in.mode) { + case SEEK_MODE_START: + f->seek_offset = io->in.offset; + break; + + case SEEK_MODE_CURRENT: + f->seek_offset += io->in.offset; + break; + + case SEEK_MODE_END: + status = pvfs_resolve_name_fd(pvfs, f->fd, f->name); + f->seek_offset = f->name->st.st_size + io->in.offset; + break; + } + + io->out.offset = f->seek_offset; + + return status; +} + diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 74b0ed85c5..42ee8a971c 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -80,7 +80,74 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE; } return pvfs_change_create_options(pvfs, req, f, create_options); + + case RAW_SFILEINFO_POSITION_INFORMATION: + f->position = info->position_information.in.position; + break; } return NT_STATUS_OK; } + + +/* + set info on a pathname +*/ +NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_filename *name; + NTSTATUS status; + struct utimbuf unix_times; + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + switch (info->generic.level) { + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + if (truncate(name->full_name, + info->end_of_file_info.in.size) == -1) { + return pvfs_map_errno(pvfs, errno); + } + break; + + case RAW_SFILEINFO_SETATTRE: + unix_times.actime = info->setattre.in.access_time; + unix_times.modtime = info->setattre.in.write_time; + + if (unix_times.actime == 0 && unix_times.modtime == 0) { + break; + } + + /* set modify time = to access time if modify time was 0 */ + if (unix_times.actime != 0 && unix_times.modtime == 0) { + unix_times.modtime = unix_times.actime; + } + + /* Set the date on this file */ + if (utime(name->full_name, &unix_times) == -1) { + return NT_STATUS_ACCESS_DENIED; + } + break; + + case RAW_SFILEINFO_DISPOSITION_INFO: + case RAW_SFILEINFO_DISPOSITION_INFORMATION: + return NT_STATUS_INVALID_PARAMETER; + + case RAW_SFILEINFO_POSITION_INFORMATION: + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; +} + diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index a7b7084a08..7ab1d340bd 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -67,6 +67,8 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, if (ret == -1) { return map_nt_error_from_unix(errno); } + + f->seek_offset = wr->writex.in.offset + ret; wr->writex.out.nwritten = ret; wr->writex.out.remaining = 0; /* should fill this in? */ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 383dbf7a16..64f0e09f59 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -179,26 +179,6 @@ static NTSTATUS pvfs_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } -/* - seek in a file -*/ -static NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) -{ - DEBUG(0,("pvfs_seek not implemented\n")); - return NT_STATUS_NOT_SUPPORTED; -} - -/* - set info on a pathname -*/ -static NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) -{ - DEBUG(0,("pvfs_setpathinfo not implemented\n")); - return NT_STATUS_NOT_SUPPORTED; -} - /* return print queue info */ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 0bd01f5377..d4c0b19974 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -125,6 +125,10 @@ struct pvfs_file { uint32_t create_options; uint32_t share_access; uint32_t access_mask; + + /* yes, we need 2 independent positions ... */ + uint64_t seek_offset; + uint64_t position; }; -- cgit From 06b3879c8fec97ef5de9b969301611e28fff00de Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 24 Oct 2004 22:46:47 +0000 Subject: r3167: Add a member 'endpoint' to the dcerpc_binding struct to use instead of options[0]. (This used to be commit 18582083af800abd3d8de40eb73255c8ae6598dd) --- source4/ntvfs/ipc/vfs_ipc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2109fb829e..dcbfdb948f 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -212,9 +212,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, finalised for Samba4 */ ep_description.transport = NCACN_NP; - ep_description.options = talloc_array_p(req, const char *, 2); - ep_description.options[0] = p->pipe_name; - ep_description.options[1] = NULL; + ep_description.endpoint = p->pipe_name; /* tell the RPC layer the session_info */ if (req->session) { -- cgit From 06d9380114aef28969edbd9782f6aa528343b493 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 01:16:04 +0000 Subject: r3172: much better qfileinfo implementation in pvfs. We now pass RAW-QFILEINFO (This used to be commit 65c2c81b8cf6aeeccdc53d8145c2595f230bd531) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 231 +++++++++++++++++++++++++++-------- 1 file changed, 179 insertions(+), 52 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 1a6ff0ae26..04c196121a 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -30,49 +30,152 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, struct pvfs_filename *name, union smb_fileinfo *info) { - info->generic.out.create_time = name->dos.create_time; - info->generic.out.access_time = name->dos.access_time; - info->generic.out.write_time = name->dos.write_time; - info->generic.out.change_time = name->dos.change_time; - - info->generic.out.alloc_size = name->dos.alloc_size; - info->generic.out.size = name->st.st_size; - info->generic.out.attrib = name->dos.attrib; - info->generic.out.nlink = name->dos.nlink; - info->generic.out.directory = (name->dos.attrib&FILE_ATTRIBUTE_DIRECTORY)?1:0; - info->generic.out.file_id = name->dos.file_id; - - /* REWRITE: TODO stuff in here */ - info->generic.out.delete_pending = 0; - info->generic.out.ea_size = 0; - info->generic.out.num_eas = 0; - info->generic.out.fname.s = name->original_name; - info->generic.out.alt_fname.s = pvfs_short_name(pvfs, name, name); - info->generic.out.compressed_size = name->st.st_size; - info->generic.out.format = 0; - info->generic.out.unit_shift = 0; - info->generic.out.chunk_shift = 0; - info->generic.out.cluster_shift = 0; - - info->generic.out.access_flags = 0; - info->generic.out.position = 0; - info->generic.out.mode = 0; - info->generic.out.alignment_requirement = 0; - info->generic.out.reparse_tag = 0; - - /* setup a single data stream */ - info->generic.out.num_streams = 1; - info->generic.out.streams = talloc_array_p(mem_ctx, - struct stream_struct, - info->generic.out.num_streams); - if (!info->generic.out.streams) { - return NT_STATUS_NO_MEMORY; + switch (info->generic.level) { + case RAW_FILEINFO_GETATTR: + info->getattr.out.attrib = name->dos.attrib; + info->getattr.out.size = name->st.st_size; + info->getattr.out.write_time = nt_time_to_unix(name->dos.write_time); + return NT_STATUS_OK; + + case RAW_FILEINFO_GETATTRE: + case RAW_FILEINFO_STANDARD: + info->standard.out.create_time = nt_time_to_unix(name->dos.create_time); + info->standard.out.access_time = nt_time_to_unix(name->dos.access_time); + info->standard.out.write_time = nt_time_to_unix(name->dos.write_time); + info->standard.out.size = name->st.st_size; + info->standard.out.alloc_size = name->dos.alloc_size; + info->standard.out.attrib = name->dos.attrib; + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_SIZE: + info->ea_size.out.create_time = nt_time_to_unix(name->dos.create_time); + info->ea_size.out.access_time = nt_time_to_unix(name->dos.access_time); + info->ea_size.out.write_time = nt_time_to_unix(name->dos.write_time); + info->ea_size.out.size = name->st.st_size; + info->ea_size.out.alloc_size = name->dos.alloc_size; + info->ea_size.out.attrib = name->dos.attrib; + info->ea_size.out.ea_size = name->dos.ea_size; + return NT_STATUS_OK; + + case RAW_FILEINFO_ALL_EAS: + info->all_eas.out.num_eas = 0; + info->all_eas.out.eas = NULL; + return NT_STATUS_OK; + + case RAW_FILEINFO_IS_NAME_VALID: + return NT_STATUS_OK; + + case RAW_FILEINFO_BASIC_INFO: + case RAW_FILEINFO_BASIC_INFORMATION: + info->basic_info.out.create_time = name->dos.create_time; + info->basic_info.out.access_time = name->dos.access_time; + info->basic_info.out.write_time = name->dos.write_time; + info->basic_info.out.change_time = name->dos.change_time; + info->basic_info.out.attrib = name->dos.attrib; + return NT_STATUS_OK; + + case RAW_FILEINFO_STANDARD_INFO: + case RAW_FILEINFO_STANDARD_INFORMATION: + info->standard_info.out.alloc_size = name->dos.alloc_size; + info->standard_info.out.size = name->st.st_size; + info->standard_info.out.nlink = name->st.st_nlink; + info->standard_info.out.delete_pending = 0; + info->standard_info.out.directory = + (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; + return NT_STATUS_OK; + + case RAW_FILEINFO_EA_INFO: + case RAW_FILEINFO_EA_INFORMATION: + info->ea_info.out.ea_size = name->dos.ea_size; + return NT_STATUS_OK; + + case RAW_FILEINFO_NAME_INFO: + case RAW_FILEINFO_NAME_INFORMATION: + info->name_info.out.fname.s = name->original_name; + return NT_STATUS_OK; + + case RAW_FILEINFO_ALL_INFO: + case RAW_FILEINFO_ALL_INFORMATION: + info->all_info.out.create_time = name->dos.create_time; + info->all_info.out.access_time = name->dos.access_time; + info->all_info.out.write_time = name->dos.write_time; + info->all_info.out.change_time = name->dos.change_time; + info->all_info.out.attrib = name->dos.attrib; + info->all_info.out.alloc_size = name->dos.alloc_size; + info->all_info.out.size = name->st.st_size; + info->all_info.out.nlink = name->st.st_nlink; + info->all_info.out.delete_pending = 0; + info->all_info.out.directory = + (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; + info->all_info.out.ea_size = name->dos.ea_size; + info->all_info.out.fname.s = name->original_name; + return NT_STATUS_OK; + + case RAW_FILEINFO_ALT_NAME_INFO: + case RAW_FILEINFO_ALT_NAME_INFORMATION: + info->name_info.out.fname.s = pvfs_short_name(pvfs, name, name); + return NT_STATUS_OK; + + case RAW_FILEINFO_STREAM_INFO: + case RAW_FILEINFO_STREAM_INFORMATION: + info->stream_info.out.num_streams = 1; + info->stream_info.out.streams = talloc_array_p(mem_ctx, + struct stream_struct, 1); + if (!info->stream_info.out.streams) { + return NT_STATUS_NO_MEMORY; + } + info->stream_info.out.streams[0].size = name->st.st_size; + info->stream_info.out.streams[0].alloc_size = name->dos.alloc_size; + info->stream_info.out.streams[0].stream_name.s = + talloc_strdup(info->stream_info.out.streams, "::$DATA"); + return NT_STATUS_OK; + + case RAW_FILEINFO_COMPRESSION_INFO: + case RAW_FILEINFO_COMPRESSION_INFORMATION: + info->compression_info.out.compressed_size = name->st.st_size; + info->compression_info.out.format = 0; + info->compression_info.out.unit_shift = 0; + info->compression_info.out.chunk_shift = 0; + info->compression_info.out.cluster_shift = 0; + return NT_STATUS_OK; + + case RAW_FILEINFO_INTERNAL_INFORMATION: + info->internal_information.out.file_id = name->dos.file_id; + return NT_STATUS_OK; + + case RAW_FILEINFO_ACCESS_INFORMATION: + info->access_information.out.access_flags = 0; + return NT_STATUS_OK; + + case RAW_FILEINFO_POSITION_INFORMATION: + info->position_information.out.position = 0; + return NT_STATUS_OK; + + case RAW_FILEINFO_MODE_INFORMATION: + info->mode_information.out.mode = 0; /* what is this? */ + return NT_STATUS_OK; + + case RAW_FILEINFO_ALIGNMENT_INFORMATION: + info->alignment_information.out.alignment_requirement = 0; + return NT_STATUS_OK; + + case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: + info->network_open_information.out.create_time = name->dos.create_time; + info->network_open_information.out.access_time = name->dos.access_time; + info->network_open_information.out.write_time = name->dos.write_time; + info->network_open_information.out.change_time = name->dos.change_time; + info->network_open_information.out.alloc_size = name->dos.alloc_size; + info->network_open_information.out.size = name->st.st_size; + info->network_open_information.out.attrib = name->dos.attrib; + return NT_STATUS_OK; + + case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: + info->attribute_tag_information.out.attrib = name->dos.attrib; + info->attribute_tag_information.out.reparse_tag = 0; + return NT_STATUS_OK; } - info->generic.out.streams[0].size = name->st.st_size; - info->generic.out.streams[0].alloc_size = name->st.st_size; - info->generic.out.streams[0].stream_name.s = talloc_strdup(mem_ctx, "::$DATA"); - return NT_STATUS_OK; + return NT_STATUS_INVALID_LEVEL; } /* @@ -85,12 +188,9 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; NTSTATUS status; - if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qpathinfo(req, info, ntvfs); - } - /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -99,7 +199,9 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - return pvfs_map_fileinfo(pvfs, req, name, info); + status = pvfs_map_fileinfo(pvfs, req, name, info); + + return status; } /* @@ -112,10 +214,6 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct pvfs_file *f; NTSTATUS status; - if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qfileinfo(req, info, ntvfs); - } - f = pvfs_find_fd(pvfs, req, info->generic.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; @@ -129,7 +227,36 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, status = pvfs_map_fileinfo(pvfs, req, f->name, info); - info->generic.out.position = f->position; + /* a qfileinfo can fill in a bit more info than a qpathinfo - + now modify the levels that need to be fixed up */ + switch (info->generic.level) { + case RAW_FILEINFO_STANDARD_INFO: + case RAW_FILEINFO_STANDARD_INFORMATION: + if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + info->standard_info.out.delete_pending = 1; + info->standard_info.out.nlink--; + } + break; + + case RAW_FILEINFO_ALL_INFO: + case RAW_FILEINFO_ALL_INFORMATION: + if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + info->all_info.out.delete_pending = 1; + info->all_info.out.nlink--; + } + break; + + case RAW_FILEINFO_POSITION_INFORMATION: + info->position_information.out.position = f->position; + break; + + case RAW_FILEINFO_ACCESS_INFORMATION: + info->access_information.out.access_flags = f->access_mask; + break; + + default: + break; + } return status; } -- cgit From c1c696460b74fa3dd381f3903ec0281f6f1865a9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 01:29:31 +0000 Subject: r3174: added pvfs_is_open() to allow us to check for open files on unlink. We now pass BASE-UNLINK. (This used to be commit f23a2f8538bda8f6790e86c93ee22436388b2975) --- source4/ntvfs/common/opendb.c | 20 ++++++++++++++++++++ source4/ntvfs/posix/pvfs_open.c | 17 +++++++++++++++++ source4/ntvfs/posix/pvfs_unlink.c | 4 ++++ 3 files changed, 41 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 3def23f190..5c962fbad0 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -335,3 +335,23 @@ NTSTATUS odb_set_create_options(struct odb_lock *lck, return status; } + + +/* + determine if a file is open +*/ +BOOL odb_is_open(struct odb_context *odb, DATA_BLOB *key) +{ + TDB_DATA dbuf; + TDB_DATA kbuf; + + kbuf.dptr = key->data; + kbuf.dsize = key->length; + + dbuf = tdb_fetch(odb->w->tdb, kbuf); + if (dbuf.dptr == NULL) { + return False; + } + free(dbuf.dptr); + return True; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index e587ebbf95..7f06626706 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -703,3 +703,20 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, return status; } + + +/* + determine if a file is open - used to prevent some operations on open files +*/ +BOOL pvfs_is_open(struct pvfs_state *pvfs, struct pvfs_filename *name) +{ + NTSTATUS status; + DATA_BLOB key; + + status = pvfs_locking_key(name, name, &key); + if (!NT_STATUS_IS_OK(status)) { + return False; + } + + return odb_is_open(pvfs->odb_context, &key); +} diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 0f4ff8b148..d5e25b5622 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -80,6 +80,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + if (pvfs_is_open(pvfs, name)) { + return NT_STATUS_SHARING_VIOLATION; + } + dir = talloc_p(req, struct pvfs_dir); if (dir == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From 2a5eb0ceba2fd225c8854891899461a61673db41 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 01:55:38 +0000 Subject: r3177: check for open files on rename (This used to be commit c334182095c53b09fcb65a40053b518acb6ec38b) --- source4/ntvfs/posix/pvfs_rename.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 80b6a510b0..89d6a0da14 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -48,6 +48,11 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return status; } + if (pvfs_is_open(pvfs, name1) || + pvfs_is_open(pvfs, name2)) { + return NT_STATUS_SHARING_VIOLATION; + } + if (name1->has_wildcard || name2->has_wildcard) { DEBUG(3,("Rejecting wildcard rename '%s' -> '%s'\n", ren->rename.in.pattern1, ren->rename.in.pattern2)); -- cgit From e90ab07050f2fe8dd1c4399e5deff7eddf66e6d0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 01:56:01 +0000 Subject: r3178: honor the write_time on pvfs_close() (This used to be commit 4e28c45bafa453eaa94716a5b77d830b81efe6cf) --- source4/ntvfs/posix/pvfs_open.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 7f06626706..ac2742d357 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -605,6 +605,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; NTSTATUS status; + struct utimbuf unix_times; if (io->generic.level != RAW_CLOSE_CLOSE) { return ntvfs_map_close(req, io, ntvfs); @@ -615,6 +616,10 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } + unix_times.actime = 0; + unix_times.modtime = io->close.in.write_time; + utime(f->name->full_name, &unix_times); + if (f->fd != -1 && close(f->fd) == -1) { status = pvfs_map_errno(pvfs, errno); -- cgit From 8af9b5e42e7e1a356e6401079ed5d035f9cc8636 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 01:56:29 +0000 Subject: r3179: - fixed error return on utime failure - formatting fix (This used to be commit 8ca4d7c51e5c76aa28f600d49437a45a8a0d31a9) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_unlink.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 42ee8a971c..6a9e2003f4 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -64,7 +64,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* Set the date on this file */ if (utime(f->name->full_name, &unix_times) == -1) { - return NT_STATUS_ACCESS_DENIED; + return pvfs_map_errno(pvfs, errno); } break; diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index d5e25b5622..5733722ad5 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -100,7 +100,8 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } for (i=0;icount;i++) { - status = pvfs_unlink_one(pvfs, req, dir->unix_path, dir->names[i], unl->in.attrib); + status = pvfs_unlink_one(pvfs, req, dir->unix_path, + dir->names[i], unl->in.attrib); if (NT_STATUS_IS_OK(status)) { total_deleted++; } -- cgit From 3cf018b517de0afa006ac14d5185e3c95d8a923b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 02:36:12 +0000 Subject: r3180: - basic support for SEC_RIGHT_MAXIMUM_ALLOWED in pvfs - RAW-CONTEXT test now passes (This used to be commit 0dae9fef09ec8bce19c39a0caf36e0882e507bc4) --- source4/ntvfs/posix/pvfs_open.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index ac2742d357..badd18d370 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -283,6 +283,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_CANNOT_DELETE; } + if (access_mask & SEC_RIGHT_MAXIMUM_ALLOWED) { + access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + } + flags = O_RDWR; f = talloc_p(req, struct pvfs_file); @@ -355,7 +359,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->lock_count = 0; f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; - f->access_mask = io->generic.in.access_mask; + f->access_mask = access_mask; f->seek_offset = 0; f->position = 0; @@ -429,6 +433,14 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, share_access = io->generic.in.share_access; access_mask = io->generic.in.access_mask; + if (access_mask & SEC_RIGHT_MAXIMUM_ALLOWED) { + if (name->dos.attrib & FILE_ATTRIBUTE_READONLY) { + access_mask = GENERIC_RIGHTS_FILE_READ; + } else { + access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + } + } + /* certain create options are not allowed */ if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && !(access_mask & STD_RIGHT_DELETE_ACCESS)) { @@ -551,7 +563,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->lock_count = 0; f->create_options = io->generic.in.create_options; f->share_access = io->generic.in.share_access; - f->access_mask = io->generic.in.access_mask; + f->access_mask = access_mask; f->seek_offset = 0; f->position = 0; -- cgit From f7c6a9438dba17032aea102d18b44c6d96ae470b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 25 Oct 2004 04:16:57 +0000 Subject: r3185: Machines can login with krb5, so we need to allow them to map to a unix account. Andrew Bartlett (This used to be commit fbe932ddd4282c3d8af8a28fdd0cee83d0c8f4f3) --- source4/ntvfs/unixuid/vfs_unixuid.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index d0060bf11d..440ebd21c8 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -57,8 +57,8 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, /* make sure its a user, not a group */ atype = samdb_result_uint(res[0], "sAMAccountType", 0); - if (atype && atype != ATYPE_NORMAL_ACCOUNT) { - DEBUG(0,("sid_to_unixuid: sid %s is not ATYPE_NORMAL_ACCOUNT\n", sidstr)); + if (!atype || (!(atype & ATYPE_ACCOUNT))) { + DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; } -- cgit From 5c95896499dd6f72c8fc9be84b0da880571731da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 04:24:58 +0000 Subject: r3189: improved the share_conflict() logic (both in terms of readability and correctness). pvfs now passes the BASE-RENAME test. (This used to be commit 4cf3f65a5c19fdad62a0bdef225b2d9002cf8c8b) --- source4/ntvfs/common/opendb.c | 74 ++++++++++++++++++++++++++------------- source4/ntvfs/posix/pvfs_open.c | 15 +++++--- source4/ntvfs/posix/pvfs_rename.c | 11 ++++-- source4/ntvfs/posix/pvfs_unlink.c | 9 ++--- 4 files changed, 74 insertions(+), 35 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 5c962fbad0..a3924daf8e 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -145,41 +145,38 @@ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, return lck; } - /* determine if two odb_entry structures conflict */ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) { - uint32_t m1, m2; - - m1 = e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA); - m2 = e2->share_access & - (NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ); +#define CHECK_MASK(am, sa, right, share) if (((am) & (right)) && !((sa) & (share))) return True - if ((m1 & m2) != m1) { - return True; + /* if either open involves no read.write or delete access then + it can't conflict */ + if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA | STD_RIGHT_DELETE_ACCESS))) { + return False; + } + if (!(e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA | STD_RIGHT_DELETE_ACCESS))) { + return False; } - m1 = e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA); - m2 = e1->share_access & - (NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ); + /* check the basic share access */ + CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE); + CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE); - if ((m1 & m2) != m1) { - return True; - } + CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_READ_DATA, NTCREATEX_SHARE_ACCESS_READ); + CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_READ_DATA, NTCREATEX_SHARE_ACCESS_READ); + CHECK_MASK(e1->access_mask, e2->share_access, STD_RIGHT_DELETE_ACCESS, NTCREATEX_SHARE_ACCESS_DELETE); + CHECK_MASK(e2->access_mask, e1->share_access, STD_RIGHT_DELETE_ACCESS, NTCREATEX_SHARE_ACCESS_DELETE); + + /* if a delete is pending then a second open is not allowed */ if ((e1->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) || (e2->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return True; } - if ((e1->access_mask & STD_RIGHT_DELETE_ACCESS) && - !(e2->share_access & NTCREATEX_SHARE_ACCESS_DELETE)) { - return True; - } - - return False; } @@ -338,20 +335,49 @@ NTSTATUS odb_set_create_options(struct odb_lock *lck, /* - determine if a file is open + determine if a file can be opened with the given share_access, + create_options and access_mask */ -BOOL odb_is_open(struct odb_context *odb, DATA_BLOB *key) +NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key, + uint32_t share_access, uint32_t create_options, + uint32_t access_mask) { TDB_DATA dbuf; TDB_DATA kbuf; + struct odb_entry *elist; + int i, count; + struct odb_entry e; kbuf.dptr = key->data; kbuf.dsize = key->length; dbuf = tdb_fetch(odb->w->tdb, kbuf); if (dbuf.dptr == NULL) { - return False; + return NT_STATUS_OK; } + + elist = (struct odb_entry *)dbuf.dptr; + count = dbuf.dsize / sizeof(struct odb_entry); + + if (count == 0) { + free(dbuf.dptr); + return NT_STATUS_OK; + } + + e.server = odb->server; + e.tid = odb->tid; + e.fnum = -1; + e.share_access = share_access; + e.create_options = create_options; + e.access_mask = access_mask; + + for (i=0;iodb_context, &key); + status = odb_can_open(pvfs->odb_context, &key, + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE, + 0, STD_RIGHT_DELETE_ACCESS); + + return status; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 89d6a0da14..6116f6c7bf 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -48,9 +48,14 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return status; } - if (pvfs_is_open(pvfs, name1) || - pvfs_is_open(pvfs, name2)) { - return NT_STATUS_SHARING_VIOLATION; + status = pvfs_can_delete(pvfs, name1); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_can_delete(pvfs, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; } if (name1->has_wildcard || name2->has_wildcard) { diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 5733722ad5..10a27a5de7 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -47,6 +47,11 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + status = pvfs_can_delete(pvfs, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* finally try the actual unlink */ if (unlink(name->full_name) == -1) { status = pvfs_map_errno(pvfs, errno); @@ -80,10 +85,6 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (pvfs_is_open(pvfs, name)) { - return NT_STATUS_SHARING_VIOLATION; - } - dir = talloc_p(req, struct pvfs_dir); if (dir == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From 3918ae351db67dd77a393b48e59a487e29febbd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 05:27:15 +0000 Subject: r3192: make sure we don't call pvfs_can_delete() until after we have confirmed that name->exists it true (This used to be commit d368d2f4fe23bdc13f6b9bbdc044dd158ab61169) --- source4/ntvfs/posix/pvfs_rename.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 6116f6c7bf..ad69f092ad 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -48,16 +48,6 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_can_delete(pvfs, name1); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = pvfs_can_delete(pvfs, name2); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if (name1->has_wildcard || name2->has_wildcard) { DEBUG(3,("Rejecting wildcard rename '%s' -> '%s'\n", ren->rename.in.pattern1, ren->rename.in.pattern2)); @@ -72,6 +62,11 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } + status = pvfs_can_delete(pvfs, name1); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (rename(name1->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } -- cgit From 1be85de5884d107f89eaf4221f225c9ec468365e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 05:27:49 +0000 Subject: r3193: improved the initial permissions choice for file create, based upon dos attribute (This used to be commit f6fb1e3493a2a0734747f769cd1013215d967cde) --- source4/ntvfs/posix/pvfs_fileinfo.c | 86 +++++++++++++++---------------------- source4/ntvfs/posix/pvfs_open.c | 36 ++++++++++++---- 2 files changed, 61 insertions(+), 61 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 77eb10422d..4fa2c1601b 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -35,58 +35,6 @@ #define UNIX_TYPE_UNKNOWN 0xFFFFFFFF -/* - Return the major devicenumber for UNIX extensions. -*/ -static uint32_t unix_dev_major(dev_t dev) -{ -#if defined(HAVE_DEVICE_MAJOR_FN) - return (uint32)major(dev); -#else - return (uint32)(dev >> 8); -#endif -} - -/* - Return the minor devicenumber for UNIX extensions. -*/ -static uint32_t unix_dev_minor(dev_t dev) -{ -#if defined(HAVE_DEVICE_MINOR_FN) - return (uint32)minor(dev); -#else - return (uint32)(dev & 0xff); -#endif -} - -/* - Return the filetype for UNIX extensions -*/ -static uint32_t unix_filetype(mode_t mode) -{ - if (S_ISREG(mode)) return UNIX_TYPE_FILE; - if (S_ISDIR(mode)) return UNIX_TYPE_DIR; -#ifdef S_ISLNK - if (S_ISLNK(mode)) return UNIX_TYPE_SYMLINK; -#endif -#ifdef S_ISCHR - if (S_ISCHR(mode)) return UNIX_TYPE_CHARDEV; -#endif -#ifdef S_ISBLK - if (S_ISBLK(mode)) return UNIX_TYPE_BLKDEV; -#endif -#ifdef S_ISFIFO - if (S_ISFIFO(mode)) return UNIX_TYPE_FIFO; -#endif -#ifdef S_ISSOCK - if (S_ISSOCK(mode)) return UNIX_TYPE_SOCKET; -#endif - - DEBUG(0,("unix_filetype: unknown filetype %u", (unsigned)mode)); - return UNIX_TYPE_UNKNOWN; -} - - /**************************************************************************** Change a unix mode to a dos mode. ****************************************************************************/ @@ -153,3 +101,37 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) return NT_STATUS_OK; } + + +/* + return a set of unix file permissions for a new file or directory +*/ +mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32 attrib) +{ + mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; + + if (attrib & FILE_ATTRIBUTE_DIRECTORY) { + mode |= S_IXUSR | S_IXGRP | S_IXOTH; + } + + if (!(attrib & FILE_ATTRIBUTE_READONLY)) { + mode |= S_IWUSR; + } + + if ((attrib & FILE_ATTRIBUTE_ARCHIVE) && + (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) { + mode |= S_IXUSR; + } + + if ((attrib & FILE_ATTRIBUTE_SYSTEM) && + (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) { + mode |= S_IXGRP; + } + + if ((attrib & FILE_ATTRIBUTE_HIDDEN) && + (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) { + mode |= S_IXOTH; + } + + return mode; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index b66b3725db..4844521c45 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -150,7 +150,9 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, talloc_set_destructor(f, pvfs_dir_fd_destructor); if (!name->exists) { - if (mkdir(name->full_name, 0755) == -1) { + uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY; + mode_t mode = pvfs_fileperms(pvfs, attrib); + if (mkdir(name->full_name, mode) == -1) { return pvfs_map_errno(pvfs,errno); } status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, @@ -287,7 +289,17 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; } - flags = O_RDWR; + switch (access_mask & (SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA)) { + case SA_RIGHT_FILE_READ_DATA: + flags = O_RDONLY; + break; + case SA_RIGHT_FILE_WRITE_DATA: + flags = O_WRONLY; + break; + case SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_READ_DATA: + flags = O_RDWR; + break; + } f = talloc_p(req, struct pvfs_file); if (f == NULL) { @@ -299,11 +311,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } - if (io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) { - mode = 0444; - } else { - mode = 0644; - } + mode = pvfs_fileperms(pvfs, io->ntcreatex.in.file_attr); /* create the file */ fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode); @@ -434,7 +442,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, access_mask = io->generic.in.access_mask; if (access_mask & SEC_RIGHT_MAXIMUM_ALLOWED) { - if (name->dos.attrib & FILE_ATTRIBUTE_READONLY) { + if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_READONLY)) { access_mask = GENERIC_RIGHTS_FILE_READ; } else { access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; @@ -488,7 +496,17 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - flags |= O_RDWR; + switch (access_mask & (SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA)) { + case SA_RIGHT_FILE_READ_DATA: + flags |= O_RDONLY; + break; + case SA_RIGHT_FILE_WRITE_DATA: + flags |= O_WRONLY; + break; + case SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_READ_DATA: + flags |= O_RDWR; + break; + } /* handle creating a new file separately */ if (!name->exists) { -- cgit From a555d2eadc0894d53140f0917faf7fc0c76beb7b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 05:28:18 +0000 Subject: r3194: fixed an uninitialised variable (This used to be commit 8123cfc59edb7b455c7f6511480f0faeb4c9aba8) --- source4/ntvfs/posix/pvfs_fsinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index a9153b4c19..e1cb2f710d 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -61,6 +61,7 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.out.quota_flags = 0; fs->generic.out.volume_name = talloc_strdup(req, pvfs->share_name); fs->generic.out.fs_type = req->tcon->fs_type; + ZERO_STRUCT(fs->generic.out.guid); return NT_STATUS_OK; } -- cgit From 53e22ff5096fda6ebdf6a86ff5fae87ccb133d5e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 05:44:00 +0000 Subject: r3195: fill in more of the fsinfo fields, and avoid calling the potentially expensive sys_fsusage() call unless we really need to (This used to be commit 57eb14773b1811fbab2c37d1ff815c1ab07b3685) --- source4/ntvfs/posix/pvfs_fsinfo.c | 127 ++++++++++++++++++++++++++++++-------- 1 file changed, 102 insertions(+), 25 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index e1cb2f710d..6ddef98ea0 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -31,37 +31,114 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_fsinfo *fs) { struct pvfs_state *pvfs = ntvfs->private_data; + uint64_t blocks_free, blocks_total; + uint_t bpunit; struct stat st; + const uint16_t block_size = 512; - if (fs->generic.level != RAW_QFS_GENERIC) { - return ntvfs_map_fsinfo(req, fs, ntvfs); + /* only some levels need the expensive sys_fsusage() call */ + switch (fs->generic.level) { + case RAW_QFS_DSKATTR: + case RAW_QFS_ALLOCATION: + case RAW_QFS_SIZE_INFO: + case RAW_QFS_SIZE_INFORMATION: + case RAW_QFS_FULL_SIZE_INFORMATION: + if (sys_fsusage(pvfs->base_directory, &blocks_free, &blocks_total) == -1) { + return pvfs_map_errno(pvfs, errno); + } + default: + break; } - if (sys_fsusage(pvfs->base_directory, - &fs->generic.out.blocks_free, - &fs->generic.out.blocks_total) == -1) { - return pvfs_map_errno(pvfs, errno); + if (stat(pvfs->base_directory, &st) != 0) { + return NT_STATUS_DISK_CORRUPT_ERROR; } - fs->generic.out.block_size = 512; + /* now fill in the out fields */ + switch (fs->generic.level) { + case RAW_QFS_GENERIC: + return NT_STATUS_INVALID_LEVEL; - if (stat(pvfs->base_directory, &st) != 0) { - return NT_STATUS_DISK_CORRUPT_ERROR; + case RAW_QFS_DSKATTR: + /* we need to scale the sizes to fit */ + for (bpunit=64; bpunit<0x10000; bpunit *= 2) { + if (blocks_total * (double)block_size < bpunit * 512 * 65535.0) { + break; + } + } + fs->dskattr.out.blocks_per_unit = bpunit; + fs->dskattr.out.block_size = block_size; + fs->dskattr.out.units_total = (blocks_total * (double)block_size) / (bpunit * 512); + fs->dskattr.out.units_free = (blocks_free * (double)block_size) / (bpunit * 512); + + /* we must return a maximum of 2G to old DOS systems, or they get very confused */ + if (bpunit > 64 && req->smb_conn->negotiate.protocol <= PROTOCOL_LANMAN2) { + fs->dskattr.out.blocks_per_unit = 64; + fs->dskattr.out.units_total = 0xFFFF; + fs->dskattr.out.units_free = 0xFFFF; + } + return NT_STATUS_OK; + + case RAW_QFS_ALLOCATION: + fs->allocation.out.fs_id = st.st_dev; + fs->allocation.out.total_alloc_units = blocks_total; + fs->allocation.out.avail_alloc_units = blocks_free; + fs->allocation.out.sectors_per_unit = 1; + fs->allocation.out.bytes_per_sector = block_size; + return NT_STATUS_OK; + + case RAW_QFS_VOLUME: + fs->volume.out.serial_number = st.st_ino; + fs->volume.out.volume_name.s = pvfs->share_name; + return NT_STATUS_OK; + + case RAW_QFS_VOLUME_INFO: + case RAW_QFS_VOLUME_INFORMATION: + unix_to_nt_time(&fs->volume_info.out.create_time, st.st_ctime); + fs->volume_info.out.serial_number = st.st_ino; + fs->volume_info.out.volume_name.s = pvfs->share_name; + return NT_STATUS_OK; + + case RAW_QFS_SIZE_INFO: + case RAW_QFS_SIZE_INFORMATION: + fs->size_info.out.total_alloc_units = blocks_total; + fs->size_info.out.avail_alloc_units = blocks_free; + fs->size_info.out.sectors_per_unit = 1; + fs->size_info.out.bytes_per_sector = block_size; + return NT_STATUS_OK; + + case RAW_QFS_DEVICE_INFO: + case RAW_QFS_DEVICE_INFORMATION: + fs->device_info.out.device_type = 0; + fs->device_info.out.characteristics = 0; + return NT_STATUS_OK; + + case RAW_QFS_ATTRIBUTE_INFO: + case RAW_QFS_ATTRIBUTE_INFORMATION: + fs->attribute_info.out.fs_attr = 0; + fs->attribute_info.out.max_file_component_length = 255; + fs->attribute_info.out.fs_type.s = req->tcon->fs_type; + return NT_STATUS_OK; + + case RAW_QFS_QUOTA_INFORMATION: + ZERO_STRUCT(fs->quota_information.out.unknown); + fs->quota_information.out.quota_soft = 0; + fs->quota_information.out.quota_hard = 0; + fs->quota_information.out.quota_flags = 0; + return NT_STATUS_OK; + + case RAW_QFS_FULL_SIZE_INFORMATION: + fs->full_size_information.out.total_alloc_units = blocks_total; + fs->full_size_information.out.call_avail_alloc_units = blocks_free; + fs->full_size_information.out.actual_avail_alloc_units = blocks_free; + fs->full_size_information.out.sectors_per_unit = 1; + fs->full_size_information.out.bytes_per_sector = block_size; + return NT_STATUS_OK; + + case RAW_QFS_OBJECTID_INFORMATION: + ZERO_STRUCT(fs->objectid_information.out); + return NT_STATUS_OK; } - - fs->generic.out.fs_id = st.st_ino; - unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); - fs->generic.out.serial_number = st.st_ino; - fs->generic.out.fs_attr = 0; - fs->generic.out.max_file_component_length = 255; - fs->generic.out.device_type = 0; - fs->generic.out.device_characteristics = 0; - fs->generic.out.quota_soft = 0; - fs->generic.out.quota_hard = 0; - fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req, pvfs->share_name); - fs->generic.out.fs_type = req->tcon->fs_type; - ZERO_STRUCT(fs->generic.out.guid); - - return NT_STATUS_OK; + + return NT_STATUS_INVALID_LEVEL; } -- cgit From 7780bec7b4169cb2a78ceda16e6dc9e00dcb0b0f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 06:23:28 +0000 Subject: r3198: check for too many .. components in filenames pvfs now passes RAW-MKDIR (This used to be commit 41adb385f123b8d4cd3fe2eb03d891b6bdcf2361) --- source4/ntvfs/posix/pvfs_resolve.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 5b86cd3a73..5d98274511 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -180,8 +180,9 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, uint_t flags, struct pvfs_filename *name) { - char *ret, *p; + char *ret, *p, *p_start; size_t len; + int num_components=0; name->original_name = talloc_strdup(name, cifs_name); name->stream_name = NULL; @@ -217,6 +218,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, /* now do an in-place conversion of '\' to '/', checking for legal characters */ + p_start = p; while (*p) { size_t c_size; codepoint_t c = next_codepoint(p, &c_size); @@ -228,6 +230,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, return NT_STATUS_ILLEGAL_CHARACTER; } *p = '/'; + num_components++; break; case ':': if (!(flags & PVFS_RESOLVE_STREAMS)) { @@ -252,6 +255,18 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, case '/': case '|': return NT_STATUS_ILLEGAL_CHARACTER; + case '.': + if (p[1] != '.' || + (p[2] != '\\' && p[2] != 0) || + (p != p_start && p[-1] != '/')) { + break; + } + /* its definately a .. component */ + num_components--; + if (num_components <= 0) { + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; + } + break; } p += c_size; -- cgit From 7fa912e708331e729d5e4ffad28646d294d4745a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 07:03:15 +0000 Subject: r3200: - improved the accuracy of openx emulation. We now nearly pass the openx portion of RAW-OPEN - fixed directory size reporting to make it consistent. we now pass the ntcreatex portion of RAW-OPEN (This used to be commit 6282e5811b8d4f1c17152d86875ac60d1323779d) --- source4/ntvfs/ntvfs_generic.c | 56 ++++++++++++++++++++++++++++++------- source4/ntvfs/posix/pvfs_fileinfo.c | 11 ++++---- source4/ntvfs/posix/pvfs_open.c | 7 ++--- 3 files changed, 53 insertions(+), 21 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index ceb7900935..452273cbdb 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -90,14 +90,20 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { case OPENX_MODE_ACCESS_READ: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io->openx.out.access = OPENX_MODE_ACCESS_READ; break; case OPENX_MODE_ACCESS_WRITE: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_WRITE; break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: + case OPENX_MODE_ACCESS_EXEC: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_RDWR; break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; } switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { @@ -129,12 +135,11 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, case OPENX_MODE_DENY_FCB: io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; } switch (io->openx.in.open_func) { - case (OPENX_OPEN_FUNC_FAIL): - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; case (OPENX_OPEN_FUNC_OPEN): io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; break; @@ -150,8 +155,17 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; break; + default: + /* this one is very strange */ + if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == + OPENX_MODE_ACCESS_EXEC) { + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + } + return NT_STATUS_INVALID_LOCK_SEQUENCE; } - io2->generic.in.alloc_size = io->openx.in.size; + + io2->generic.in.alloc_size = 0; io2->generic.in.file_attr = io->openx.in.file_attrs; io2->generic.in.fname = io->openx.in.fname; @@ -159,13 +173,35 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, if (!NT_STATUS_IS_OK(status)) { return status; } + + io->openx.out.fnum = io2->generic.out.fnum; + io->openx.out.attrib = io2->generic.out.attrib; + io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->openx.out.size = io2->generic.out.size; + io->openx.out.ftype = 0; + io->openx.out.devstate = 0; + io->openx.out.action = io2->generic.out.create_action; + io->openx.out.unique_fid = 0; + io->openx.out.access_mask = io2->generic.in.access_mask; + io->openx.out.unknown = 0; - ZERO_STRUCT(io->openx.out); - io->openx.out.fnum = io2->generic.out.fnum; - io->openx.out.attrib = io2->generic.out.attrib; - io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); - io->openx.out.size = io2->generic.out.size; - + /* we need to extend the file to the requested size if + it was newly created */ + if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED && + io->openx.in.size != 0) { + union smb_setfileinfo *sf; + sf = talloc_p(req, union smb_setfileinfo); + if (sf != NULL) { + sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; + sf->generic.file.fnum = io2->generic.out.fnum; + sf->end_of_file_info.in.size = io->openx.in.size; + status = ntvfs->ops->setfileinfo(ntvfs, req, sf); + if (NT_STATUS_IS_OK(status)) { + io->openx.out.size = io->openx.in.size; + } + } + } + return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 4fa2c1601b..2e2acb2c82 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -57,12 +57,6 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) if (S_ISDIR(st->st_mode)) result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY); -#if defined (HAVE_STAT_ST_BLOCKS) && defined (HAVE_STAT_ST_BLKSIZE) - if (st->st_size > st->st_blocks * (off_t)st->st_blksize) { - result |= FILE_ATTRIBUTE_SPARSE; - } -#endif - if (!(result & (FILE_ATTRIBUTE_READONLY| FILE_ATTRIBUTE_ARCHIVE| @@ -82,6 +76,11 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) */ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) { + /* make directories appear as size 0 */ + if (S_ISDIR(name->st.st_mode)) { + name->st.st_size = 0; + } + /* for now just use the simple samba mapping */ unix_to_nt_time(&name->dos.create_time, name->st.st_ctime); unix_to_nt_time(&name->dos.access_time, name->st.st_atime); diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 4844521c45..5e162ad147 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -180,8 +180,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, io->generic.out.write_time = name->dos.write_time; io->generic.out.change_time = name->dos.change_time; io->generic.out.attrib = name->dos.attrib; - io->generic.out.alloc_size = 0; - io->generic.out.size = 0; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; io->generic.out.file_type = FILE_TYPE_DISK; io->generic.out.ipc_state = 0; io->generic.out.is_directory = 1; @@ -457,9 +457,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: - if (!name->exists) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } flags = O_TRUNC; break; -- cgit From ee0c87b4c98e2d3878aa7ab7f8919aa16c4aa063 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Oct 2004 07:58:47 +0000 Subject: r3207: - reformat error msgs in BASE-DIR* tests - added support for mandatory attributes in old style directory search - we now pass BASE-DIR1 and BASE-DIR2 (This used to be commit efaa0eaec49e952aa515c3448246d9048a484c26) --- source4/ntvfs/posix/pvfs_search.c | 6 ++++-- source4/ntvfs/posix/pvfs_unlink.c | 2 +- source4/ntvfs/posix/pvfs_util.c | 6 +++++- source4/ntvfs/posix/vfs_posix.h | 1 + 4 files changed, 11 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 1464609e98..ff9ad20b43 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -54,7 +54,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return status; } - if (!pvfs_match_attrib(pvfs, name, search->search_attrib)) { + if (!pvfs_match_attrib(pvfs, name, search->search_attrib, search->must_attrib)) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -296,7 +296,8 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, search->handle = id; search->dir = dir; search->current_index = 0; - search->search_attrib = search_attrib; + search->search_attrib = search_attrib & 0xFF; + search->must_attrib = (search_attrib>>8) & 0xFF; talloc_set_destructor(search, pvfs_search_destructor); @@ -425,6 +426,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, search->dir = dir; search->current_index = 0; search->search_attrib = search_attrib; + search->must_attrib = 0; talloc_set_destructor(search, pvfs_search_destructor); diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 10a27a5de7..12ab583082 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -42,7 +42,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, } /* make sure its matches the given attributes */ - if (!pvfs_match_attrib(pvfs, name, attrib)) { + if (!pvfs_match_attrib(pvfs, name, attrib, 0)) { talloc_free(name); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 3c65453798..ae1dc6236d 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -49,11 +49,15 @@ NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno) this is used by calls like unlink and search which take an attribute and only include special files if they match the given attribute */ -BOOL pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, uint32_t attrib) +BOOL pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, + uint32_t attrib, uint32_t must_attrib) { if ((name->dos.attrib & ~attrib) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM)) { return False; } + if (must_attrib & ~name->dos.attrib) { + return False; + } return True; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index d4c0b19974..656ac85380 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -90,6 +90,7 @@ struct pvfs_search_state { uint16_t handle; uint_t current_index; uint16_t search_attrib; + uint16_t must_attrib; struct pvfs_dir *dir; }; -- cgit From d5fd12648e004b47bbe5ed2623838866fedcbeb0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 00:59:06 +0000 Subject: r3227: added a per-share option "case insensitive filesystem", that tells the backend that the underlying filesystem is case insensitive, so it can bypass the directory search if the name is not found. (This used to be commit d84ade90ce7e03ec749d6ae8dcdcb41de85d836e) --- source4/ntvfs/posix/pvfs_resolve.c | 18 ++++++++++++------ source4/ntvfs/posix/pvfs_shortname.c | 15 +++++++++++++-- source4/ntvfs/posix/vfs_posix.c | 1 + source4/ntvfs/posix/vfs_posix.h | 3 +-- 4 files changed, 27 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 5d98274511..271dbc2b9a 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -125,6 +125,18 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * } continue; } + + /* the filesystem might be case insensitive, in which + case a search is pointless unless the name is + mangled */ + if ((pvfs->flags & PVFS_FLAG_CI_FILESYSTEM) && + !pvfs_is_mangled_component(pvfs, components[i])) { + if (i < num_components-1) { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + partial_name = test_name; + continue; + } dir = opendir(partial_name); if (!dir) { @@ -319,12 +331,6 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return pvfs_fill_dos_info(pvfs, *name); } - /* the filesystem might be case insensitive, in which - case a search is pointless */ - if (pvfs->flags & PVFS_FLAG_CI_FILESYSTEM) { - return NT_STATUS_OK; - } - /* search for a matching filename */ status = pvfs_case_search(pvfs, *name); diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index c3c33fbc98..f80e532762 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -237,7 +237,7 @@ static BOOL is_mangled(struct pvfs_mangle_context *ctx, const char *name) } /* and the last part ... */ - return is_mangled_component(ctx, s,strlen(s)); + return is_mangled_component(ctx, s, strlen(s)); } @@ -301,7 +301,8 @@ static BOOL is_8_3(struct pvfs_mangle_context *ctx, /* the length are all OK. Now check to see if the characters themselves are OK */ for (i=0; name[i]; i++) { /* note that we may allow wildcard petterns! */ - if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && name[i] != '.') { + if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && + name[i] != '.') { return False; } } @@ -686,3 +687,13 @@ BOOL pvfs_is_reserved_name(struct pvfs_state *pvfs, const char *name) { return is_reserved_name(pvfs->mangle_ctx, name); } + + +/* + see if a component of a filename could be a mangled name from our + mangling code +*/ +BOOL pvfs_is_mangled_component(struct pvfs_state *pvfs, const char *name) +{ + return is_mangled_component(pvfs->mangle_ctx, name, strlen(name)); +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 64f0e09f59..cd41bf2329 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -41,6 +41,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_readonly(snum)) pvfs->flags |= PVFS_FLAG_READONLY; if (lp_strict_sync(snum)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; + if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 656ac85380..48a2ba9288 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -94,8 +94,7 @@ struct pvfs_search_state { struct pvfs_dir *dir; }; -/* open file state - this is a temporary implementation - to allow some tests to work */ +/* open file state */ struct pvfs_file { struct pvfs_file *next, *prev; int fd; -- cgit From 84bbf02e95639536c34140906aa4652ad61ea2c3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 05:36:14 +0000 Subject: r3239: reads of more than UINT16_MAX bytes should return 0 bytes (This used to be commit 16c7dd641707b6b8b3159290ca9fa08053a10692) --- source4/ntvfs/ipc/vfs_ipc.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index dcbfdb948f..f7eac65712 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -365,17 +365,23 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, } fnum = rd->readx.in.fnum; - data.length = rd->readx.in.maxcnt; - data.data = rd->readx.out.data; p = pipe_state_find(private, fnum); if (!p) { return NT_STATUS_INVALID_HANDLE; } - status = dcesrv_output_blob(p->dce_conn, &data); - if (NT_STATUS_IS_ERR(status)) { - return status; + data.length = rd->readx.in.maxcnt; + data.data = rd->readx.out.data; + if (data.length > UINT16_MAX) { + data.length = 0; + } + + if (data.length != 0) { + status = dcesrv_output_blob(p->dce_conn, &data); + if (NT_STATUS_IS_ERR(status)) { + return status; + } } rd->readx.out.remaining = 0; -- cgit From e9820e1b6e62240c5a18fa85e38a99685beed2df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 05:39:54 +0000 Subject: r3240: - update the rules for what error codes should be given on the different type of unlink an seach mismatches - wildcard directory listings that have attribute FILE_ATTRIBUTE_DIRECTORY and match "." or ".." should be failed. - don't set the write_time on SMBclose unless it is non-zero - added much better support for setfileinfo and setpathinfo in pvfs - better (and more efficient) handling of .. and . components in filenames (This used to be commit 9305b07af395a158cb9f0c1c9486f7122c79d357) --- source4/ntvfs/posix/pvfs_open.c | 8 +- source4/ntvfs/posix/pvfs_read.c | 9 +- source4/ntvfs/posix/pvfs_resolve.c | 116 ++++++++++++++++-- source4/ntvfs/posix/pvfs_search.c | 5 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 213 ++++++++++++++++++++++++++------- source4/ntvfs/posix/pvfs_unlink.c | 26 +++- source4/ntvfs/posix/pvfs_util.c | 16 +-- 7 files changed, 327 insertions(+), 66 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5e162ad147..ffd1520b07 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -643,9 +643,11 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - unix_times.actime = 0; - unix_times.modtime = io->close.in.write_time; - utime(f->name->full_name, &unix_times); + if (!null_time(io->close.in.write_time)) { + unix_times.actime = 0; + unix_times.modtime = io->close.in.write_time; + utime(f->name->full_name, &unix_times); + } if (f->fd != -1 && close(f->fd) == -1) { diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index eb821d1f31..ee750a138f 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -51,6 +51,12 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_VIOLATION; } + /* this matches w2k3 behaviour for attempted large reads */ + if (rd->readx.in.maxcnt > UINT16_MAX) { + ret = 0; + goto done_read; + } + status = pvfs_check_lock(pvfs, f, req->smbpid, rd->readx.in.offset, rd->readx.in.maxcnt, @@ -67,10 +73,11 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } +done_read: f->position = f->seek_offset = rd->readx.in.offset + ret; rd->readx.out.nread = ret; - rd->readx.out.remaining = 0; /* should fill this in? */ + rd->readx.out.remaining = 0xFFFF; rd->readx.out.compaction_mode = 0; return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 271dbc2b9a..a7a693b217 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -194,7 +194,6 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, { char *ret, *p, *p_start; size_t len; - int num_components=0; name->original_name = talloc_strdup(name, cifs_name); name->stream_name = NULL; @@ -242,7 +241,6 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, return NT_STATUS_ILLEGAL_CHARACTER; } *p = '/'; - num_components++; break; case ':': if (!(flags & PVFS_RESOLVE_STREAMS)) { @@ -268,14 +266,19 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, case '|': return NT_STATUS_ILLEGAL_CHARACTER; case '.': - if (p[1] != '.' || - (p[2] != '\\' && p[2] != 0) || - (p != p_start && p[-1] != '/')) { - break; + /* see if it is definately a .. or + . component. If it is then fail here, and + let the next layer up try again after + pvfs_reduce_name() if it wants to. This is + much more efficient on average than always + scanning for these separately */ + if (p[1] == '.' && + (p[2] == 0 || p[2] == '\\') && + (p == p_start || p[-1] == '/')) { + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; } - /* its definately a .. component */ - num_components--; - if (num_components <= 0) { + if ((p[1] == 0 || p[1] == '\\') && + (p == p_start || p[-1] == '/')) { return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; } break; @@ -290,6 +293,92 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, } +/* + reduce a name that contains .. components or repeated \ separators + return NULL if it can't be reduced +*/ +const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname) +{ + codepoint_t c; + size_t c_size, len; + int i, num_components; + char **components; + char *p, *s, *ret; + + s = talloc_strdup(mem_ctx, fname); + if (s == NULL) return NULL; + + for (num_components=1, p=s; *p; p += c_size) { + c = next_codepoint(p, &c_size); + if (c == '\\') num_components++; + } + if (num_components < 2) { + talloc_free(s); + return NULL; + } + + components = talloc_array_p(s, char *, num_components+1); + if (components == NULL) { + talloc_free(s); + return NULL; + } + + components[0] = s; + for (i=0, p=s; *p; p += c_size) { + c = next_codepoint(p, &c_size); + if (c == '\\') { + *p = 0; + components[++i] = p+1; + } + } + components[i+1] = NULL; + + /* remove any null components */ + for (i=0;components[i];i++) { + if (strcmp(components[i], "") == 0 || + strcmp(components[i], ".") == 0) { + memmove(&components[i], &components[i+1], + sizeof(char *)*(num_components-i)); + i--; + } + if (strcmp(components[i], "..") == 0) { + if (i < 1) return NULL; + memmove(&components[i-1], &components[i+1], + sizeof(char *)*(num_components-(i+1))); + i -= 2; + } + } + + if (components[0] == NULL) { + talloc_free(s); + return talloc_strdup(mem_ctx, "\\"); + } + + for (len=i=0;components[i];i++) { + len += strlen(components[i]) + 1; + } + + /* rebuild the name */ + ret = talloc(mem_ctx, len+1); + if (ret == NULL) { + talloc_free(s); + return NULL; + } + + for (len=0,i=0;components[i];i++) { + size_t len1 = strlen(components[i]); + ret[len] = '\\'; + memcpy(ret+len+1, components[i], len1); + len += len1 + 1; + } + ret[len] = 0; + + talloc_free(s); + + return ret; +} + + /* resolve a name from relative client format to a struct pvfs_filename the memory for the filename is made as a talloc child of 'name' @@ -316,6 +405,15 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* do the basic conversion to a unix formatted path, also checking for allowable characters */ status = pvfs_unix_path(pvfs, cifs_name, flags, *name); + + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) { + /* it might contain .. components which need to be reduced */ + cifs_name = pvfs_reduce_name(*name, cifs_name); + if (cifs_name) { + status = pvfs_unix_path(pvfs, cifs_name, flags, *name); + } + } + if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index ff9ad20b43..61e4651c5f 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -54,8 +54,9 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return status; } - if (!pvfs_match_attrib(pvfs, name, search->search_attrib, search->must_attrib)) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + status = pvfs_match_attrib(pvfs, name, search->search_attrib, search->must_attrib); + if (!NT_STATUS_IS_OK(status)) { + return status; } switch (level) { diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 6a9e2003f4..71a9ce1266 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -34,37 +34,64 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct utimbuf unix_times; struct pvfs_file *f; uint32_t create_options; + struct pvfs_filename newstats; + NTSTATUS status; f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } + /* update the file information */ + status = pvfs_resolve_name_fd(pvfs, f->fd, f->name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* we take a copy of the current file stats, then update + newstats in each of the elements below. At the end we + compare, and make any changes needed */ + newstats = *f->name; + switch (info->generic.level) { - case RAW_SFILEINFO_END_OF_FILE_INFO: - case RAW_SFILEINFO_END_OF_FILE_INFORMATION: - if (ftruncate(f->fd, - info->end_of_file_info.in.size) == -1) { - return pvfs_map_errno(pvfs, errno); + case RAW_SFILEINFO_SETATTR: + if (!null_time(info->setattr.in.write_time)) { + unix_to_nt_time(&newstats.dos.write_time, info->setattr.in.write_time); } - break; + if (info->setattr.in.attrib != FILE_ATTRIBUTE_NORMAL) { + newstats.dos.attrib = info->setattr.in.attrib; + } + break; case RAW_SFILEINFO_SETATTRE: - unix_times.actime = info->setattre.in.access_time; - unix_times.modtime = info->setattre.in.write_time; - - if (unix_times.actime == 0 && unix_times.modtime == 0) { - break; - } - - /* set modify time = to access time if modify time was 0 */ - if (unix_times.actime != 0 && unix_times.modtime == 0) { - unix_times.modtime = unix_times.actime; + case RAW_SFILEINFO_STANDARD: + if (!null_time(info->setattre.in.create_time)) { + unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time); + } + if (!null_time(info->setattre.in.access_time)) { + unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time); } + if (!null_time(info->setattre.in.write_time)) { + unix_to_nt_time(&newstats.dos.write_time, info->setattre.in.write_time); + } + break; - /* Set the date on this file */ - if (utime(f->name->full_name, &unix_times) == -1) { - return pvfs_map_errno(pvfs, errno); + case RAW_SFILEINFO_BASIC_INFO: + case RAW_SFILEINFO_BASIC_INFORMATION: + if (info->basic_info.in.create_time) { + newstats.dos.create_time = info->basic_info.in.create_time; + } + if (info->basic_info.in.access_time) { + newstats.dos.access_time = info->basic_info.in.access_time; + } + if (info->basic_info.in.write_time) { + newstats.dos.write_time = info->basic_info.in.write_time; + } + if (info->basic_info.in.change_time) { + newstats.dos.change_time = info->basic_info.in.change_time; + } + if (info->basic_info.in.attrib != FILE_ATTRIBUTE_NORMAL) { + newstats.dos.attrib = info->basic_info.in.attrib; } break; @@ -81,11 +108,54 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } return pvfs_change_create_options(pvfs, req, f, create_options); + case RAW_SFILEINFO_ALLOCATION_INFO: + case RAW_SFILEINFO_ALLOCATION_INFORMATION: + newstats.dos.alloc_size = info->allocation_info.in.alloc_size; + break; + + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + newstats.st.st_size = info->end_of_file_info.in.size; + break; + case RAW_SFILEINFO_POSITION_INFORMATION: f->position = info->position_information.in.position; break; + + default: + return NT_STATUS_INVALID_LEVEL; + } + + /* possibly change the file size */ + if (newstats.st.st_size != f->name->st.st_size) { + if (ftruncate(f->fd, newstats.st.st_size) == -1) { + return pvfs_map_errno(pvfs, errno); + } + } + + /* possibly change the file timestamps */ + ZERO_STRUCT(unix_times); + if (newstats.dos.access_time != f->name->dos.access_time) { + unix_times.actime = nt_time_to_unix(newstats.dos.access_time); + } + if (newstats.dos.write_time != f->name->dos.write_time) { + unix_times.modtime = nt_time_to_unix(newstats.dos.write_time); + } + if (unix_times.actime != 0 || unix_times.modtime != 0) { + if (utime(f->name->full_name, &unix_times) == -1) { + return pvfs_map_errno(pvfs, errno); + } + } + + /* possibly change the attribute */ + if (newstats.dos.attrib != f->name->dos.attrib) { + mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib); + if (fchmod(f->fd, mode) == -1) { + return pvfs_map_errno(pvfs, errno); + } } + return NT_STATUS_OK; } @@ -98,6 +168,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_filename *name; + struct pvfs_filename newstats; NTSTATUS status; struct utimbuf unix_times; @@ -112,42 +183,102 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + + /* we take a copy of the current file stats, then update + newstats in each of the elements below. At the end we + compare, and make any changes needed */ + newstats = *name; + switch (info->generic.level) { - case RAW_SFILEINFO_END_OF_FILE_INFO: - case RAW_SFILEINFO_END_OF_FILE_INFORMATION: - if (truncate(name->full_name, - info->end_of_file_info.in.size) == -1) { - return pvfs_map_errno(pvfs, errno); + case RAW_SFILEINFO_SETATTR: + if (!null_time(info->setattr.in.write_time)) { + unix_to_nt_time(&newstats.dos.write_time, info->setattr.in.write_time); } - break; + if (info->setattr.in.attrib != FILE_ATTRIBUTE_NORMAL) { + newstats.dos.attrib = info->setattr.in.attrib; + } + break; case RAW_SFILEINFO_SETATTRE: - unix_times.actime = info->setattre.in.access_time; - unix_times.modtime = info->setattre.in.write_time; - - if (unix_times.actime == 0 && unix_times.modtime == 0) { - break; - } - - /* set modify time = to access time if modify time was 0 */ - if (unix_times.actime != 0 && unix_times.modtime == 0) { - unix_times.modtime = unix_times.actime; + case RAW_SFILEINFO_STANDARD: + if (!null_time(info->setattre.in.create_time)) { + unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time); + } + if (!null_time(info->setattre.in.access_time)) { + unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time); } + if (!null_time(info->setattre.in.write_time)) { + unix_to_nt_time(&newstats.dos.write_time, info->setattre.in.write_time); + } + break; - /* Set the date on this file */ - if (utime(name->full_name, &unix_times) == -1) { - return NT_STATUS_ACCESS_DENIED; + case RAW_SFILEINFO_BASIC_INFO: + case RAW_SFILEINFO_BASIC_INFORMATION: + if (info->basic_info.in.create_time) { + newstats.dos.create_time = info->basic_info.in.create_time; + } + if (info->basic_info.in.access_time) { + newstats.dos.access_time = info->basic_info.in.access_time; + } + if (info->basic_info.in.write_time) { + newstats.dos.write_time = info->basic_info.in.write_time; + } + if (info->basic_info.in.change_time) { + newstats.dos.change_time = info->basic_info.in.change_time; + } + if (info->basic_info.in.attrib != FILE_ATTRIBUTE_NORMAL) { + newstats.dos.attrib = info->basic_info.in.attrib; } break; + case RAW_SFILEINFO_ALLOCATION_INFO: + case RAW_SFILEINFO_ALLOCATION_INFORMATION: + newstats.dos.alloc_size = info->allocation_info.in.alloc_size; + break; + + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + newstats.st.st_size = info->end_of_file_info.in.size; + break; + case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - return NT_STATUS_INVALID_PARAMETER; - case RAW_SFILEINFO_POSITION_INFORMATION: return NT_STATUS_OK; + + default: + return NT_STATUS_INVALID_LEVEL; } - return NT_STATUS_INVALID_LEVEL; + /* possibly change the file size */ + if (newstats.st.st_size != name->st.st_size) { + if (truncate(name->full_name, newstats.st.st_size) == -1) { + return pvfs_map_errno(pvfs, errno); + } + } + + /* possibly change the file timestamps */ + ZERO_STRUCT(unix_times); + if (newstats.dos.access_time != name->dos.access_time) { + unix_times.actime = nt_time_to_unix(newstats.dos.access_time); + } + if (newstats.dos.write_time != name->dos.write_time) { + unix_times.modtime = nt_time_to_unix(newstats.dos.write_time); + } + if (unix_times.actime != 0 || unix_times.modtime != 0) { + if (utime(name->full_name, &unix_times) == -1) { + return pvfs_map_errno(pvfs, errno); + } + } + + /* possibly change the attribute */ + if (newstats.dos.attrib != name->dos.attrib) { + mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib); + if (chmod(name->full_name, mode) == -1) { + return pvfs_map_errno(pvfs, errno); + } + } + + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 12ab583082..432481a88a 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -42,16 +42,23 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, } /* make sure its matches the given attributes */ - if (!pvfs_match_attrib(pvfs, name, attrib, 0)) { + status = pvfs_match_attrib(pvfs, name, attrib, 0); + if (!NT_STATUS_IS_OK(status)) { talloc_free(name); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + return status; } status = pvfs_can_delete(pvfs, name); if (!NT_STATUS_IS_OK(status)) { + talloc_free(name); return status; } + if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + talloc_free(name); + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + /* finally try the actual unlink */ if (unlink(name->full_name) == -1) { status = pvfs_map_errno(pvfs, errno); @@ -85,6 +92,11 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + if (name->exists && + (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + dir = talloc_p(req, struct pvfs_dir); if (dir == NULL) { return NT_STATUS_NO_MEMORY; @@ -97,10 +109,18 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (dir->count == 0) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + return NT_STATUS_NO_SUCH_FILE; } for (i=0;icount;i++) { + + /* this seems to be a special case */ + if ((unl->in.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (strcmp(dir->names[i], ".") == 0 || + strcmp(dir->names[i], "..") == 0)) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + status = pvfs_unlink_one(pvfs, req, dir->unix_path, dir->names[i], unl->in.attrib); if (NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index ae1dc6236d..50a78c2965 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -49,15 +49,17 @@ NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno) this is used by calls like unlink and search which take an attribute and only include special files if they match the given attribute */ -BOOL pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, - uint32_t attrib, uint32_t must_attrib) +NTSTATUS pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, + uint32_t attrib, uint32_t must_attrib) { - if ((name->dos.attrib & ~attrib) & - (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_SYSTEM)) { - return False; + if ((name->dos.attrib & ~attrib) & FILE_ATTRIBUTE_DIRECTORY) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + if ((name->dos.attrib & ~attrib) & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) { + return NT_STATUS_NO_SUCH_FILE; } if (must_attrib & ~name->dos.attrib) { - return False; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - return True; + return NT_STATUS_OK; } -- cgit From ba15d622d3e9d1eaf0b740c1367dee50f4b29e5c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 06:17:52 +0000 Subject: r3241: don't skip the read completely for a zero-length read, as it could give a lock conflict (This used to be commit 7ce6139f984c72a6347c7a64d95d5278bcf3e868) --- source4/ntvfs/posix/pvfs_read.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index ee750a138f..b36840cb15 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -33,6 +33,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, ssize_t ret; struct pvfs_file *f; NTSTATUS status; + uint32_t maxcnt; if (rd->generic.level != RAW_READ_READX) { return ntvfs_map_read(req, rd, ntvfs); @@ -51,15 +52,14 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_VIOLATION; } - /* this matches w2k3 behaviour for attempted large reads */ - if (rd->readx.in.maxcnt > UINT16_MAX) { - ret = 0; - goto done_read; + maxcnt = rd->readx.in.maxcnt; + if (maxcnt > UINT16_MAX) { + maxcnt = 0; } - + status = pvfs_check_lock(pvfs, f, req->smbpid, rd->readx.in.offset, - rd->readx.in.maxcnt, + maxcnt, READ_LOCK); if (!NT_STATUS_IS_OK(status)) { return status; @@ -67,13 +67,12 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, ret = pread(f->fd, rd->readx.out.data, - rd->readx.in.maxcnt, + maxcnt, rd->readx.in.offset); if (ret == -1) { return pvfs_map_errno(pvfs, errno); } -done_read: f->position = f->seek_offset = rd->readx.in.offset + ret; rd->readx.out.nread = ret; -- cgit From 67bd7a7cb9589b0db874323aa87246a997fcf922 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 07:03:12 +0000 Subject: r3246: new files should get created with FILE_ATTRIBUTE_ARCHIVE (This used to be commit 090574c6982f703b124a5a123d2199be8f5b3968) --- source4/ntvfs/posix/pvfs_open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index ffd1520b07..f533a36637 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -311,7 +311,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } - mode = pvfs_fileperms(pvfs, io->ntcreatex.in.file_attr); + mode = pvfs_fileperms(pvfs, io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE); /* create the file */ fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode); -- cgit From 220c289ecf01bb6a0915cd2427bb8408ea4a299e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 07:04:10 +0000 Subject: r3247: FILE_ATTRIBUTE_NORMAL is only a null-op for setattr and setattre, not basic_info (This used to be commit 36286e477c9bc7b6e268fffb123b565b6e897a44) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 71a9ce1266..4b00a8ac5d 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -90,7 +90,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, if (info->basic_info.in.change_time) { newstats.dos.change_time = info->basic_info.in.change_time; } - if (info->basic_info.in.attrib != FILE_ATTRIBUTE_NORMAL) { + if (info->basic_info.in.attrib != 0) { newstats.dos.attrib = info->basic_info.in.attrib; } break; -- cgit From 7a11723cfcb05a308568e3e286f63842c0b93942 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 07:04:45 +0000 Subject: r3248: don't stop searches on failed fill_search_info() (This used to be commit 4cdd750b5cc9b26dbbaebe58b4f1c3984dac8d6c) --- source4/ntvfs/posix/pvfs_search.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 61e4651c5f..9decf0f6ae 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -208,15 +208,9 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, status = fill_search_info(pvfs, level, dir->unix_path, dir->names[i], search, i, file); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - talloc_free(file); - continue; - } - if (!NT_STATUS_IS_OK(status)) { talloc_free(file); - search->current_index = i; - return status; + continue; } if (!callback(search_private, file)) { -- cgit From f1814e5a53d2f685e193ba5f28b38ea48efd9269 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 07:11:49 +0000 Subject: r3249: - change_time is closer to ctime than mtime - pvfs now passes the RAW-CLOSE test (This used to be commit 98aea91ce67a0c64a98537bfe244495f10672323) --- source4/ntvfs/posix/pvfs_fileinfo.c | 6 +++--- source4/ntvfs/posix/pvfs_open.c | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 2e2acb2c82..42aad1a20e 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -84,13 +84,13 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) /* for now just use the simple samba mapping */ unix_to_nt_time(&name->dos.create_time, name->st.st_ctime); unix_to_nt_time(&name->dos.access_time, name->st.st_atime); - unix_to_nt_time(&name->dos.write_time, name->st.st_mtime); - unix_to_nt_time(&name->dos.change_time, name->st.st_mtime); + unix_to_nt_time(&name->dos.write_time, name->st.st_mtime); + unix_to_nt_time(&name->dos.change_time, name->st.st_ctime); #ifdef HAVE_STAT_TV_NSEC name->dos.create_time += name->st.st_ctim.tv_nsec / 100; name->dos.access_time += name->st.st_atim.tv_nsec / 100; name->dos.write_time += name->st.st_mtim.tv_nsec / 100; - name->dos.change_time += name->st.st_mtim.tv_nsec / 100; + name->dos.change_time += name->st.st_ctim.tv_nsec / 100; #endif name->dos.attrib = dos_mode_from_stat(pvfs, &name->st); name->dos.alloc_size = name->st.st_size; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index f533a36637..1575ca82c1 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -634,6 +634,10 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct utimbuf unix_times; + if (io->generic.level == RAW_CLOSE_SPLCLOSE) { + return NT_STATUS_UNSUCCESSFUL; + } + if (io->generic.level != RAW_CLOSE_CLOSE) { return ntvfs_map_close(req, io, ntvfs); } -- cgit From 7f60959e64c4281e02fd11fbcce2d15f43da1892 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 08:35:29 +0000 Subject: r3253: - added rudimentary support for ntioctl in pvfs - catch the SIGXFSZ signal, which for some completely insane reason is generated in current Linux systems when you write before the maximum offset in a file (maximum is 2^41 on my box). Why wasn't errno good enough for this? - give the right ntstatus code for large offset write failures (This used to be commit 367f0c2af409e4292f727e8a865762a008fd7e67) --- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_ioctl.c | 87 ++++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_write.c | 3 ++ source4/ntvfs/posix/vfs_posix.c | 15 +++---- 4 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_ioctl.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 8d28bd5a44..4918ee61eb 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -23,6 +23,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_lock.o \ ntvfs/posix/pvfs_wait.o \ ntvfs/posix/pvfs_seek.o \ + ntvfs/posix/pvfs_ioctl.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c new file mode 100644 index 0000000000..15b9d6c27a --- /dev/null +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -0,0 +1,87 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - open and close + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "include/includes.h" +#include "vfs_posix.h" + +/* + old ioctl interface +*/ +static NTSTATUS pvfs_ioctl_old(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + + f = pvfs_find_fd(pvfs, req, io->ioctl.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + return NT_STATUS_NOT_SUPPORTED; +} + +/* + nt ioctl interface +*/ +static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + + f = pvfs_find_fd(pvfs, req, io->ntioctl.in.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + switch (io->ntioctl.in.function) { + case FSCTL_SET_SPARSE: + /* maybe some posix systems have a way of marking + a file non-sparse? */ + return NT_STATUS_OK; + } + + return NT_STATUS_NOT_SUPPORTED; +} + +/* + ioctl interface +*/ +NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) +{ + NTSTATUS status; + + switch (io->generic.level) { + case RAW_IOCTL_IOCTL: + status = pvfs_ioctl_old(ntvfs, req, io); + break; + + case RAW_IOCTL_NTIOCTL: + status = pvfs_ntioctl(ntvfs, req, io); + break; + } + + return status; +} + diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 7ab1d340bd..235a21882a 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -65,6 +65,9 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, wr->writex.in.count, wr->writex.in.offset); if (ret == -1) { + if (errno == EFBIG) { + return NT_STATUS_INVALID_PARAMETER; + } return map_nt_error_from_unix(errno); } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index cd41bf2329..b83e4c494e 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -122,6 +122,12 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs_setup_options(pvfs); +#ifdef SIGXFSZ + /* who had the stupid idea to generate a signal on a large + file write instead of just failing it!? */ + BlockSignals(True, SIGXFSZ); +#endif + return NT_STATUS_OK; } @@ -134,15 +140,6 @@ static NTSTATUS pvfs_disconnect(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } -/* - ioctl interface - we don't do any -*/ -static NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) -{ - return NT_STATUS_INVALID_PARAMETER; -} - /* check if a directory exists */ -- cgit From 4db039c3f33ff4119ced156f23786b1bcb73b5fd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 08:41:12 +0000 Subject: r3254: - expanded the RAW-IOCTL test - fixed the old ioctl interface to not check handle before failing - pvs now passes RAW-IOCTL (This used to be commit 98f6dbdba46c907039951559ec5f526410fd0039) --- source4/ntvfs/posix/pvfs_ioctl.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 15b9d6c27a..4feca8979f 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -29,15 +29,7 @@ static NTSTATUS pvfs_ioctl_old(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_ioctl *io) { - struct pvfs_state *pvfs = ntvfs->private_data; - struct pvfs_file *f; - - f = pvfs_find_fd(pvfs, req, io->ioctl.in.fnum); - if (!f) { - return NT_STATUS_INVALID_HANDLE; - } - - return NT_STATUS_NOT_SUPPORTED; + return NT_STATUS_UNSUCCESSFUL; } /* -- cgit From f9fdeaa8f47585870b13f7dbe65b697ee8c7e9bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 09:31:11 +0000 Subject: r3255: - fixed 2 uninitialised data errors found with valgrind - fixed offset of setup words in nttrans reply (This used to be commit 86b5118c2ae605560a196ee014b6134ec2928c5b) --- source4/ntvfs/posix/pvfs_ioctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 4feca8979f..3eb016c5b4 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -50,6 +50,7 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, case FSCTL_SET_SPARSE: /* maybe some posix systems have a way of marking a file non-sparse? */ + io->ntioctl.out.blob = data_blob(NULL, 0); return NT_STATUS_OK; } @@ -62,7 +63,7 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_ioctl *io) { - NTSTATUS status; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; switch (io->generic.level) { case RAW_IOCTL_IOCTL: -- cgit From 1fa9cb1449c5022f3ea55c4d9ceb02d2cd761cbf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 09:52:00 +0000 Subject: r3258: fixed "don't change" attribute for RAW_SFILEINFO_BASIC_INFO (This used to be commit 51f84800d50f44ec47a34e1c922c6197eb794558) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 4b00a8ac5d..bba3ee3747 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -226,7 +226,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, if (info->basic_info.in.change_time) { newstats.dos.change_time = info->basic_info.in.change_time; } - if (info->basic_info.in.attrib != FILE_ATTRIBUTE_NORMAL) { + if (info->basic_info.in.attrib != 0) { newstats.dos.attrib = info->basic_info.in.attrib; } break; -- cgit From e767d8d1b2c1e86e48d827f10f1773b0dab8e565 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 11:11:16 +0000 Subject: r3260: redid the pvfs_dirlist() interface in preparation for a "keep directory open" implementation, as opposed to the "load the whole directory" interface used now. This will be needed to pass RAW-SEARCH (This used to be commit 692623c6c0a2c6817fddfa77cd1c2525c27145c4) --- source4/ntvfs/posix/pvfs_dirlist.c | 40 ++++++++++++++++++++-- source4/ntvfs/posix/pvfs_search.c | 69 +++++++++++++++++--------------------- source4/ntvfs/posix/pvfs_unlink.c | 25 +++++++------- 3 files changed, 79 insertions(+), 55 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 0482cda808..59e755d6ff 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -57,12 +57,11 @@ static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filen } /* - read a directory and find all matching file names, returning them in - the structure *dir. The returned names are relative to the directory + start to read a directory if the pattern matches no files then we return NT_STATUS_OK, with dir->count = 0 */ -NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct pvfs_dir *dir) +NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, struct pvfs_dir *dir) { DIR *odir; struct dirent *dent; @@ -134,3 +133,38 @@ NTSTATUS pvfs_list(struct pvfs_state *pvfs, struct pvfs_filename *name, struct p return NT_STATUS_OK; } + +/* + return unix directory of an open search +*/ +const char *pvfs_list_unix_path(struct pvfs_dir *dir) +{ + return dir->unix_path; +} + +/* + return True if end of search has been reached +*/ +BOOL pvfs_list_eos(struct pvfs_dir *dir, uint_t ofs) +{ + return ofs >= dir->count; +} + +/* + return the next entry +*/ +const char *pvfs_list_next(struct pvfs_dir *dir, uint_t ofs) +{ + if (ofs >= dir->count) return NULL; + return dir->names[ofs]; +} + +/* + seek to the given name +*/ +uint_t pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t ofs) +{ + /* not correct, needs to be replaced with real search when + DIR* implementation is done */ + return ofs; +} diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 9decf0f6ae..5efc2f023f 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -73,12 +73,12 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, memcpy(file->search.id.name, shortname, MIN(strlen(shortname)+1, sizeof(file->search.id.name))); file->search.id.handle = search->handle; - file->search.id.server_cookie = dir_index+1; + file->search.id.server_cookie = dir_index; file->search.id.client_cookie = 0; return NT_STATUS_OK; case RAW_SEARCH_STANDARD: - file->standard.resume_key = dir_index+1; + file->standard.resume_key = dir_index; file->standard.create_time = nt_time_to_unix(name->dos.create_time); file->standard.access_time = nt_time_to_unix(name->dos.access_time); file->standard.write_time = nt_time_to_unix(name->dos.write_time); @@ -89,7 +89,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_SEARCH_EA_SIZE: - file->ea_size.resume_key = dir_index+1; + file->ea_size.resume_key = dir_index; file->ea_size.create_time = nt_time_to_unix(name->dos.create_time); file->ea_size.access_time = nt_time_to_unix(name->dos.access_time); file->ea_size.write_time = nt_time_to_unix(name->dos.write_time); @@ -101,7 +101,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_SEARCH_DIRECTORY_INFO: - file->directory_info.file_index = dir_index+1; + file->directory_info.file_index = dir_index; file->directory_info.create_time = name->dos.create_time; file->directory_info.access_time = name->dos.access_time; file->directory_info.write_time = name->dos.write_time; @@ -113,7 +113,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_SEARCH_FULL_DIRECTORY_INFO: - file->full_directory_info.file_index = dir_index+1; + file->full_directory_info.file_index = dir_index; file->full_directory_info.create_time = name->dos.create_time; file->full_directory_info.access_time = name->dos.access_time; file->full_directory_info.write_time = name->dos.write_time; @@ -131,7 +131,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_SEARCH_BOTH_DIRECTORY_INFO: - file->both_directory_info.file_index = dir_index+1; + file->both_directory_info.file_index = dir_index; file->both_directory_info.create_time = name->dos.create_time; file->both_directory_info.access_time = name->dos.access_time; file->both_directory_info.write_time = name->dos.write_time; @@ -145,7 +145,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: - file->id_full_directory_info.file_index = dir_index+1; + file->id_full_directory_info.file_index = dir_index; file->id_full_directory_info.create_time = name->dos.create_time; file->id_full_directory_info.access_time = name->dos.access_time; file->id_full_directory_info.write_time = name->dos.write_time; @@ -159,7 +159,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: - file->id_both_directory_info.file_index = dir_index+1; + file->id_both_directory_info.file_index = dir_index; file->id_both_directory_info.create_time = name->dos.create_time; file->id_both_directory_info.access_time = name->dos.access_time; file->id_both_directory_info.write_time = name->dos.write_time; @@ -192,22 +192,32 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - int i; struct pvfs_dir *dir = search->dir; NTSTATUS status; *reply_count = 0; - for (i = search->current_index; i < dir->count;i++) { + if (max_count == 0) { + max_count = 1; + } + + while ((*reply_count) < max_count) { union smb_search_data *file; + const char *name; + + name = pvfs_list_next(dir, search->current_index); + if (name == NULL) break; + + search->current_index++; file = talloc_p(mem_ctx, union smb_search_data); if (!file) { return NT_STATUS_NO_MEMORY; } - status = fill_search_info(pvfs, level, dir->unix_path, dir->names[i], - search, i, file); + status = fill_search_info(pvfs, level, + pvfs_list_unix_path(dir), name, + search, search->current_index, file); if (!NT_STATUS_IS_OK(status)) { talloc_free(file); continue; @@ -215,18 +225,14 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, if (!callback(search_private, file)) { talloc_free(file); + search->current_index--; break; } + (*reply_count)++; talloc_free(file); - - /* note that this deliberately allows a reply_count of - 1 for a max_count of 0. w2k3 allows this too. */ - if (*reply_count >= max_count) break; } - search->current_index = i; - return NT_STATUS_OK; } @@ -275,7 +281,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, } /* do the actual directory listing */ - status = pvfs_list(pvfs, name, dir); + status = pvfs_list_start(pvfs, name, dir); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -406,7 +412,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, } /* do the actual directory listing */ - status = pvfs_list(pvfs, name, dir); + status = pvfs_list_start(pvfs, name, dir); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -438,7 +444,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, io->t2ffirst.out.count = reply_count; io->t2ffirst.out.handle = search->handle; - io->t2ffirst.out.end_of_search = (search->current_index == dir->count) ? 1 : 0; + io->t2ffirst.out.end_of_search = pvfs_list_eos(dir, search->current_index) ? 1 : 0; /* work out if we are going to keep the search state and allow for a search continue */ @@ -465,7 +471,6 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, uint_t reply_count; uint16_t handle; NTSTATUS status; - int i; if (io->generic.level >= RAW_SEARCH_SEARCH) { return pvfs_search_next_old(ntvfs, req, io, search_private, callback); @@ -483,28 +488,14 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, /* work out what type of continuation is being used */ if (io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { - /* look backwards first */ - for (i=search->current_index; i > 0; i--) { - if (strcmp(io->t2fnext.in.last_name, dir->names[i-1]) == 0) { - search->current_index = i; - goto found; - } - } - - /* then look forwards */ - for (i=search->current_index+1; i <= dir->count; i++) { - if (strcmp(io->t2fnext.in.last_name, dir->names[i-1]) == 0) { - search->current_index = i; - goto found; - } - } + search->current_index = pvfs_list_seek(dir, io->t2fnext.in.last_name, + search->current_index); } else if (io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) { /* plain continue - nothing to do */ } else { search->current_index = io->t2fnext.in.resume_key; } -found: status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { @@ -517,7 +508,7 @@ found: } io->t2fnext.out.count = reply_count; - io->t2fnext.out.end_of_search = (search->current_index == dir->count) ? 1 : 0; + io->t2fnext.out.end_of_search = pvfs_list_eos(dir, search->current_index) ? 1 : 0; /* work out if we are going to keep the search state */ if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 432481a88a..74614d194a 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -81,6 +81,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, NTSTATUS status; uint32_t i, total_deleted=0; struct pvfs_filename *name; + const char *fname; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 0, &name); @@ -103,36 +104,34 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } /* get list of matching files */ - status = pvfs_list(pvfs, name, dir); + status = pvfs_list_start(pvfs, name, dir); if (!NT_STATUS_IS_OK(status)) { return status; } - if (dir->count == 0) { - return NT_STATUS_NO_SUCH_FILE; - } - - for (i=0;icount;i++) { + status = NT_STATUS_NO_SUCH_FILE; + for (i=0; + (fname = pvfs_list_next(dir, i)); + i++) { /* this seems to be a special case */ if ((unl->in.attrib & FILE_ATTRIBUTE_DIRECTORY) && - (strcmp(dir->names[i], ".") == 0 || - strcmp(dir->names[i], "..") == 0)) { + (strcmp(fname, ".") == 0 || + strcmp(fname, "..") == 0)) { return NT_STATUS_OBJECT_NAME_INVALID; } - status = pvfs_unlink_one(pvfs, req, dir->unix_path, - dir->names[i], unl->in.attrib); + status = pvfs_unlink_one(pvfs, req, dir->unix_path, fname, unl->in.attrib); if (NT_STATUS_IS_OK(status)) { total_deleted++; } } - if (total_deleted == 0) { - return status; + if (total_deleted > 0) { + status = NT_STATUS_OK; } - return NT_STATUS_OK; + return status; } -- cgit From ee7fa4812c8366588b77d6be91b8666a275ba92c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 13:18:34 +0000 Subject: r3262: - new pvfs_dirlist code that reopens the directory between search calls. This is needed to allow for "new files appear during a search" behaviour - pvfs now passes RAW-SEARCH (This used to be commit 0d98f7653a1d58510a6cd4c2ac6c5e05c541109c) --- source4/ntvfs/posix/pvfs_dirlist.c | 210 ++++++++++++++++++++++++++----------- source4/ntvfs/posix/pvfs_search.c | 40 +++---- source4/ntvfs/posix/pvfs_unlink.c | 18 ++-- source4/ntvfs/posix/vfs_posix.h | 9 -- 4 files changed, 176 insertions(+), 101 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 59e755d6ff..3f5b606bf9 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -24,6 +24,16 @@ #include "includes.h" #include "vfs_posix.h" +struct pvfs_dir { + struct pvfs_state *pvfs; + BOOL no_wildcard; + char *last_name; + off_t offset; + DIR *dir; + const char *unix_path; + BOOL end_of_search; +}; + /* a special directory listing case where the pattern has no wildcard. We can just do a single stat() thus avoiding the more expensive directory scan @@ -35,38 +45,52 @@ static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filen return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - dir->count = 0; + dir->pvfs = pvfs; + dir->no_wildcard = True; + dir->end_of_search = False; dir->unix_path = talloc_strdup(dir, name->full_name); if (!dir->unix_path) { return NT_STATUS_NO_MEMORY; } - dir->names = talloc_array_p(dir, const char *, 1); - if (!dir->names) { + dir->last_name = talloc_strdup(dir, pattern); + if (!dir->last_name) { return NT_STATUS_NO_MEMORY; } - dir->names[0] = talloc_strdup(dir, pattern); - if (!dir->names[0]) { - return NT_STATUS_NO_MEMORY; - } - - dir->count = 1; + dir->dir = NULL; + dir->offset = 0; return NT_STATUS_OK; } +/* + destroy an open search +*/ +static int pvfs_dirlist_destructor(void *ptr) +{ + struct pvfs_dir *dir = ptr; + if (dir->dir) closedir(dir->dir); + return 0; +} + /* start to read a directory if the pattern matches no files then we return NT_STATUS_OK, with dir->count = 0 */ -NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, struct pvfs_dir *dir) +NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, + TALLOC_CTX *mem_ctx, struct pvfs_dir **dirp) { - DIR *odir; - struct dirent *dent; - uint_t allocated = 0; char *pattern; + struct pvfs_dir *dir; + + (*dirp) = talloc_p(mem_ctx, struct pvfs_dir); + if (*dirp == NULL) { + return NT_STATUS_NO_MEMORY; + } + + dir = *dirp; /* split the unix path into a directory + pattern */ pattern = strrchr(name->full_name, '/'); @@ -82,58 +106,104 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, st return pvfs_list_no_wildcard(pvfs, name, pattern, dir); } - dir->names = NULL; - dir->count = 0; dir->unix_path = talloc_strdup(dir, name->full_name); if (!dir->unix_path) { return NT_STATUS_NO_MEMORY; } - odir = opendir(name->full_name); - if (!odir) { + dir->dir = opendir(name->full_name); + if (!dir->dir) { return pvfs_map_errno(pvfs, errno); } - while ((dent = readdir(odir))) { - uint_t i = dir->count; - const char *dname = dent->d_name; - - if (ms_fnmatch(pattern, dname, - pvfs->tcon->smb_conn->negotiate.protocol) != 0) { - char *short_name = pvfs_short_name_component(pvfs, dname); - if (short_name == NULL || - ms_fnmatch(pattern, short_name, - pvfs->tcon->smb_conn->negotiate.protocol) != 0) { - talloc_free(short_name); - continue; - } - talloc_free(short_name); - } + dir->pvfs = pvfs; + dir->no_wildcard = False; + dir->last_name = NULL; + dir->end_of_search = False; + dir->offset = 0; - if (dir->count >= allocated) { - allocated = (allocated + 100) * 1.2; - dir->names = talloc_realloc_p(dir, dir->names, const char *, allocated); - if (!dir->names) { - closedir(odir); - return NT_STATUS_NO_MEMORY; - } - } + talloc_set_destructor(dir, pvfs_dirlist_destructor); - dir->names[i] = talloc_strdup(dir, dname); - if (!dir->names[i]) { - closedir(odir); - return NT_STATUS_NO_MEMORY; - } - - dir->count++; + return NT_STATUS_OK; +} + +/* + return the next entry +*/ +const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) +{ + struct dirent *de; + + /* non-wildcard searches are easy */ + if (dir->no_wildcard) { + dir->end_of_search = True; + if (*ofs != 0) return NULL; + (*ofs)++; + return dir->last_name; + } + + if (*ofs != dir->offset) { + seekdir(dir->dir, *ofs); + dir->offset = *ofs; + } + + de = readdir(dir->dir); + if (de == NULL) { + dir->last_name = NULL; + dir->end_of_search = True; + pvfs_list_hibernate(dir); + return NULL; } - closedir(odir); + dir->offset = telldir(dir->dir); + (*ofs) = dir->offset; + + dir->last_name = de->d_name; + + return dir->last_name; +} + +/* + put the directory to sleep. Used between search calls to give the + right directory change semantics +*/ +void pvfs_list_hibernate(struct pvfs_dir *dir) +{ + if (dir->dir) { + closedir(dir->dir); + dir->dir = NULL; + } +} + + +/* + wake up the directory search +*/ +NTSTATUS pvfs_list_wakeup(struct pvfs_dir *dir, uint_t *ofs) +{ + if (dir->no_wildcard || + dir->dir != NULL) { + return NT_STATUS_OK; + } + + dir->dir = opendir(dir->unix_path); + if (dir->dir == NULL) { + dir->end_of_search = True; + return pvfs_map_errno(dir->pvfs, errno); + } + + seekdir(dir->dir, *ofs); + dir->offset = telldir(dir->dir); + if (dir->offset != *ofs) { + DEBUG(0,("pvfs_list_wakeup: search offset changed %u -> %u\n", + *ofs, (unsigned)dir->offset)); + } return NT_STATUS_OK; } + /* return unix directory of an open search */ @@ -147,24 +217,40 @@ const char *pvfs_list_unix_path(struct pvfs_dir *dir) */ BOOL pvfs_list_eos(struct pvfs_dir *dir, uint_t ofs) { - return ofs >= dir->count; -} - -/* - return the next entry -*/ -const char *pvfs_list_next(struct pvfs_dir *dir, uint_t ofs) -{ - if (ofs >= dir->count) return NULL; - return dir->names[ofs]; + return dir->end_of_search; } /* seek to the given name */ -uint_t pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t ofs) +NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) { - /* not correct, needs to be replaced with real search when - DIR* implementation is done */ - return ofs; + struct dirent *de; + NTSTATUS status; + + status = pvfs_list_wakeup(dir, ofs); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (StrCaseCmp(name, dir->last_name) == 0) { + *ofs = dir->offset; + return NT_STATUS_OK; + } + + rewinddir(dir->dir); + + while ((de = readdir(dir->dir))) { + if (StrCaseCmp(name, de->d_name) == 0) { + dir->offset = telldir(dir->dir); + *ofs = dir->offset; + return NT_STATUS_OK; + } + } + + dir->end_of_search = True; + + pvfs_list_hibernate(dir); + + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 5efc2f023f..0df3ebee0f 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -204,12 +204,11 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, while ((*reply_count) < max_count) { union smb_search_data *file; const char *name; + uint_t ofs = search->current_index; - name = pvfs_list_next(dir, search->current_index); + name = pvfs_list_next(dir, &search->current_index); if (name == NULL) break; - search->current_index++; - file = talloc_p(mem_ctx, union smb_search_data); if (!file) { return NT_STATUS_NO_MEMORY; @@ -225,7 +224,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, if (!callback(search_private, file)) { talloc_free(file); - search->current_index--; + search->current_index = ofs; break; } @@ -233,6 +232,8 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, talloc_free(file); } + pvfs_list_hibernate(dir); + return NT_STATUS_OK; } @@ -275,13 +276,8 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - dir = talloc_p(search, struct pvfs_dir); - if (!dir) { - return NT_STATUS_NO_MEMORY; - } - /* do the actual directory listing */ - status = pvfs_list_start(pvfs, name, dir); + status = pvfs_list_start(pvfs, name, search, &dir); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -343,9 +339,13 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, } search->current_index = io->search_next.in.id.server_cookie; - dir = search->dir; + status = pvfs_list_wakeup(dir, &search->current_index); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { @@ -406,13 +406,8 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - dir = talloc_p(search, struct pvfs_dir); - if (!dir) { - return NT_STATUS_NO_MEMORY; - } - /* do the actual directory listing */ - status = pvfs_list_start(pvfs, name, dir); + status = pvfs_list_start(pvfs, name, search, &dir); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -488,14 +483,21 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, /* work out what type of continuation is being used */ if (io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { - search->current_index = pvfs_list_seek(dir, io->t2fnext.in.last_name, - search->current_index); + status = pvfs_list_seek(dir, io->t2fnext.in.last_name, &search->current_index); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } else if (io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) { /* plain continue - nothing to do */ } else { search->current_index = io->t2fnext.in.resume_key; } + status = pvfs_list_wakeup(dir, &search->current_index); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 74614d194a..ff02d77613 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -79,9 +79,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_dir *dir; NTSTATUS status; - uint32_t i, total_deleted=0; + uint32_t total_deleted=0; struct pvfs_filename *name; const char *fname; + uint_t ofs; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 0, &name); @@ -98,22 +99,17 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - dir = talloc_p(req, struct pvfs_dir); - if (dir == NULL) { - return NT_STATUS_NO_MEMORY; - } - /* get list of matching files */ - status = pvfs_list_start(pvfs, name, dir); + status = pvfs_list_start(pvfs, name, req, &dir); if (!NT_STATUS_IS_OK(status)) { return status; } status = NT_STATUS_NO_SUCH_FILE; - for (i=0; - (fname = pvfs_list_next(dir, i)); - i++) { + ofs = 0; + + while ((fname = pvfs_list_next(dir, &ofs))) { /* this seems to be a special case */ if ((unl->in.attrib & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(fname, ".") == 0 || @@ -121,7 +117,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_INVALID; } - status = pvfs_unlink_one(pvfs, req, dir->unix_path, fname, unl->in.attrib); + status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->in.attrib); if (NT_STATUS_IS_OK(status)) { total_deleted++; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 48a2ba9288..19408848fd 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -75,15 +75,6 @@ struct pvfs_filename { }; -/* this holds a list of file names for a search. We deliberately do - not hold the file stat information here to minimise the memory - overhead of idle searches */ -struct pvfs_dir { - uint_t count; - const char *unix_path; - const char **names; -}; - /* the state of a search started with pvfs_search_first() */ struct pvfs_search_state { struct pvfs_state *pvfs; -- cgit From 731e64cdcfebd39ac32aa87d34dcf511caeda57f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 22:25:34 +0000 Subject: r3268: - fixed wildcard handling in new dirlist code - ensure that d_name from readdir is not used after closedir (This used to be commit 5352613342c58192ae00618977041b98cd0ff7b6) --- source4/ntvfs/posix/pvfs_dirlist.c | 53 +++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 3f5b606bf9..79f014d967 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -28,6 +28,7 @@ struct pvfs_dir { struct pvfs_state *pvfs; BOOL no_wildcard; char *last_name; + const char *pattern; off_t offset; DIR *dir; const char *unix_path; @@ -60,6 +61,7 @@ static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filen dir->dir = NULL; dir->offset = 0; + dir->pattern = NULL; return NT_STATUS_OK; } @@ -110,6 +112,11 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, if (!dir->unix_path) { return NT_STATUS_NO_MEMORY; } + + dir->pattern = talloc_strdup(dir, pattern); + if (dir->pattern == NULL) { + return NT_STATUS_NO_MEMORY; + } dir->dir = opendir(name->full_name); if (!dir->dir) { @@ -147,20 +154,35 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) dir->offset = *ofs; } - de = readdir(dir->dir); - if (de == NULL) { - dir->last_name = NULL; - dir->end_of_search = True; - pvfs_list_hibernate(dir); - return NULL; - } + while ((de = readdir(dir->dir))) { + const char *dname = de->d_name; + + if (ms_fnmatch(dir->pattern, dname, + dir->pvfs->tcon->smb_conn->negotiate.protocol) != 0) { + char *short_name = pvfs_short_name_component(dir->pvfs, dname); + if (short_name == NULL || + ms_fnmatch(dir->pattern, short_name, + dir->pvfs->tcon->smb_conn->negotiate.protocol) != 0) { + talloc_free(short_name); + continue; + } + talloc_free(short_name); + } - dir->offset = telldir(dir->dir); - (*ofs) = dir->offset; + dir->offset = telldir(dir->dir); + (*ofs) = dir->offset; - dir->last_name = de->d_name; + if (dir->last_name) talloc_free(dir->last_name); + dir->last_name = talloc_strdup(dir, de->d_name); - return dir->last_name; + return dir->last_name; + } + + if (dir->last_name) talloc_free(dir->last_name); + dir->last_name = NULL; + dir->end_of_search = True; + pvfs_list_hibernate(dir); + return NULL; } /* @@ -173,6 +195,10 @@ void pvfs_list_hibernate(struct pvfs_dir *dir) closedir(dir->dir); dir->dir = NULL; } + if (!dir->no_wildcard && dir->last_name) { + talloc_free(dir->last_name); + dir->last_name = NULL; + } } @@ -233,7 +259,8 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) return status; } - if (StrCaseCmp(name, dir->last_name) == 0) { + if (dir->last_name && + StrCaseCmp(name, dir->last_name) == 0) { *ofs = dir->offset; return NT_STATUS_OK; } @@ -244,6 +271,8 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) if (StrCaseCmp(name, de->d_name) == 0) { dir->offset = telldir(dir->dir); *ofs = dir->offset; + if (dir->last_name) talloc_free(dir->last_name); + dir->last_name = talloc_strdup(dir, de->d_name); return NT_STATUS_OK; } } -- cgit From 05ad898f68a2df1b102af95fdba0704479bde073 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 26 Oct 2004 22:45:33 +0000 Subject: r3271: use "struct messaging_context *" instead of "void *" in messaging API (This used to be commit cc93813e4a09c538ad485dc2b3cb4c9be34f3d18) --- source4/ntvfs/common/brlock.c | 4 ++-- source4/ntvfs/common/opendb.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 607947615e..d4b152cf42 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -61,7 +61,7 @@ struct brl_context { struct tdb_wrap *w; servid_t server; uint16_t tid; - void *messaging_ctx; + struct messaging_context *messaging_ctx; struct lock_struct last_lock_failure; }; @@ -72,7 +72,7 @@ struct brl_context { pending lock notifications. */ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, - void *messaging_ctx) + struct messaging_context *messaging_ctx) { char *path; struct brl_context *brl; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index a3924daf8e..d8ca4c999d 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -44,7 +44,7 @@ struct odb_context { struct tdb_wrap *w; servid_t server; uint16_t tid; - void *messaging_ctx; + struct messaging_context *messaging_ctx; }; /* @@ -76,7 +76,7 @@ struct odb_lock { notifications. */ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, - void *messaging_ctx) + struct messaging_context *messaging_ctx) { char *path; struct odb_context *odb; -- cgit From b9ddb09f03332a9c4442e61bb5c73f7bde04d1d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Oct 2004 01:11:44 +0000 Subject: r3276: - allow for more than 256 open old style searches (limit currently set at an arbitrary 5000) - auto-cleanup old searches that the client forgot to close (common with old searches) - expanded the RAW-SEARCH test to test more than 256 old searches, and old search rewind (w2k3 fails this - it appears to not support rewind on old style searches) (This used to be commit bc83d823b2140a10007490bf0101843a886f99a6) --- source4/ntvfs/posix/pvfs_search.c | 54 ++++++++++++++++++++++++++++++++++++--- source4/ntvfs/posix/vfs_posix.h | 13 +++------- 2 files changed, 53 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 0df3ebee0f..43d0f946b7 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -24,6 +24,22 @@ #include "vfs_posix.h" +/* the state of a search started with pvfs_search_first() */ +struct pvfs_search_state { + struct pvfs_state *pvfs; + uint16_t handle; + uint_t current_index; + uint16_t search_attrib; + uint16_t must_attrib; + struct pvfs_dir *dir; + time_t last_used; +}; + + +/* place a reasonable limit on old-style searches as clients tend to + not send search close requests */ +#define MAX_OLD_SEARCHES 2000 + /* destroy an open search */ @@ -68,11 +84,11 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->search.write_time = nt_time_to_unix(name->dos.write_time); file->search.size = name->st.st_size; file->search.name = shortname; - file->search.id.reserved = 8; + file->search.id.reserved = search->handle >> 8; memset(file->search.id.name, ' ', sizeof(file->search.id.name)); memcpy(file->search.id.name, shortname, MIN(strlen(shortname)+1, sizeof(file->search.id.name))); - file->search.id.handle = search->handle; + file->search.id.handle = search->handle & 0xFF; file->search.id.server_cookie = dir_index; file->search.id.client_cookie = 0; return NT_STATUS_OK; @@ -237,6 +253,29 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } +/* + we've run out of search handles - cleanup those that the client forgot + to close +*/ +static void pvfs_search_cleanup(struct pvfs_state *pvfs) +{ + int i; + time_t t = time(NULL); + + for (i=0;iidtree_search, i); + if (search == NULL) return; + if (pvfs_list_eos(search->dir, search->current_index) && + search->last_used != 0 && + t > search->last_used + 30) { + /* its almost certainly been forgotten + about */ + talloc_free(search); + } + } +} + + /* list files in a directory matching a wildcard pattern - old SMBsearch interface */ @@ -284,7 +323,11 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, /* we need to give a handle back to the client so it can continue a search */ - id = idr_get_new(pvfs->idtree_search, search, UINT8_MAX); + id = idr_get_new(pvfs->idtree_search, search, MAX_OLD_SEARCHES); + if (id == -1) { + pvfs_search_cleanup(pvfs); + id = idr_get_new(pvfs->idtree_search, search, MAX_OLD_SEARCHES); + } if (id == -1) { return NT_STATUS_INSUFFICIENT_RESOURCES; } @@ -295,6 +338,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, search->current_index = 0; search->search_attrib = search_attrib & 0xFF; search->must_attrib = (search_attrib>>8) & 0xFF; + search->last_used = time(NULL); talloc_set_destructor(search, pvfs_search_destructor); @@ -329,7 +373,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, uint16_t handle; NTSTATUS status; - handle = io->search_next.in.id.handle; + handle = io->search_next.in.id.handle | (io->search_next.in.id.reserved<<8); max_count = io->search_next.in.max_count; search = idr_find(pvfs->idtree_search, handle); @@ -339,6 +383,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, } search->current_index = io->search_next.in.id.server_cookie; + search->last_used = time(NULL); dir = search->dir; status = pvfs_list_wakeup(dir, &search->current_index); @@ -423,6 +468,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, search->current_index = 0; search->search_attrib = search_attrib; search->must_attrib = 0; + search->last_used = 0; talloc_set_destructor(search, pvfs_search_destructor); diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 19408848fd..231d9a2d08 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -75,16 +75,6 @@ struct pvfs_filename { }; -/* the state of a search started with pvfs_search_first() */ -struct pvfs_search_state { - struct pvfs_state *pvfs; - uint16_t handle; - uint_t current_index; - uint16_t search_attrib; - uint16_t must_attrib; - struct pvfs_dir *dir; -}; - /* open file state */ struct pvfs_file { struct pvfs_file *next, *prev; @@ -161,4 +151,7 @@ struct pvfs_mangle_context { #define PVFS_FLAG_STRICT_SYNC (1<<5) #define PVFS_FLAG_STRICT_LOCKING (1<<6) +/* forward declare some anonymous structures */ +struct pvfs_dir; + #endif /* _VFS_POSIX_H_ */ -- cgit From 9d055846f225bea4953822f40fab1d2f1a2e2d07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Oct 2004 03:15:42 +0000 Subject: r3278: - rewrote the client side rpc connection code to use lib/socket/ rather than doing everything itself. This greatly simplifies the code, although I really don't like the socket_recv() interface (it always allocates memory for you, which means an extra memcpy in this code) - fixed several bugs in the socket_ipv4.c code, in particular client side code used a non-blocking connect but didn't handle EINPROGRESS, so it had no chance of working. Also fixed the error codes, using map_nt_error_from_unix() - cleaned up and expanded map_nt_error_from_unix() - changed interpret_addr2() to not take a mem_ctx. It makes absolutely no sense to allocate a fixed size 4 byte structure like this. Dozens of places in the code were also using interpret_addr2() incorrectly (precisely because the allocation made no sense) (This used to be commit 7f2c771b0e0e98c5c9e5cf662592d64d34ff1205) --- source4/ntvfs/posix/pvfs_wait.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 2a4a1d286b..071ecbce15 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -29,7 +29,7 @@ struct pvfs_wait { void *private; struct timed_event *te; int msg_type; - void *msg_ctx; + struct messaging_context *msg_ctx; struct event_context *ev; struct smbsrv_request *req; BOOL timed_out; @@ -51,7 +51,7 @@ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, /* receive a completion message for a wait */ -static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, +static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uint32_t msg_type, servid_t src, DATA_BLOB *data) { struct pvfs_wait *pwait = private; -- cgit From 074da7ccf72bba1868d3f9e4ce206acbd56c8074 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Oct 2004 08:36:51 +0000 Subject: r3288: - updated the path processing in pvfs to pass the RAW-CHKPATH test. This rather extensive test reveals some really bizarre error code handling in w2k3. - extended and simplified the RAW-CHKPATH test, making it easier to read (note that Samba3 fails the new tests - jra may wish to look) - marked RAW-CHKPATH as pass for pvfs (This used to be commit 32dccf91cfa5b57f84dd6307720b3f45faa10ae0) --- source4/ntvfs/posix/pvfs_resolve.c | 81 +++++++++++++++++++++++--------------- source4/ntvfs/posix/vfs_posix.c | 3 +- 2 files changed, 52 insertions(+), 32 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index a7a693b217..75fbeb39a5 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -116,7 +116,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * /* check if this component exists as-is */ if (stat(test_name, &name->st) == 0) { if (ist.st_mode)) { - return NT_STATUS_NOT_A_DIRECTORY; + return NT_STATUS_OBJECT_PATH_NOT_FOUND; } talloc_free(partial_name); partial_name = test_name; @@ -193,7 +193,6 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, uint_t flags, struct pvfs_filename *name) { char *ret, *p, *p_start; - size_t len; name->original_name = talloc_strdup(name, cifs_name); name->stream_name = NULL; @@ -218,18 +217,10 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, p = ret + strlen(pvfs->base_directory) + 1; - len = strlen(cifs_name); - if (len>0 && p[len-1] == '\\') { - p[len-1] = 0; - len--; - } - if (len>1 && p[len-1] == '.' && p[len-2] == '\\') { - return NT_STATUS_OBJECT_NAME_INVALID; - } - /* now do an in-place conversion of '\' to '/', checking for legal characters */ p_start = p; + while (*p) { size_t c_size; codepoint_t c = next_codepoint(p, &c_size); @@ -240,7 +231,11 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, of a name */ return NT_STATUS_ILLEGAL_CHARACTER; } - *p = '/'; + if (p > p_start && p[1] == 0) { + *p = 0; + } else { + *p = '/'; + } break; case ':': if (!(flags & PVFS_RESOLVE_STREAMS)) { @@ -258,7 +253,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, case '?': case '"': if (flags & PVFS_RESOLVE_NO_WILDCARD) { - return NT_STATUS_ILLEGAL_CHARACTER; + return NT_STATUS_OBJECT_NAME_INVALID; } name->has_wildcard = True; break; @@ -297,30 +292,26 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, reduce a name that contains .. components or repeated \ separators return NULL if it can't be reduced */ -const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname) +static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t flags) { codepoint_t c; size_t c_size, len; - int i, num_components; + int i, num_components, err_count; char **components; char *p, *s, *ret; - s = talloc_strdup(mem_ctx, fname); - if (s == NULL) return NULL; + s = talloc_strdup(mem_ctx, *fname); + if (s == NULL) return NT_STATUS_NO_MEMORY; for (num_components=1, p=s; *p; p += c_size) { c = next_codepoint(p, &c_size); if (c == '\\') num_components++; } - if (num_components < 2) { - talloc_free(s); - return NULL; - } components = talloc_array_p(s, char *, num_components+1); if (components == NULL) { talloc_free(s); - return NULL; + return NT_STATUS_NO_MEMORY; } components[0] = s; @@ -333,16 +324,40 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname) } components[i+1] = NULL; + /* + rather bizarre! + + '.' components are not allowed, but the rules for what error + code to give don't seem to make sense. This is a close + approximation. + */ + for (err_count=i=0;components[i];i++) { + if (strcmp(components[i], "") == 0) { + continue; + } + if (strcmp(components[i], ".") == 0 || err_count) { + err_count++; + } + } + if (err_count) { + if (!(flags & PVFS_RESOLVE_NO_WILDCARD)) err_count--; + + if (err_count==1) { + return NT_STATUS_OBJECT_NAME_INVALID; + } else { + return NT_STATUS_OBJECT_PATH_NOT_FOUND; + } + } + /* remove any null components */ for (i=0;components[i];i++) { - if (strcmp(components[i], "") == 0 || - strcmp(components[i], ".") == 0) { + if (strcmp(components[i], "") == 0) { memmove(&components[i], &components[i+1], sizeof(char *)*(num_components-i)); i--; } if (strcmp(components[i], "..") == 0) { - if (i < 1) return NULL; + if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; memmove(&components[i-1], &components[i+1], sizeof(char *)*(num_components-(i+1))); i -= 2; @@ -351,7 +366,8 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname) if (components[0] == NULL) { talloc_free(s); - return talloc_strdup(mem_ctx, "\\"); + *fname = talloc_strdup(mem_ctx, "\\"); + return NT_STATUS_OK; } for (len=i=0;components[i];i++) { @@ -362,7 +378,7 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname) ret = talloc(mem_ctx, len+1); if (ret == NULL) { talloc_free(s); - return NULL; + return NT_STATUS_NO_MEMORY; } for (len=0,i=0;components[i];i++) { @@ -374,8 +390,10 @@ const char *pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char *fname) ret[len] = 0; talloc_free(s); + + *fname = ret; - return ret; + return NT_STATUS_OK; } @@ -408,10 +426,11 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) { /* it might contain .. components which need to be reduced */ - cifs_name = pvfs_reduce_name(*name, cifs_name); - if (cifs_name) { - status = pvfs_unix_path(pvfs, cifs_name, flags, *name); + status = pvfs_reduce_name(*name, &cifs_name, flags); + if (!NT_STATUS_IS_OK(status)) { + return status; } + status = pvfs_unix_path(pvfs, cifs_name, flags, *name); } if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index b83e4c494e..8dc87b160d 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -151,7 +151,8 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs, NTSTATUS status; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name); + status = pvfs_resolve_name(pvfs, req, cp->in.path, + PVFS_RESOLVE_NO_WILDCARD, &name); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From fbb44e96169cb0b18cb0a242fd412a88c16faadb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Oct 2004 13:38:30 +0000 Subject: r3290: allow SID_ANONYMOUS ( "S-1-5-7" ) to be the users sid metze (This used to be commit 177afd4855c66f46c82899b46f030803be63d52a) --- source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 440ebd21c8..062f6b1b85 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -57,7 +57,7 @@ static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, /* make sure its a user, not a group */ atype = samdb_result_uint(res[0], "sAMAccountType", 0); - if (!atype || (!(atype & ATYPE_ACCOUNT))) { + if (atype && (!(atype & ATYPE_ACCOUNT))) { DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", sidstr)); talloc_free(ctx); return NT_STATUS_ACCESS_DENIED; -- cgit From c8c3a56b8bf0db89fdb8f548fe6016cb87d115ad Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 06:45:28 +0000 Subject: r3312: in the brlock code, we prevent lock stampedes by attempting to not wakeup all pending locks at once. This change means that we only trigger this anti-stampede code for write locks, as for pending read locks the correct behaviour is to stampede (as they will all succeed) (This used to be commit 8021d1d74207db1204139309592b9d2f80f2bd0e) --- source4/ntvfs/common/brlock.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d4b152cf42..b43f0705a5 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -338,7 +338,9 @@ static void brl_notify_unlock(struct brl_context *brl, if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { continue; } - last_notice = i; + if (locks[i].lock_type == PENDING_WRITE_LOCK) { + last_notice = i; + } data.data = (void *)&locks[i].notify_ptr; data.length = sizeof(void *); messaging_send(brl->messaging_ctx, locks[i].context.server, MSG_BRL_RETRY, &data); -- cgit From a6ae640313a47ac2950c0948e4385fa934a5ef09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 28 Oct 2004 13:19:39 +0000 Subject: r3323: more warning reductions (This used to be commit 5921587ec26e4892efc678421277e4969417d7f5) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 3 +++ source4/ntvfs/simple/vfs_simple.c | 49 +++++++++++------------------------- 2 files changed, 18 insertions(+), 34 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 04c196121a..db4951fff0 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -31,6 +31,9 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, struct pvfs_filename *name, union smb_fileinfo *info) { switch (info->generic.level) { + case RAW_FILEINFO_GENERIC: + return NT_STATUS_INVALID_LEVEL; + case RAW_FILEINFO_GETATTR: info->getattr.out.attrib = name->dos.attrib; info->getattr.out.size = name->st.st_size; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index faf8f17b78..379d24f848 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -508,43 +508,24 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, { ssize_t ret; - CHECK_READ_ONLY(req); + if (wr->generic.level != RAW_WRITE_WRITEX) { + return ntvfs_map_write(req, wr, ntvfs); + } - switch (wr->generic.level) { - case RAW_WRITE_WRITEX: - ret = pwrite(wr->writex.in.fnum, - wr->writex.in.data, - wr->writex.in.count, - wr->writex.in.offset); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - wr->writex.out.nwritten = ret; - wr->writex.out.remaining = 0; /* should fill this in? */ - - return NT_STATUS_OK; - - case RAW_WRITE_WRITE: - if (wr->write.in.count == 0) { - /* a truncate! */ - ret = ftruncate(wr->write.in.fnum, wr->write.in.offset); - } else { - ret = pwrite(wr->write.in.fnum, - wr->write.in.data, - wr->write.in.count, - wr->write.in.offset); - } - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - wr->write.out.nwritten = ret; + CHECK_READ_ONLY(req); - return NT_STATUS_OK; + ret = pwrite(wr->writex.in.fnum, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); } - - return NT_STATUS_NOT_SUPPORTED; + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; } /* -- cgit From 019719595778e0bd0a00781b33407554d1943985 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Oct 2004 21:48:53 +0000 Subject: r3336: use a struct ntvfs_async_state to be able to do async chaning of ntvfs modules the idea is that a passthru module can use ntvfs_async_state_push() before calling ntvfs_next_*() and in the _send function it calls ntvfs_async_state_pop() and then call the upper layer send_fn itself - ntvfs_nbench is now fully async - the ntvfs_map_*() functions and the trans(2) mapping functions are not converted yet metze (This used to be commit fde64c0dc142b53d128c8ba09af048dc58d8ef3a) --- source4/ntvfs/cifs/vfs_cifs.c | 78 +++--- source4/ntvfs/nbench/vfs_nbench.c | 565 ++++++++++++++++++++++++++------------ source4/ntvfs/ntvfs.h | 33 +++ source4/ntvfs/ntvfs_base.c | 2 + source4/ntvfs/ntvfs_generic.c | 8 +- source4/ntvfs/ntvfs_util.c | 38 ++- source4/ntvfs/posix/pvfs_lock.c | 14 +- source4/ntvfs/posix/pvfs_wait.c | 2 +- 8 files changed, 508 insertions(+), 232 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 1a0f1f2f71..9c5cfd9584 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -182,8 +182,8 @@ static void async_simple(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smbcli_request_simple_recv(c_req); - req->async.send_fn(req); + req->async_states->status = smbcli_request_simple_recv(c_req); + req->async_states->send_fn(req); } @@ -199,7 +199,7 @@ static void async_simple(struct smbcli_request *c_req) c_req->async.private = async; \ } \ c_req->async.fn = async_fn; \ - req->control_flags |= REQ_CONTROL_ASYNC; \ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ return NT_STATUS_OK; \ } while (0) @@ -219,7 +219,7 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, /* see if the front end will allow us to perform this function asynchronously. */ - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_unlink(private->tree, unl); } @@ -235,8 +235,8 @@ static void async_ioctl(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_ioctl_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -252,7 +252,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, /* see if the front end will allow us to perform this function asynchronously. */ - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_ioctl(private->tree, req, io); } @@ -272,7 +272,7 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_chkpath(private->tree, cp); } @@ -288,8 +288,8 @@ static void async_qpathinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_pathinfo_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -303,7 +303,7 @@ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_pathinfo(private->tree, req, info); } @@ -319,8 +319,8 @@ static void async_qfileinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_fileinfo_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -334,7 +334,7 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_fileinfo(private->tree, req, info); } @@ -355,7 +355,7 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setpathinfo(private->tree, st); } @@ -372,8 +372,8 @@ static void async_open(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_open_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_open_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -392,7 +392,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(req, io, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_open(private->tree, req, io); } @@ -412,7 +412,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_mkdir(private->tree, md); } @@ -432,7 +432,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_rmdir(private->tree, rd); } c_req = smb_raw_rmdir_send(private->tree, rd); @@ -451,7 +451,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_rename(private->tree, ren); } @@ -476,8 +476,8 @@ static void async_read(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_read_recv(c_req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_read_recv(c_req, async->parms); + req->async_states->send_fn(req); } /* @@ -496,7 +496,7 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(req, rd, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_read(private->tree, rd); } @@ -512,8 +512,8 @@ static void async_write(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_write_recv(c_req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_write_recv(c_req, async->parms); + req->async_states->send_fn(req); } /* @@ -532,7 +532,7 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(req, wr, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_write(private->tree, wr); } @@ -552,7 +552,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_seek(private->tree, io); } @@ -572,7 +572,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_flush(private->tree, io); } @@ -597,7 +597,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(req, io, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_close(private->tree, io); } @@ -617,7 +617,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_exit(private->tree->session); } @@ -662,7 +662,7 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, return ntvfs_map_lock(req, lck, ntvfs); } - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_lock(private->tree, lck); } @@ -682,7 +682,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setfileinfo(private->tree, info); } c_req = smb_raw_setfileinfo_send(private->tree, info); @@ -698,8 +698,8 @@ static void async_fsinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_fsinfo_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* @@ -713,7 +713,7 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_fsinfo(private->tree, req, fs); } @@ -777,8 +777,8 @@ static void async_trans2(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct smbsrv_request *req = async->req; - req->async.status = smb_raw_trans2_recv(c_req, req, async->parms); - req->async.send_fn(req); + req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); + req->async_states->send_fn(req); } /* raw trans2 */ @@ -790,7 +790,7 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, SETUP_PID; - if (!(req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_trans2(private->tree, req, trans2); } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 482f0208a2..ab2d7af7b1 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -47,7 +47,7 @@ static void nbench_log(struct nbench_private *private, vasprintf(&s, format, ap); va_end(ap); - write(private->log_fd, s, strlen(s)); + //write(private->log_fd, s, strlen(s)); free(s); } @@ -58,11 +58,39 @@ static void nbench_log(struct nbench_private *private, async calls are a pain for the nbench module as it makes pulling the status code and any result parameters much harder. */ -#define PASS_THRU_REQ(ntvfs, req, op, args) do { \ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; \ +#define PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1) do { \ + status = ntvfs_async_state_push(req, par1, nbench_##op##_send, ntvfs); \ + if (!NT_STATUS_IS_OK(status)) { \ + return status; \ + } \ +} while (0) + +#define PASS_THRU_REQ_POST_ASYNC(req) do { \ + req->async_states->status = status; \ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \ +DEBUG(0,("NBENCH S 0x%04X: %s: %s 0x%X\n", req->mid, __FUNCTION__, nt_errstr(status),req->async_states->state)); \ + req->async_states->send_fn(req); \ + } else { \ +DEBUG(0,("NBENCH A 0x%04X: %s: %s\n", req->mid, __FUNCTION__, nt_errstr(status))); \ + } \ +} while (0) + +#define PASS_THRU_REQ(ntvfs, req, op, par1, args) do { \ + PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1); \ status = ntvfs_next_##op args; \ + PASS_THRU_REQ_POST_ASYNC(req); \ } while (0) +#define PASS_THRU_REP_POST(req) do { \ + ntvfs_async_state_pop(req); \ + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \ +DEBUG(0,("NBENCH A0x%04X: %s: %s\n", req->mid, __FUNCTION__, nt_errstr(req->async_states->status))); \ + req->async_states->send_fn(req); \ + } \ +} while (0) + +#define PASS_THRU_REP_PRE(req) \ + struct nbench_private *nprivates = req->async_states->ntvfs->private_data /* connect to a share - used when a tree_connect operation comes in. @@ -70,25 +98,25 @@ static void nbench_log(struct nbench_private *private, static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) { - struct nbench_private *private; + struct nbench_private *nprivates; NTSTATUS status; char *logname = NULL; - private = talloc_p(req->tcon, struct nbench_private); - if (!private) { + nprivates = talloc_p(req->tcon, struct nbench_private); + if (!nprivates) { return NT_STATUS_NO_MEMORY; } - +#if 0 asprintf(&logname, "/tmp/nbenchlog%d.%u", ntvfs->depth, getpid()); - private->log_fd = sys_open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); + nprivates->log_fd = sys_open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); free(logname); - if (private->log_fd == -1) { + if (nprivates->log_fd == -1) { DEBUG(0,("Failed to open nbench log\n")); return NT_STATUS_UNSUCCESSFUL; } - - ntvfs->private_data = private; +#endif + ntvfs->private_data = nprivates; status = ntvfs_next_connect(ntvfs, req, sharename); @@ -101,13 +129,13 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, struct smbsrv_tcon *tcon) { - struct nbench_private *private = ntvfs->private_data; + struct nbench_private *nprivates = ntvfs->private_data; NTSTATUS status; - close(private->log_fd); + close(nprivates->log_fd); status = ntvfs_next_disconnect(ntvfs, tcon); - + return status; } @@ -115,17 +143,24 @@ static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ +static void nbench_unlink_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_unlink *unl = req->async_states->private_data; + + nbench_log(nprivates, "Unlink \"%s\" 0x%x %s\n", + unl->in.pattern, unl->in.attrib, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_unlink *unl) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, unlink, (ntvfs, req, unl)); - - nbench_log(private, "Unlink \"%s\" 0x%x %s\n", - unl->in.pattern, unl->in.attrib, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, unlink, unl, (ntvfs, req, unl)); return status; } @@ -133,15 +168,21 @@ static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, /* ioctl interface */ +static void nbench_ioctl_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Ioctl - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_ioctl *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, ioctl, (ntvfs, req, io)); - - nbench_log(private, "Ioctl - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, ioctl, io, (ntvfs, req, io)); return status; } @@ -149,17 +190,24 @@ static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, /* check if a directory exists */ +static void nbench_chkpath_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_chkpath *cp = req->async_states->private_data; + + nbench_log(nprivates, "Chkpath \"%s\" %s\n", + cp->in.path, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_chkpath *cp) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, chkpath, (ntvfs, req, cp)); - - nbench_log(private, "Chkpath \"%s\" %s\n", - cp->in.path, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, chkpath, cp, (ntvfs, req, cp)); return status; } @@ -167,18 +215,25 @@ static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, /* return info on a pathname */ +static void nbench_qpathinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_fileinfo *info = req->async_states->private_data; + + nbench_log(nprivates, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", + info->generic.in.fname, + info->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_fileinfo *info) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, qpathinfo, (ntvfs, req, info)); - - nbench_log(private, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", - info->generic.in.fname, - info->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, qpathinfo, info, (ntvfs, req, info)); return status; } @@ -186,38 +241,51 @@ static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, /* query info on a open file */ +static void nbench_qfileinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_fileinfo *info = req->async_states->private_data; + + nbench_log(nprivates, "QUERY_FILE_INFORMATION %d %d %s\n", + info->generic.in.fnum, + info->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_fileinfo *info) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, qfileinfo, (ntvfs, req, info)); - - nbench_log(private, "QUERY_FILE_INFORMATION %d %d %s\n", - info->generic.in.fnum, - info->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, qfileinfo, info, (ntvfs, req, info)); return status; } - /* set info on a pathname */ +static void nbench_setpathinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_setfileinfo *st = req->async_states->private_data; + + nbench_log(nprivates, "SET_PATH_INFORMATION \"%s\" %d %s\n", + st->generic.file.fname, + st->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_setfileinfo *st) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, setpathinfo, (ntvfs, req, st)); - - nbench_log(private, "SET_PATH_INFORMATION \"%s\" %d %s\n", - st->generic.file.fname, - st->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, setpathinfo, st, (ntvfs, req, st)); return status; } @@ -225,47 +293,58 @@ static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, /* open a file */ -static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) +static void nbench_open_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, open, (ntvfs, req, io)); - - DEBUG(0,("%d: %s\n", ntvfs->depth, get_nt_error_c_code(status))); + PASS_THRU_REP_PRE(req); + union smb_open *io = req->async_states->private_data; switch (io->generic.level) { case RAW_OPEN_NTCREATEX: - nbench_log(private, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", + nbench_log(nprivates, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", io->ntcreatex.in.fname, io->ntcreatex.in.create_options, io->ntcreatex.in.open_disposition, io->ntcreatex.out.fnum, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Open-%d - NOT HANDLED\n", + nbench_log(nprivates, "Open-%d - NOT HANDLED\n", io->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io)); + return status; } /* create a directory */ +static void nbench_mkdir_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Mkdir - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_mkdir *md) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, mkdir, (ntvfs, req, md)); - - nbench_log(private, "Mkdir - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, mkdir, md, (ntvfs, req, md)); return status; } @@ -273,17 +352,24 @@ static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, /* remove a directory */ +static void nbench_rmdir_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_rmdir *rd = req->async_states->private_data; + + nbench_log(nprivates, "Rmdir \"%s\" %s\n", + rd->in.path, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_rmdir *rd) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, rmdir, (ntvfs, req, rd)); - - nbench_log(private, "Rmdir \"%s\" %s\n", - rd->in.path, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, rmdir, rd, (ntvfs, req, rd)); return status; } @@ -291,43 +377,56 @@ static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, /* rename a set of files */ -static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) +static void nbench_rename_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, rename, (ntvfs, req, ren)); + PASS_THRU_REP_PRE(req); + union smb_rename *ren = req->async_states->private_data; switch (ren->generic.level) { case RAW_RENAME_RENAME: - nbench_log(private, "Rename \"%s\" \"%s\" %s\n", + nbench_log(nprivates, "Rename \"%s\" \"%s\" %s\n", ren->rename.in.pattern1, ren->rename.in.pattern2, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Rename-%d - NOT HANDLED\n", + nbench_log(nprivates, "Rename-%d - NOT HANDLED\n", ren->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, rename, ren, (ntvfs, req, ren)); + return status; } /* copy a set of files */ +static void nbench_copy_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Copy - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_copy *cp) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, copy, (ntvfs, req, cp)); - - nbench_log(private, "Copy - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, copy, cp, (ntvfs, req, cp)); return status; } @@ -335,83 +434,103 @@ static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, /* read from a file */ -static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) +static void nbench_read_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, read, (ntvfs, req, rd)); + PASS_THRU_REP_PRE(req); + union smb_read *rd = req->async_states->private_data; switch (rd->generic.level) { case RAW_READ_READX: - nbench_log(private, "ReadX %d %d %d %d %s\n", + nbench_log(nprivates, "ReadX %d %d %d %d %s\n", rd->readx.in.fnum, (int)rd->readx.in.offset, rd->readx.in.maxcnt, rd->readx.out.nread, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Read-%d - NOT HANDLED\n", + nbench_log(nprivates, "Read-%d - NOT HANDLED\n", rd->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *rd) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, read, rd, (ntvfs, req, rd)); + return status; } /* write to a file */ -static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) +static void nbench_write_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, write, (ntvfs, req, wr)); + PASS_THRU_REP_PRE(req); + union smb_write *wr = req->async_states->private_data; switch (wr->generic.level) { case RAW_WRITE_WRITEX: - nbench_log(private, "WriteX %d %d %d %d %s\n", + nbench_log(nprivates, "WriteX %d %d %d %d %s\n", wr->writex.in.fnum, (int)wr->writex.in.offset, wr->writex.in.count, wr->writex.out.nwritten, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; case RAW_WRITE_WRITE: - nbench_log(private, "Write %d %d %d %d %s\n", + nbench_log(nprivates, "Write %d %d %d %d %s\n", wr->write.in.fnum, wr->write.in.offset, wr->write.in.count, wr->write.out.nwritten, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Write-%d - NOT HANDLED\n", + nbench_log(nprivates, "Write-%d - NOT HANDLED\n", wr->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *wr) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, write, wr, (ntvfs, req, wr)); + return status; } /* seek in a file */ +static void nbench_seek_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Seek - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_seek *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, seek, (ntvfs, req, io)); - - nbench_log(private, "Seek - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, seek, io, (ntvfs, req, io)); return status; } @@ -419,17 +538,24 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, /* flush a file */ +static void nbench_flush_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + struct smb_flush *io = req->async_states->private_data; + + nbench_log(nprivates, "Flush %d %s\n", + io->in.fnum, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_flush *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, flush, (ntvfs, req, io)); - - nbench_log(private, "Flush %d %s\n", - io->in.fnum, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, flush, io, (ntvfs, req, io)); return status; } @@ -437,39 +563,55 @@ static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, /* close a file */ -static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) +static void nbench_close_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, close, (ntvfs, req, io)); + PASS_THRU_REP_PRE(req); + union smb_close *io = req->async_states->private_data; switch (io->generic.level) { case RAW_CLOSE_CLOSE: - nbench_log(private, "Close %d %s\n", + nbench_log(nprivates, "Close %d %s\n", io->close.in.fnum, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Close-%d - NOT HANDLED\n", + nbench_log(nprivates, "Close-%d - NOT HANDLED\n", io->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, close, io, (ntvfs, req, io)); + return status; } /* exit - closing files */ +static void nbench_exit_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Exit - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, exit, (ntvfs, req)); + PASS_THRU_REQ(ntvfs, req, exit, NULL, (ntvfs, req)); return status; } @@ -477,12 +619,21 @@ static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, /* logoff - closing files */ +static void nbench_logoff_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Logoff - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, logoff, (ntvfs, req)); + PASS_THRU_REQ(ntvfs, req, logoff, NULL, (ntvfs, req)); return status; } @@ -500,71 +651,91 @@ static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, /* lock a byte range */ -static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) +static void nbench_lock_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, lock, (ntvfs, req, lck)); + PASS_THRU_REP_PRE(req); + union smb_lock *lck = req->async_states->private_data; if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.lock_cnt == 1 && lck->lockx.in.ulock_cnt == 0) { - nbench_log(private, "LockX %d %d %d %s\n", + nbench_log(nprivates, "LockX %d %d %d %s\n", lck->lockx.in.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); } else if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.ulock_cnt == 1) { - nbench_log(private, "UnlockX %d %d %d %s\n", + nbench_log(nprivates, "UnlockX %d %d %d %s\n", lck->lockx.in.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); } else { - nbench_log(private, "Lock-%d - NOT HANDLED\n", lck->generic.level); + nbench_log(nprivates, "Lock-%d - NOT HANDLED\n", lck->generic.level); } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, lock, lck, (ntvfs, req, lck)); + return status; } /* set info on a open file */ +static void nbench_setfileinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_setfileinfo *info = req->async_states->private_data; + + nbench_log(nprivates, "SET_FILE_INFORMATION %d %d %s\n", + info->generic.file.fnum, + info->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_setfileinfo *info) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, setfileinfo, (ntvfs, req, info)); - - nbench_log(private, "SET_FILE_INFORMATION %d %d %s\n", - info->generic.file.fnum, - info->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, setfileinfo, info, (ntvfs, req, info)); return status; } - /* return filesystem space info */ +static void nbench_fsinfo_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_fsinfo *fs = req->async_states->private_data; + + nbench_log(nprivates, "QUERY_FS_INFORMATION %d %s\n", + fs->generic.level, + get_nt_error_c_code(req->async_states->status)); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_fsinfo *fs) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, fsinfo, (ntvfs, req, fs)); - - nbench_log(private, "QUERY_FS_INFORMATION %d %s\n", - fs->generic.level, - get_nt_error_c_code(status)); + PASS_THRU_REQ(ntvfs, req, fsinfo, fs, (ntvfs, req, fs)); return status; } @@ -572,15 +743,22 @@ static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, /* return print queue info */ +static void nbench_lpq_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_lpq *lpq = req->async_states->private_data; + + nbench_log(nprivates, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_lpq *lpq) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, lpq, (ntvfs, req, lpq)); - - nbench_log(private, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); + PASS_THRU_REQ(ntvfs, req, lpq, lpq, (ntvfs, req, lpq)); return status; } @@ -588,74 +766,101 @@ static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, /* list files in a directory matching a wildcard pattern */ -static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) +static void nbench_search_first_send(struct smbsrv_request *req) { - struct nbench_private *private = ntvfs->private_data; - NTSTATUS status; - - PASS_THRU_REQ(ntvfs, req, search_first, (ntvfs, req, io, search_private, callback)); - + PASS_THRU_REP_PRE(req); + union smb_search_first *io = req->async_states->private_data; + switch (io->generic.level) { case RAW_SEARCH_BOTH_DIRECTORY_INFO: - nbench_log(private, "FIND_FIRST \"%s\" %d %d %d %s\n", + nbench_log(nprivates, "FIND_FIRST \"%s\" %d %d %d %s\n", io->t2ffirst.in.pattern, io->generic.level, io->t2ffirst.in.max_count, io->t2ffirst.out.count, - get_nt_error_c_code(status)); + get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(private, "Search-%d - NOT HANDLED\n", io->generic.level); + nbench_log(nprivates, "Search-%d - NOT HANDLED\n", io->generic.level); break; } + PASS_THRU_REP_POST(req); +} + +static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, search_first, io, (ntvfs, req, io, search_private, callback)); + return status; } /* continue a search */ +static void nbench_search_next_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_search_next *io = req->async_states->private_data; + + nbench_log(nprivates, "Searchnext-%d - NOT HANDLED\n", io->generic.level); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, search_next, (ntvfs, req, io, search_private, callback)); - - nbench_log(private, "Searchnext-%d - NOT HANDLED\n", io->generic.level); + PASS_THRU_REQ(ntvfs, req, search_next, io, (ntvfs, req, io, search_private, callback)); return status; } /* close a search */ +static void nbench_search_close_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + union smb_search_close *io = req->async_states->private_data; + + nbench_log(nprivates, "Searchclose-%d - NOT HANDLED\n", io->generic.level); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_search_close *io) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, search_close, (ntvfs, req, io)); - - nbench_log(private, "Searchclose-%d - NOT HANDLED\n", io->generic.level); + PASS_THRU_REQ(ntvfs, req, search_close, io, (ntvfs, req, io)); return status; } /* SMBtrans - not used on file shares */ +static void nbench_trans_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_PRE(req); + + nbench_log(nprivates, "Trans - NOT HANDLED\n"); + + PASS_THRU_REP_POST(req); +} + static NTSTATUS nbench_trans(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans2) { - struct nbench_private *private = ntvfs->private_data; NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, trans, (ntvfs, req, trans2)); - - nbench_log(private, "Trans - NOT HANDLED\n"); + PASS_THRU_REQ(ntvfs, req, trans, trans2, (ntvfs, req, trans2)); return status; } diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index c9fe276f54..04e9b871c7 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -134,12 +134,45 @@ struct ntvfs_context { struct ntvfs_module_context *modules; }; + +/* a set of flags to control handling of request structures */ +#define NTVFS_ASYNC_STATE_ASYNC (1<<1) /* the backend will answer this one later */ +#define NTVFS_ASYNC_STATE_MAY_ASYNC (1<<2) /* the backend is allowed to answer async */ + +/* the ntvfs_async_state structure allows backend functions to + delay replying to requests. To use this, the front end must + set send_fn to a function to be called by the backend + when the reply is finally ready to be sent. The backend + must set status to the status it wants in the + reply. The backend must set the NTVFS_ASYNC_STATE_ASYNC + control_flag on the request to indicate that it wishes to + delay the reply + + If NTVFS_ASYNC_STATE_MAY_ASYNC is not set then the backend cannot + ask for a delayed reply for this request + + note that the private_data pointer is private to the layer which alloced this struct +*/ +struct ntvfs_async_state { + struct ntvfs_async_state *prev, *next; + /* the async handling infos */ + unsigned state; + void *private_data; + void (*send_fn)(struct smbsrv_request *); + NTSTATUS status; + + /* the passthru module's per session private data */ + struct ntvfs_module_context *ntvfs; +}; + /* this structure is used by backends to determine the size of some critical types */ struct ntvfs_critical_sizes { int interface_version; + int sizeof_ntvfs_critical_sizes; int sizeof_ntvfs_context; int sizeof_ntvfs_module_context; int sizeof_ntvfs_ops; + int sizeof_ntvfs_async_state; int sizeof_smbsrv_tcon; int sizeof_smbsrv_request; }; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index acbd02d915..17900b3dfc 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -100,9 +100,11 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { static const struct ntvfs_critical_sizes critical_sizes = { NTVFS_INTERFACE_VERSION, + sizeof(struct ntvfs_critical_sizes), sizeof(struct ntvfs_context), sizeof(struct ntvfs_module_context), sizeof(struct ntvfs_ops), + sizeof(struct ntvfs_async_state), sizeof(struct smbsrv_tcon), sizeof(struct smbsrv_request), }; diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 452273cbdb..2639b5ae39 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -71,7 +71,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, /* must be synchronous, or we won't be called to do the translation */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; switch (io->generic.level) { case RAW_OPEN_GENERIC: @@ -692,7 +692,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf /* must be synchronous, or we won't be called to do the translation */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; status = ntvfs->ops->qpathinfo(ntvfs, req, info2); if (!NT_STATUS_IS_OK(status)) { @@ -768,7 +768,7 @@ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, wr2->generic.level = RAW_WRITE_GENERIC; /* we can't map asynchronously */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; switch (wr->generic.level) { case RAW_WRITE_WRITEX: @@ -874,7 +874,7 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, rd2->generic.level = RAW_READ_GENERIC; /* we can't map asynchronously */ - req->control_flags &= ~REQ_CONTROL_MAY_ASYNC; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; switch (rd->generic.level) { case RAW_READ_READX: diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 4036fb0935..929ec037de 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. NTVFS utility code - Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan Metzmacher 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,4 +23,40 @@ #include "includes.h" +NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, + void *private_data, + void (*send_fn)(struct smbsrv_request *), + struct ntvfs_module_context *ntvfs) +{ + struct ntvfs_async_state *async; + async = talloc_p(req, struct ntvfs_async_state); + if (!async) { + return NT_STATUS_NO_MEMORY; + } + + async->state = req->async_states->state; + async->private_data = private_data; + async->send_fn = send_fn; + async->status = NT_STATUS_INTERNAL_ERROR; + + async->ntvfs = ntvfs; + + DLIST_ADD(req->async_states, async); + + return NT_STATUS_OK; +} + +void ntvfs_async_state_pop(struct smbsrv_request *req) +{ + struct ntvfs_async_state *async; + + async = req->async_states; + + DLIST_REMOVE(req->async_states, async); + + req->async_states->state = async->state; + req->async_states->status = async->status; + + talloc_free(async); +} diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 4a4da34b60..3835c9319b 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -77,8 +77,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, locks[i].count); f->lock_count--; } - req->async.status = status; - req->async.send_fn(req); + req->async_states->status = status; + req->async_states->send_fn(req); } @@ -192,8 +192,8 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) } /* we've managed to get all the locks. Tell the client */ - req->async.status = NT_STATUS_OK; - req->async.send_fn(req); + req->async_states->status = NT_STATUS_OK; + req->async_states->send_fn(req); } @@ -217,8 +217,8 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) next = p->next; DLIST_REMOVE(f->pending_list, p); talloc_free(p->wait_handle); - p->req->async.status = NT_STATUS_RANGE_NOT_LOCKED; - p->req->async.send_fn(p->req); + p->req->async_states->status = NT_STATUS_RANGE_NOT_LOCKED; + p->req->async_states->send_fn(p->req); } } @@ -287,7 +287,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } if (lck->lockx.in.timeout != 0 && - (req->control_flags & REQ_CONTROL_MAY_ASYNC)) { + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { pending = talloc_p(req, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 071ecbce15..2a8cbbbe0d 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -149,7 +149,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, /* tell the main smb server layer that we will be replying asynchronously */ - req->control_flags |= REQ_CONTROL_ASYNC; + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; /* make sure we cleanup the timer and message handler */ talloc_set_destructor(pwait, pvfs_wait_destructor); -- cgit From 195f48dcbf432833f8957b0387ac81fb7c46ca27 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Oct 2004 22:18:52 +0000 Subject: r3337: remove debug code and reanable the reall logging:-) metze (This used to be commit 00b285e5a815e6d53ede7d102dee4e5b79d47f52) --- source4/ntvfs/nbench/vfs_nbench.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index ab2d7af7b1..db89d7ccf4 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -47,7 +47,7 @@ static void nbench_log(struct nbench_private *private, vasprintf(&s, format, ap); va_end(ap); - //write(private->log_fd, s, strlen(s)); + write(private->log_fd, s, strlen(s)); free(s); } @@ -68,10 +68,7 @@ static void nbench_log(struct nbench_private *private, #define PASS_THRU_REQ_POST_ASYNC(req) do { \ req->async_states->status = status; \ if (!(req->async_states->state & NTVFS_ASYNC_STATE_ASYNC)) { \ -DEBUG(0,("NBENCH S 0x%04X: %s: %s 0x%X\n", req->mid, __FUNCTION__, nt_errstr(status),req->async_states->state)); \ req->async_states->send_fn(req); \ - } else { \ -DEBUG(0,("NBENCH A 0x%04X: %s: %s\n", req->mid, __FUNCTION__, nt_errstr(status))); \ } \ } while (0) @@ -84,7 +81,6 @@ DEBUG(0,("NBENCH A 0x%04X: %s: %s\n", req->mid, __FUNCTION__, nt_errstr(status)) #define PASS_THRU_REP_POST(req) do { \ ntvfs_async_state_pop(req); \ if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { \ -DEBUG(0,("NBENCH A0x%04X: %s: %s\n", req->mid, __FUNCTION__, nt_errstr(req->async_states->status))); \ req->async_states->send_fn(req); \ } \ } while (0) @@ -106,7 +102,7 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, if (!nprivates) { return NT_STATUS_NO_MEMORY; } -#if 0 + asprintf(&logname, "/tmp/nbenchlog%d.%u", ntvfs->depth, getpid()); nprivates->log_fd = sys_open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); free(logname); @@ -115,7 +111,7 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, DEBUG(0,("Failed to open nbench log\n")); return NT_STATUS_UNSUCCESSFUL; } -#endif + ntvfs->private_data = nprivates; status = ntvfs_next_connect(ntvfs, req, sharename); -- cgit From 6876fae4ebba0caea1e5e3274b9856b056e54079 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 00:51:41 +0000 Subject: r3346: - simplified vfs_nbench.c a bit, by using req->async_state->ntvfs inside nbench_log() instead of declaring nprivates every time. - added correct async_setup pass-thru in nbench (This used to be commit 8d79bceeca4528ab31cff1adc7706faa075013ac) --- source4/ntvfs/nbench/vfs_nbench.c | 125 ++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 74 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index db89d7ccf4..f9a93aa1c7 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -34,12 +34,13 @@ struct nbench_private { /* log one request to the nbench log */ -static void nbench_log(struct nbench_private *private, +static void nbench_log(struct smbsrv_request *req, const char *format, ...) PRINTF_ATTRIBUTE(2, 3); -static void nbench_log(struct nbench_private *private, +static void nbench_log(struct smbsrv_request *req, const char *format, ...) { + struct nbench_private *private = req->async_states->ntvfs->private_data; va_list ap; char *s = NULL; @@ -85,9 +86,6 @@ static void nbench_log(struct nbench_private *private, } \ } while (0) -#define PASS_THRU_REP_PRE(req) \ - struct nbench_private *nprivates = req->async_states->ntvfs->private_data - /* connect to a share - used when a tree_connect operation comes in. */ @@ -141,10 +139,9 @@ static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, */ static void nbench_unlink_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); struct smb_unlink *unl = req->async_states->private_data; - nbench_log(nprivates, "Unlink \"%s\" 0x%x %s\n", + nbench_log(req, "Unlink \"%s\" 0x%x %s\n", unl->in.pattern, unl->in.attrib, get_nt_error_c_code(req->async_states->status)); @@ -166,9 +163,7 @@ static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, */ static void nbench_ioctl_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); - - nbench_log(nprivates, "Ioctl - NOT HANDLED\n"); + nbench_log(req, "Ioctl - NOT HANDLED\n"); PASS_THRU_REP_POST(req); } @@ -188,10 +183,9 @@ static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, */ static void nbench_chkpath_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); struct smb_chkpath *cp = req->async_states->private_data; - nbench_log(nprivates, "Chkpath \"%s\" %s\n", + nbench_log(req, "Chkpath \"%s\" %s\n", cp->in.path, get_nt_error_c_code(req->async_states->status)); @@ -213,10 +207,9 @@ static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, */ static void nbench_qpathinfo_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_fileinfo *info = req->async_states->private_data; - nbench_log(nprivates, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", + nbench_log(req, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", info->generic.in.fname, info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -239,10 +232,9 @@ static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, */ static void nbench_qfileinfo_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_fileinfo *info = req->async_states->private_data; - nbench_log(nprivates, "QUERY_FILE_INFORMATION %d %d %s\n", + nbench_log(req, "QUERY_FILE_INFORMATION %d %d %s\n", info->generic.in.fnum, info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -265,10 +257,9 @@ static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs, */ static void nbench_setpathinfo_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_setfileinfo *st = req->async_states->private_data; - nbench_log(nprivates, "SET_PATH_INFORMATION \"%s\" %d %s\n", + nbench_log(req, "SET_PATH_INFORMATION \"%s\" %d %s\n", st->generic.file.fname, st->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -291,12 +282,11 @@ static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, */ static void nbench_open_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_open *io = req->async_states->private_data; switch (io->generic.level) { case RAW_OPEN_NTCREATEX: - nbench_log(nprivates, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", + nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", io->ntcreatex.in.fname, io->ntcreatex.in.create_options, io->ntcreatex.in.open_disposition, @@ -305,7 +295,7 @@ static void nbench_open_send(struct smbsrv_request *req) break; default: - nbench_log(nprivates, "Open-%d - NOT HANDLED\n", + nbench_log(req, "Open-%d - NOT HANDLED\n", io->generic.level); break; } @@ -328,9 +318,7 @@ static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, */ static void nbench_mkdir_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); - - nbench_log(nprivates, "Mkdir - NOT HANDLED\n"); + nbench_log(req, "Mkdir - NOT HANDLED\n"); PASS_THRU_REP_POST(req); } @@ -350,10 +338,9 @@ static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, */ static void nbench_rmdir_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); struct smb_rmdir *rd = req->async_states->private_data; - nbench_log(nprivates, "Rmdir \"%s\" %s\n", + nbench_log(req, "Rmdir \"%s\" %s\n", rd->in.path, get_nt_error_c_code(req->async_states->status)); @@ -375,19 +362,18 @@ static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, */ static void nbench_rename_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_rename *ren = req->async_states->private_data; switch (ren->generic.level) { case RAW_RENAME_RENAME: - nbench_log(nprivates, "Rename \"%s\" \"%s\" %s\n", + nbench_log(req, "Rename \"%s\" \"%s\" %s\n", ren->rename.in.pattern1, ren->rename.in.pattern2, get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(nprivates, "Rename-%d - NOT HANDLED\n", + nbench_log(req, "Rename-%d - NOT HANDLED\n", ren->generic.level); break; } @@ -410,9 +396,7 @@ static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, */ static void nbench_copy_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); - - nbench_log(nprivates, "Copy - NOT HANDLED\n"); + nbench_log(req, "Copy - NOT HANDLED\n"); PASS_THRU_REP_POST(req); } @@ -432,12 +416,11 @@ static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, */ static void nbench_read_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_read *rd = req->async_states->private_data; switch (rd->generic.level) { case RAW_READ_READX: - nbench_log(nprivates, "ReadX %d %d %d %d %s\n", + nbench_log(req, "ReadX %d %d %d %d %s\n", rd->readx.in.fnum, (int)rd->readx.in.offset, rd->readx.in.maxcnt, @@ -445,7 +428,7 @@ static void nbench_read_send(struct smbsrv_request *req) get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(nprivates, "Read-%d - NOT HANDLED\n", + nbench_log(req, "Read-%d - NOT HANDLED\n", rd->generic.level); break; } @@ -468,12 +451,11 @@ static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, */ static void nbench_write_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_write *wr = req->async_states->private_data; switch (wr->generic.level) { case RAW_WRITE_WRITEX: - nbench_log(nprivates, "WriteX %d %d %d %d %s\n", + nbench_log(req, "WriteX %d %d %d %d %s\n", wr->writex.in.fnum, (int)wr->writex.in.offset, wr->writex.in.count, @@ -482,7 +464,7 @@ static void nbench_write_send(struct smbsrv_request *req) break; case RAW_WRITE_WRITE: - nbench_log(nprivates, "Write %d %d %d %d %s\n", + nbench_log(req, "Write %d %d %d %d %s\n", wr->write.in.fnum, wr->write.in.offset, wr->write.in.count, @@ -491,7 +473,7 @@ static void nbench_write_send(struct smbsrv_request *req) break; default: - nbench_log(nprivates, "Write-%d - NOT HANDLED\n", + nbench_log(req, "Write-%d - NOT HANDLED\n", wr->generic.level); break; } @@ -514,9 +496,7 @@ static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, */ static void nbench_seek_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); - - nbench_log(nprivates, "Seek - NOT HANDLED\n"); + nbench_log(req, "Seek - NOT HANDLED\n"); PASS_THRU_REP_POST(req); } @@ -536,10 +516,9 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, */ static void nbench_flush_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); struct smb_flush *io = req->async_states->private_data; - nbench_log(nprivates, "Flush %d %s\n", + nbench_log(req, "Flush %d %s\n", io->in.fnum, get_nt_error_c_code(req->async_states->status)); @@ -561,18 +540,17 @@ static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, */ static void nbench_close_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_close *io = req->async_states->private_data; switch (io->generic.level) { case RAW_CLOSE_CLOSE: - nbench_log(nprivates, "Close %d %s\n", + nbench_log(req, "Close %d %s\n", io->close.in.fnum, get_nt_error_c_code(req->async_states->status)); break; default: - nbench_log(nprivates, "Close-%d - NOT HANDLED\n", + nbench_log(req, "Close-%d - NOT HANDLED\n", io->generic.level); break; } @@ -595,9 +573,7 @@ static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, */ static void nbench_exit_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); - - nbench_log(nprivates, "Exit - NOT HANDLED\n"); + nbench_log(req, "Exit - NOT HANDLED\n"); PASS_THRU_REP_POST(req); } @@ -617,9 +593,7 @@ static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, */ static void nbench_logoff_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); - - nbench_log(nprivates, "Logoff - NOT HANDLED\n"); + nbench_log(req, "Logoff - NOT HANDLED\n"); PASS_THRU_REP_POST(req); } @@ -634,6 +608,14 @@ static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, return status; } +/* + async_setup - send fn +*/ +static void nbench_async_setup_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_POST(req); +} + /* async setup */ @@ -641,7 +623,11 @@ static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, void *private) { - return NT_STATUS_OK; + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, async_setup, NULL, (ntvfs, req, private)); + + return status; } /* @@ -649,26 +635,25 @@ static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, */ static void nbench_lock_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_lock *lck = req->async_states->private_data; if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.lock_cnt == 1 && lck->lockx.in.ulock_cnt == 0) { - nbench_log(nprivates, "LockX %d %d %d %s\n", + nbench_log(req, "LockX %d %d %d %s\n", lck->lockx.in.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); } else if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.ulock_cnt == 1) { - nbench_log(nprivates, "UnlockX %d %d %d %s\n", + nbench_log(req, "UnlockX %d %d %d %s\n", lck->lockx.in.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); } else { - nbench_log(nprivates, "Lock-%d - NOT HANDLED\n", lck->generic.level); + nbench_log(req, "Lock-%d - NOT HANDLED\n", lck->generic.level); } PASS_THRU_REP_POST(req); @@ -689,10 +674,9 @@ static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, */ static void nbench_setfileinfo_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_setfileinfo *info = req->async_states->private_data; - nbench_log(nprivates, "SET_FILE_INFORMATION %d %d %s\n", + nbench_log(req, "SET_FILE_INFORMATION %d %d %s\n", info->generic.file.fnum, info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -716,10 +700,9 @@ static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs, */ static void nbench_fsinfo_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_fsinfo *fs = req->async_states->private_data; - nbench_log(nprivates, "QUERY_FS_INFORMATION %d %s\n", + nbench_log(req, "QUERY_FS_INFORMATION %d %s\n", fs->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -741,10 +724,9 @@ static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, */ static void nbench_lpq_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_lpq *lpq = req->async_states->private_data; - nbench_log(nprivates, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); + nbench_log(req, "Lpq-%d - NOT HANDLED\n", lpq->generic.level); PASS_THRU_REP_POST(req); } @@ -764,12 +746,11 @@ static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, */ static void nbench_search_first_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_search_first *io = req->async_states->private_data; switch (io->generic.level) { case RAW_SEARCH_BOTH_DIRECTORY_INFO: - nbench_log(nprivates, "FIND_FIRST \"%s\" %d %d %d %s\n", + nbench_log(req, "FIND_FIRST \"%s\" %d %d %d %s\n", io->t2ffirst.in.pattern, io->generic.level, io->t2ffirst.in.max_count, @@ -778,7 +759,7 @@ static void nbench_search_first_send(struct smbsrv_request *req) break; default: - nbench_log(nprivates, "Search-%d - NOT HANDLED\n", io->generic.level); + nbench_log(req, "Search-%d - NOT HANDLED\n", io->generic.level); break; } @@ -800,10 +781,9 @@ static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, /* continue a search */ static void nbench_search_next_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_search_next *io = req->async_states->private_data; - nbench_log(nprivates, "Searchnext-%d - NOT HANDLED\n", io->generic.level); + nbench_log(req, "Searchnext-%d - NOT HANDLED\n", io->generic.level); PASS_THRU_REP_POST(req); } @@ -823,10 +803,9 @@ static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, /* close a search */ static void nbench_search_close_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); union smb_search_close *io = req->async_states->private_data; - nbench_log(nprivates, "Searchclose-%d - NOT HANDLED\n", io->generic.level); + nbench_log(req, "Searchclose-%d - NOT HANDLED\n", io->generic.level); PASS_THRU_REP_POST(req); } @@ -844,9 +823,7 @@ static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs, /* SMBtrans - not used on file shares */ static void nbench_trans_send(struct smbsrv_request *req) { - PASS_THRU_REP_PRE(req); - - nbench_log(nprivates, "Trans - NOT HANDLED\n"); + nbench_log(req, "Trans - NOT HANDLED\n"); PASS_THRU_REP_POST(req); } -- cgit From 10ae6167651bc4fe3169c6c4086eef4920b0d739 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 01:07:07 +0000 Subject: r3347: fixed an uninitialised variable bug. Surprisingly hard to track down, as valgrind got a corrupt stack when trying to debug it. (This used to be commit 58cabaa7022e5521961551462d31fbd90e4183e4) --- source4/ntvfs/nbench/vfs_nbench.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index f9a93aa1c7..e542c3fb71 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -417,14 +417,20 @@ static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, static void nbench_read_send(struct smbsrv_request *req) { union smb_read *rd = req->async_states->private_data; - + uint32_t nread; + switch (rd->generic.level) { case RAW_READ_READX: + if (NT_STATUS_IS_OK(req->async_states->status)) { + nread = rd->readx.out.nread; + } else { + nread = 0; + } nbench_log(req, "ReadX %d %d %d %d %s\n", rd->readx.in.fnum, (int)rd->readx.in.offset, rd->readx.in.maxcnt, - rd->readx.out.nread, + nread, get_nt_error_c_code(req->async_states->status)); break; default: -- cgit From ae3b7ef161fcf248f551a2f1ac9d1052f932b3a0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 01:22:47 +0000 Subject: r3349: fixed more uninitialised variable problems with the nbench module (This used to be commit 915faf49350b29a46f39354cbac746455d70c92c) --- source4/ntvfs/nbench/vfs_nbench.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index e542c3fb71..396d3a418e 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -286,6 +286,9 @@ static void nbench_open_send(struct smbsrv_request *req) switch (io->generic.level) { case RAW_OPEN_NTCREATEX: + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(io->ntcreatex.out); + } nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", io->ntcreatex.in.fname, io->ntcreatex.in.create_options, @@ -417,20 +420,17 @@ static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, static void nbench_read_send(struct smbsrv_request *req) { union smb_read *rd = req->async_states->private_data; - uint32_t nread; switch (rd->generic.level) { case RAW_READ_READX: - if (NT_STATUS_IS_OK(req->async_states->status)) { - nread = rd->readx.out.nread; - } else { - nread = 0; + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(rd->readx.out); } nbench_log(req, "ReadX %d %d %d %d %s\n", rd->readx.in.fnum, (int)rd->readx.in.offset, rd->readx.in.maxcnt, - nread, + rd->readx.out.nread, get_nt_error_c_code(req->async_states->status)); break; default: @@ -461,6 +461,9 @@ static void nbench_write_send(struct smbsrv_request *req) switch (wr->generic.level) { case RAW_WRITE_WRITEX: + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(wr->writex.out); + } nbench_log(req, "WriteX %d %d %d %d %s\n", wr->writex.in.fnum, (int)wr->writex.in.offset, @@ -470,6 +473,9 @@ static void nbench_write_send(struct smbsrv_request *req) break; case RAW_WRITE_WRITE: + if (!NT_STATUS_IS_OK(req->async_states->status)) { + ZERO_STRUCT(wr->write.out); + } nbench_log(req, "Write %d %d %d %d %s\n", wr->write.in.fnum, wr->write.in.offset, @@ -756,6 +762,9 @@ static void nbench_search_first_send(struct smbsrv_request *req) switch (io->generic.level) { case RAW_SEARCH_BOTH_DIRECTORY_INFO: + if (NT_STATUS_IS_ERR(req->async_states->status)) { + ZERO_STRUCT(io->t2ffirst.out); + } nbench_log(req, "FIND_FIRST \"%s\" %d %d %d %s\n", io->t2ffirst.in.pattern, io->generic.level, -- cgit From 78b85c96c946069cd16ad7399b0dd8cfb7e2590b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 04:43:28 +0000 Subject: r3351: handle far more operations on open directory handles. pvfs was failing with a wxp client because of qfileinfo operations on directories failing with NT_STATUS_INVALID_HANDLE after the fstat() failed (as pvfs sets f->fd to -1 for directories) (This used to be commit 1993128cb1dbf49db6e3e0387996ecf2a14b8d76) --- source4/ntvfs/posix/pvfs_flush.c | 3 +++ source4/ntvfs/posix/pvfs_resolve.c | 10 ++++++++-- source4/ntvfs/posix/pvfs_setfileinfo.c | 7 +++++++ 3 files changed, 18 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 49eaa74cfb..43893af80d 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -28,6 +28,9 @@ */ static void pvfs_flush_file(struct pvfs_state *pvfs, struct pvfs_file *f) { + if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + return; + } if (pvfs->flags & PVFS_FLAG_STRICT_SYNC) { fsync(f->fd); } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 75fbeb39a5..be1662437e 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -510,8 +510,14 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, inode = name->st.st_ino; } - if (fstat(fd, &name->st) == -1) { - return NT_STATUS_INVALID_HANDLE; + if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (stat(name->full_name, &name->st) == -1) { + return NT_STATUS_INVALID_HANDLE; + } + } else { + if (fstat(fd, &name->st) == -1) { + return NT_STATUS_INVALID_HANDLE; + } } if (name->exists && diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index bba3ee3747..bc96f25fec 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -128,6 +128,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file size */ if (newstats.st.st_size != f->name->st.st_size) { + if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } if (ftruncate(f->fd, newstats.st.st_size) == -1) { return pvfs_map_errno(pvfs, errno); } @@ -150,6 +153,10 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the attribute */ if (newstats.dos.attrib != f->name->dos.attrib) { mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib); + if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + /* ignore on directories for now */ + return NT_STATUS_OK; + } if (fchmod(f->fd, mode) == -1) { return pvfs_map_errno(pvfs, errno); } -- cgit From d1a732dd2d0828cb3f1f67e86acffcb053ca6851 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 05:58:22 +0000 Subject: r3353: don't reference dos.attrib unless its initialised (This used to be commit 498799e4260b1c5e2bfc4fac4cba1080e8ec0a04) --- source4/ntvfs/posix/pvfs_resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index be1662437e..672d028dd5 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -510,7 +510,7 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, inode = name->st.st_ino; } - if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { if (stat(name->full_name, &name->st) == -1) { return NT_STATUS_INVALID_HANDLE; } -- cgit From dbf03959244c392073281c10badd2095397ad2f2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 07:29:26 +0000 Subject: r3357: removed the need to use TDB_CLEAR_IF_FIRST in Samba4. We found a few months ago that TDB_CLEAR_IF_FIRST is extremely inefficient for large numbers of connections, due to a fundamental limitation in the way posix byte range locking is implemented. Rather than the nasty workaround we had for Samba3, we now have a single "cleanup tmp files" function that runs when smbd starts. That deletes the tmp tdbs, so TDB_CLEAR_IF_FIRST is not needed at all. (This used to be commit ffa285bc783c775a2d53a58fb691ca339e6c76ae) --- source4/ntvfs/common/brlock.c | 2 +- source4/ntvfs/common/opendb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index b43f0705a5..0f6af3e971 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -84,7 +84,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, path = lock_path(brl, "brlock.tdb"); brl->w = tdb_wrap_open(brl, path, 0, - TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + TDB_DEFAULT, O_RDWR|O_CREAT, 0600); talloc_free(path); if (brl->w == NULL) { diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index d8ca4c999d..a66549b764 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -88,7 +88,7 @@ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, path = lock_path(odb, "openfiles.tdb"); odb->w = tdb_wrap_open(odb, path, 0, - TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + TDB_DEFAULT, O_RDWR|O_CREAT, 0600); talloc_free(path); if (odb->w == NULL) { -- cgit From 09d0b152b7bd85aa01898af81bd166a7673ab886 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 08:38:59 +0000 Subject: r3360: improved the deletion of tmp files. smbd now puts all tmp files in var/locks/smbd.tmp/ and deletes that dir on startup. (This used to be commit 7e942e7f1bd2c293a0e6648df43a96f8b8a2a295) --- source4/ntvfs/common/brlock.c | 5 ++--- source4/ntvfs/common/opendb.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 0f6af3e971..a952cb1dc7 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -82,10 +82,9 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, return NULL; } - path = lock_path(brl, "brlock.tdb"); + path = smbd_tmp_path(brl, "brlock.tdb"); brl->w = tdb_wrap_open(brl, path, 0, - TDB_DEFAULT, - O_RDWR|O_CREAT, 0600); + TDB_DEFAULT, O_RDWR|O_CREAT, 0600); talloc_free(path); if (brl->w == NULL) { talloc_free(brl); diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index a66549b764..c2c8075771 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -86,7 +86,7 @@ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, return NULL; } - path = lock_path(odb, "openfiles.tdb"); + path = smbd_tmp_path(odb, "openfiles.tdb"); odb->w = tdb_wrap_open(odb, path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); -- cgit From 9752471973007289fb7659f0311cd316b401c034 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 09:28:35 +0000 Subject: r3363: added basic support for SA_RIGHT_FILE_EXECUTE, needed for opening .dll files (This used to be commit ba1bfd51e1b694cb69afe559f695addaf03b4d81) --- source4/ntvfs/common/opendb.c | 26 +++++++++++++++++++------- source4/ntvfs/posix/pvfs_open.c | 30 ++++++++++++------------------ source4/ntvfs/posix/pvfs_read.c | 2 +- 3 files changed, 32 insertions(+), 26 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index c2c8075771..dfb1177eae 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -154,10 +154,14 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) /* if either open involves no read.write or delete access then it can't conflict */ - if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA | STD_RIGHT_DELETE_ACCESS))) { + if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | + SA_RIGHT_FILE_READ_EXEC | + STD_RIGHT_DELETE_ACCESS))) { return False; } - if (!(e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_READ_DATA | STD_RIGHT_DELETE_ACCESS))) { + if (!(e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | + SA_RIGHT_FILE_READ_EXEC | + STD_RIGHT_DELETE_ACCESS))) { return False; } @@ -165,11 +169,19 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE); CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE); - CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_READ_DATA, NTCREATEX_SHARE_ACCESS_READ); - CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_READ_DATA, NTCREATEX_SHARE_ACCESS_READ); - - CHECK_MASK(e1->access_mask, e2->share_access, STD_RIGHT_DELETE_ACCESS, NTCREATEX_SHARE_ACCESS_DELETE); - CHECK_MASK(e2->access_mask, e1->share_access, STD_RIGHT_DELETE_ACCESS, NTCREATEX_SHARE_ACCESS_DELETE); + CHECK_MASK(e1->access_mask, e2->share_access, + SA_RIGHT_FILE_READ_EXEC, + NTCREATEX_SHARE_ACCESS_READ); + CHECK_MASK(e2->access_mask, e1->share_access, + SA_RIGHT_FILE_READ_EXEC, + NTCREATEX_SHARE_ACCESS_READ); + + CHECK_MASK(e1->access_mask, e2->share_access, + STD_RIGHT_DELETE_ACCESS, + NTCREATEX_SHARE_ACCESS_DELETE); + CHECK_MASK(e2->access_mask, e1->share_access, + STD_RIGHT_DELETE_ACCESS, + NTCREATEX_SHARE_ACCESS_DELETE); /* if a delete is pending then a second open is not allowed */ if ((e1->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) || diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1575ca82c1..73514f81b7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -289,16 +289,13 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; } - switch (access_mask & (SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA)) { - case SA_RIGHT_FILE_READ_DATA: - flags = O_RDONLY; - break; - case SA_RIGHT_FILE_WRITE_DATA: - flags = O_WRONLY; - break; - case SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_READ_DATA: + if ((access_mask & SA_RIGHT_FILE_READ_EXEC) && + (access_mask & SA_RIGHT_FILE_WRITE_DATA)) { flags = O_RDWR; - break; + } else if (access_mask & SA_RIGHT_FILE_WRITE_DATA) { + flags = O_WRONLY; + } else { + flags = O_RDONLY; } f = talloc_p(req, struct pvfs_file); @@ -493,16 +490,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - switch (access_mask & (SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA)) { - case SA_RIGHT_FILE_READ_DATA: - flags |= O_RDONLY; - break; - case SA_RIGHT_FILE_WRITE_DATA: - flags |= O_WRONLY; - break; - case SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_READ_DATA: + if ((access_mask & SA_RIGHT_FILE_READ_EXEC) && + (access_mask & SA_RIGHT_FILE_WRITE_DATA)) { flags |= O_RDWR; - break; + } else if (access_mask & SA_RIGHT_FILE_WRITE_DATA) { + flags |= O_WRONLY; + } else { + flags |= O_RDONLY; } /* handle creating a new file separately */ diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index b36840cb15..734134368d 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -48,7 +48,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (!(f->access_mask & SA_RIGHT_FILE_READ_DATA)) { + if (!(f->access_mask & SA_RIGHT_FILE_READ_EXEC)) { return NT_STATUS_ACCESS_VIOLATION; } -- cgit From b97145b2a65204504593592f305211b3b27c322a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 21:51:36 +0000 Subject: r3372: fixed the initial directory permissions for pvfs_mkdir() (This used to be commit 72ddb38a7214a49548a27ef6e6b6e7b0944b01f0) --- source4/ntvfs/posix/pvfs_mkdir.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index d7dcc7dd50..73e778016c 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -32,6 +32,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name; + mode_t mode; if (md->generic.level != RAW_MKDIR_MKDIR) { return NT_STATUS_INVALID_LEVEL; @@ -48,10 +49,9 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - /* TODO: this is a temporary implementation to allow other - tests to run */ + mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY); - if (mkdir(name->full_name, 0777) == -1) { + if (mkdir(name->full_name, mode) == -1) { return pvfs_map_errno(pvfs, errno); } -- cgit From b1c8e870d8340025f2cfbd6fe56c510be34bb0e1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Oct 2004 21:52:49 +0000 Subject: r3373: added better error reporting in pvfs_open (This used to be commit 22abdfca961a00e7c48ba4231e12f254781d315d) --- source4/ntvfs/posix/pvfs_open.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 73514f81b7..346b1420e3 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -27,8 +27,8 @@ create file handles with convenient numbers for sniffers */ #define PVFS_MIN_FILE_FNUM 0x100 -#define PVFS_MIN_NEW_FNUM 0x200 -#define PVFS_MIN_DIR_FNUM 0x1000 +#define PVFS_MIN_NEW_FNUM 0x200 +#define PVFS_MIN_DIR_FNUM 0x300 /* find open file handle given fnum @@ -64,8 +64,8 @@ static int pvfs_dir_fd_destructor(void *p) if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { if (rmdir(f->name->full_name) != 0) { - DEBUG(0,("pvfs_close: failed to rmdir '%s'\n", - f->name->full_name)); + DEBUG(0,("pvfs_close: failed to rmdir '%s' - %s\n", + f->name->full_name, strerror(errno))); } } @@ -214,8 +214,8 @@ static int pvfs_fd_destructor(void *p) if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { if (unlink(f->name->full_name) != 0) { - DEBUG(0,("pvfs_close: failed to delete '%s'\n", - f->name->full_name)); + DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", + f->name->full_name, strerror(errno))); } } -- cgit From d93636c29e4e0930e91c53b367145a0c88db7de1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 30 Oct 2004 05:53:56 +0000 Subject: r3387: fixed pvfs to pass the NTDENY tests. The tricky bit was SA_RIGHT_FILE_EXECUTE, which depends on a flags2 bit (This used to be commit c36851d230bcf552ed79322f8358060ab164ec09) --- source4/ntvfs/common/opendb.c | 12 ++++++++---- source4/ntvfs/posix/pvfs_open.c | 8 ++++---- source4/ntvfs/posix/pvfs_read.c | 9 +++++++-- source4/ntvfs/posix/pvfs_write.c | 2 +- 4 files changed, 20 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index dfb1177eae..5dc68e5382 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -154,20 +154,24 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) /* if either open involves no read.write or delete access then it can't conflict */ - if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_DATA | + if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_APPEND | SA_RIGHT_FILE_READ_EXEC | STD_RIGHT_DELETE_ACCESS))) { return False; } - if (!(e2->access_mask & (SA_RIGHT_FILE_WRITE_DATA | + if (!(e2->access_mask & (SA_RIGHT_FILE_WRITE_APPEND | SA_RIGHT_FILE_READ_EXEC | STD_RIGHT_DELETE_ACCESS))) { return False; } /* check the basic share access */ - CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE); - CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_WRITE_DATA, NTCREATEX_SHARE_ACCESS_WRITE); + CHECK_MASK(e1->access_mask, e2->share_access, + SA_RIGHT_FILE_WRITE_APPEND, + NTCREATEX_SHARE_ACCESS_WRITE); + CHECK_MASK(e2->access_mask, e1->share_access, + SA_RIGHT_FILE_WRITE_APPEND, + NTCREATEX_SHARE_ACCESS_WRITE); CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_READ_EXEC, diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 346b1420e3..bfaa7bf5a1 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -290,9 +290,9 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } if ((access_mask & SA_RIGHT_FILE_READ_EXEC) && - (access_mask & SA_RIGHT_FILE_WRITE_DATA)) { + (access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { flags = O_RDWR; - } else if (access_mask & SA_RIGHT_FILE_WRITE_DATA) { + } else if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { flags = O_WRONLY; } else { flags = O_RDONLY; @@ -491,9 +491,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } if ((access_mask & SA_RIGHT_FILE_READ_EXEC) && - (access_mask & SA_RIGHT_FILE_WRITE_DATA)) { + (access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { flags |= O_RDWR; - } else if (access_mask & SA_RIGHT_FILE_WRITE_DATA) { + } else if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { flags |= O_WRONLY; } else { flags |= O_RDONLY; diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 734134368d..1f89f01a03 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -34,6 +34,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, struct pvfs_file *f; NTSTATUS status; uint32_t maxcnt; + uint32_t mask; if (rd->generic.level != RAW_READ_READX) { return ntvfs_map_read(req, rd, ntvfs); @@ -48,8 +49,12 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (!(f->access_mask & SA_RIGHT_FILE_READ_EXEC)) { - return NT_STATUS_ACCESS_VIOLATION; + mask = SA_RIGHT_FILE_READ_DATA; + if (req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) { + mask |= SA_RIGHT_FILE_EXECUTE; + } + if (!(f->access_mask & mask)) { + return NT_STATUS_ACCESS_DENIED; } maxcnt = rd->readx.in.maxcnt; diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 235a21882a..018f43e6d0 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -48,7 +48,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (!(f->access_mask & SA_RIGHT_FILE_WRITE_DATA)) { + if (!(f->access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { return NT_STATUS_ACCESS_VIOLATION; } -- cgit From 9f1210a243654fd6d94acdef83f468a33c1b3b3f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 01:03:22 +0000 Subject: r3419: moved the libcli/raw structures into libcli/raw/libcliraw.h and made them private (This used to be commit 386ac565c452ede1d74e06acb401ca9db99d3ff3) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9c5cfd9584..39befebae5 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -26,6 +26,7 @@ */ #include "includes.h" +#include "libcli/raw/libcliraw.h" /* this is stored in ntvfs_private */ struct cvfs_private { -- cgit From 668ecaa325e827f2875295b121bbfc083702b77e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 10:02:24 +0000 Subject: r3427: split the openx logic out from the other open mapping code (This used to be commit 8d71ed9271a6ee43b9a3c28724b95714b5d2e56d) --- source4/ntvfs/ntvfs_generic.c | 263 ++++++++++++++++++++++-------------------- 1 file changed, 138 insertions(+), 125 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 2639b5ae39..da60615a44 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -55,6 +55,143 @@ static BOOL is_exe_file(const char *fname) } +/* + NTVFS openx to ntcreatex mapper +*/ +NTSTATUS ntvfs_map_open_openx(struct smbsrv_request *req, + union smb_open *io, + union smb_open *io2, + struct ntvfs_module_context *ntvfs) +{ + NTSTATUS status; + + ZERO_STRUCT(io2->generic.in); + io2->generic.level = RAW_OPEN_GENERIC; + if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) { + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; + } + if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + } + + switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { + case OPENX_MODE_ACCESS_READ: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io->openx.out.access = OPENX_MODE_ACCESS_READ; + break; + case OPENX_MODE_ACCESS_WRITE: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_WRITE; + break; + case OPENX_MODE_ACCESS_RDWR: + case OPENX_MODE_ACCESS_FCB: + case OPENX_MODE_ACCESS_EXEC: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_RDWR; + break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { + case OPENX_MODE_DENY_READ: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_WRITE: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + break; + case OPENX_MODE_DENY_ALL: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + case OPENX_MODE_DENY_NONE: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_DOS: + /* DENY_DOS is quite strange - it depends on the filename! */ + if (is_exe_file(io->openx.in.fname)) { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + } else { + if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == + OPENX_MODE_ACCESS_READ) { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + } else { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + } + } + break; + case OPENX_MODE_DENY_FCB: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + switch (io->openx.in.open_func) { + case (OPENX_OPEN_FUNC_OPEN): + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; + break; + case (OPENX_OPEN_FUNC_TRUNC): + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; + break; + case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + break; + case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; + break; + default: + /* this one is very strange */ + if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == + OPENX_MODE_ACCESS_EXEC) { + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + } + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + io2->generic.in.alloc_size = 0; + io2->generic.in.file_attr = io->openx.in.file_attrs; + io2->generic.in.fname = io->openx.in.fname; + + status = ntvfs->ops->open(ntvfs, req, io2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + io->openx.out.fnum = io2->generic.out.fnum; + io->openx.out.attrib = io2->generic.out.attrib; + io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->openx.out.size = io2->generic.out.size; + io->openx.out.ftype = 0; + io->openx.out.devstate = 0; + io->openx.out.action = io2->generic.out.create_action; + io->openx.out.unique_fid = 0; + io->openx.out.access_mask = io2->generic.in.access_mask; + io->openx.out.unknown = 0; + + /* we need to extend the file to the requested size if + it was newly created */ + if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED && + io->openx.in.size != 0) { + union smb_setfileinfo *sf; + sf = talloc_p(req, union smb_setfileinfo); + if (sf != NULL) { + sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; + sf->generic.file.fnum = io2->generic.out.fnum; + sf->end_of_file_info.in.size = io->openx.in.size; + status = ntvfs->ops->setfileinfo(ntvfs, req, sf); + if (NT_STATUS_IS_OK(status)) { + io->openx.out.size = io->openx.in.size; + } + } + } + + return NT_STATUS_OK; +} + /* NTVFS open generic to any mapper */ @@ -78,131 +215,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, return NT_STATUS_INVALID_LEVEL; case RAW_OPEN_OPENX: - ZERO_STRUCT(io2->generic.in); - io2->generic.level = RAW_OPEN_GENERIC; - if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) { - io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; - } - if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { - io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; - } - - switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { - case OPENX_MODE_ACCESS_READ: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; - io->openx.out.access = OPENX_MODE_ACCESS_READ; - break; - case OPENX_MODE_ACCESS_WRITE: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; - io->openx.out.access = OPENX_MODE_ACCESS_WRITE; - break; - case OPENX_MODE_ACCESS_RDWR: - case OPENX_MODE_ACCESS_FCB: - case OPENX_MODE_ACCESS_EXEC: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; - io->openx.out.access = OPENX_MODE_ACCESS_RDWR; - break; - default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; - } - - switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { - case OPENX_MODE_DENY_READ: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPENX_MODE_DENY_WRITE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - break; - case OPENX_MODE_DENY_ALL: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - case OPENX_MODE_DENY_NONE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPENX_MODE_DENY_DOS: - /* DENY_DOS is quite strange - it depends on the filename! */ - if (is_exe_file(io->openx.in.fname)) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - } else { - if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == - OPENX_MODE_ACCESS_READ) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - } else { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - } - } - break; - case OPENX_MODE_DENY_FCB: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; - } - - switch (io->openx.in.open_func) { - case (OPENX_OPEN_FUNC_OPEN): - io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; - break; - case (OPENX_OPEN_FUNC_TRUNC): - io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; - break; - case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; - case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; - break; - case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; - break; - default: - /* this one is very strange */ - if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == - OPENX_MODE_ACCESS_EXEC) { - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; - } - return NT_STATUS_INVALID_LOCK_SEQUENCE; - } - - io2->generic.in.alloc_size = 0; - io2->generic.in.file_attr = io->openx.in.file_attrs; - io2->generic.in.fname = io->openx.in.fname; - - status = ntvfs->ops->open(ntvfs, req, io2); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - io->openx.out.fnum = io2->generic.out.fnum; - io->openx.out.attrib = io2->generic.out.attrib; - io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); - io->openx.out.size = io2->generic.out.size; - io->openx.out.ftype = 0; - io->openx.out.devstate = 0; - io->openx.out.action = io2->generic.out.create_action; - io->openx.out.unique_fid = 0; - io->openx.out.access_mask = io2->generic.in.access_mask; - io->openx.out.unknown = 0; - - /* we need to extend the file to the requested size if - it was newly created */ - if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED && - io->openx.in.size != 0) { - union smb_setfileinfo *sf; - sf = talloc_p(req, union smb_setfileinfo); - if (sf != NULL) { - sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; - sf->generic.file.fnum = io2->generic.out.fnum; - sf->end_of_file_info.in.size = io->openx.in.size; - status = ntvfs->ops->setfileinfo(ntvfs, req, sf); - if (NT_STATUS_IS_OK(status)) { - io->openx.out.size = io->openx.in.size; - } - } - } - - return NT_STATUS_OK; + return ntvfs_map_open_openx(req, io, io2, ntvfs); case RAW_OPEN_OPEN: -- cgit From 652b8b34f8b326f79771b03e039cfa3c6ba3427e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Nov 2004 20:21:54 +0000 Subject: r3441: some include file cleanups and general housekeeping (This used to be commit 73ea8ee6c268371d05cf74160f2ad451dd2ae699) --- source4/ntvfs/nbench/vfs_nbench.c | 2 +- source4/ntvfs/ntvfs_dfs.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 396d3a418e..8820279584 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -102,7 +102,7 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, } asprintf(&logname, "/tmp/nbenchlog%d.%u", ntvfs->depth, getpid()); - nprivates->log_fd = sys_open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); + nprivates->log_fd = open(logname, O_WRONLY|O_CREAT|O_APPEND, 0644); free(logname); if (nprivates->log_fd == -1) { diff --git a/source4/ntvfs/ntvfs_dfs.c b/source4/ntvfs/ntvfs_dfs.c index 7acd1f7cbb..afba3ee43e 100644 --- a/source4/ntvfs/ntvfs_dfs.c +++ b/source4/ntvfs/ntvfs_dfs.c @@ -92,7 +92,7 @@ struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) int ntvfs_interface_version(struct ntvfs_critical_sizes *sizes) { sizes->sizeof_ntvfs_ops = sizeof(struct ntvfs_ops); - sizes->sizeof_SMB_OFF_T = sizeof(SMB_OFF_T); + sizes->sizeof_off_t = sizeof(off_t); sizes->sizeof_tcon_context = sizeof(struct tcon_context); return NTVFS_INTERFACE_VERSION; -- cgit From ead3508ac81ff3ed2a48753f3b5e23537ba6ec73 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 00:24:21 +0000 Subject: r3447: more include/system/XXX.h include files (This used to be commit 264ce9181089922547e8f6f67116f2d7277a5105) --- source4/ntvfs/posix/pvfs_dirlist.c | 1 + source4/ntvfs/posix/pvfs_lock.c | 1 + source4/ntvfs/posix/pvfs_open.c | 1 + source4/ntvfs/posix/pvfs_resolve.c | 1 + source4/ntvfs/posix/pvfs_search.c | 1 + source4/ntvfs/posix/pvfs_setfileinfo.c | 1 + source4/ntvfs/simple/svfs_util.c | 2 ++ source4/ntvfs/simple/vfs_simple.c | 1 + 8 files changed, 9 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 79f014d967..613de08087 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -23,6 +23,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "system/dir.h" struct pvfs_dir { struct pvfs_state *pvfs; diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 3835c9319b..3625fc7891 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -22,6 +22,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "system/time.h" /* diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index bfaa7bf5a1..bc56962912 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -22,6 +22,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "system/time.h" /* create file handles with convenient numbers for sniffers diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 672d028dd5..551b05b248 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -29,6 +29,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "system/dir.h" /* compare two filename components. This is where the name mangling hook will go diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 43d0f946b7..18e22c2e98 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -22,6 +22,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "system/time.h" /* the state of a search started with pvfs_search_first() */ diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index bc96f25fec..8a4c6e433d 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -22,6 +22,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "system/time.h" /* set info on a open file diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 2ac12b1918..cfe846a828 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -25,6 +25,8 @@ #include "includes.h" #include "svfs.h" +#include "system/time.h" +#include "system/dir.h" /* convert a windows path to a unix path - don't do any manging or case sensitive handling diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 379d24f848..c84483ea23 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -28,6 +28,7 @@ #include "includes.h" #include "svfs.h" +#include "system/time.h" #ifndef O_DIRECTORY #define O_DIRECTORY 0 -- cgit From 26c6b4c70bd85d8030a96651f2a255a4d48fcda1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 01:42:45 +0000 Subject: r3449: more include file reduction the ldb part isn't ideal, I will have to think of a better solution (This used to be commit 6b1f86aea8427a8e957b1aeb0ec2f507297f07cb) --- source4/ntvfs/posix/pvfs_shortname.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index f80e532762..c80e68b274 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -22,6 +22,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "system/iconv.h" /* this mangling scheme uses the following format -- cgit From edbfc0f6e70150e321822365bf0eead2821551bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 02:57:18 +0000 Subject: r3453: - split out the auth and popt includes - tidied up some of the system includes - moved a few more structures back from misc.idl to netlogon.idl and samr.idl now that pidl knows about inter-IDL dependencies (This used to be commit 7b7477ac42d96faac1b0ff361525d2c63cedfc64) --- source4/ntvfs/unixuid/vfs_unixuid.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 062f6b1b85..296dadcfe4 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "auth/auth.h" struct unixuid_private { void *samctx; -- cgit From f4ec1497a1047eab8a2077694c7629ca6bb9eaa4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 03:44:52 +0000 Subject: r3455: some more portability fixes. We nearly compile on solaris again now. (This used to be commit 4f33247f1ca60416415a61a7afac43c9dc8a61fd) --- source4/ntvfs/ipc/vfs_ipc.c | 1 + source4/ntvfs/posix/pvfs_open.c | 1 + source4/ntvfs/posix/pvfs_read.c | 1 + source4/ntvfs/posix/pvfs_search.c | 1 + 4 files changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index f7eac65712..6b6dc97003 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -26,6 +26,7 @@ #include "includes.h" +#include "system/filesys.h" /* this is the private structure used to keep the state of an open ipc$ connection. It needs to keep information about all open diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index bc56962912..89da0f4b34 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -23,6 +23,7 @@ #include "include/includes.h" #include "vfs_posix.h" #include "system/time.h" +#include "system/filesys.h" /* create file handles with convenient numbers for sniffers diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 1f89f01a03..0082f74212 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -22,6 +22,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "system/filesys.h" /* read from a file diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 18e22c2e98..0eb1573006 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -23,6 +23,7 @@ #include "include/includes.h" #include "vfs_posix.h" #include "system/time.h" +#include "system/filesys.h" /* the state of a search started with pvfs_search_first() */ -- cgit From 8692564e350db4dfa4a9ef4c4cb014d76b284d3b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 04:17:30 +0000 Subject: r3458: more solaris portability fixes, the main one being that we can't use a structure element called "open" as its a macro on solaris. (This used to be commit 4e92e15c4e396b1d8cd211192888fea68c2cf0f9) --- source4/ntvfs/ntvfs_generic.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index da60615a44..835011437f 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -221,39 +221,39 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, case RAW_OPEN_OPEN: ZERO_STRUCT(io2->generic.in); io2->generic.level = RAW_OPEN_GENERIC; - io2->generic.in.file_attr = io->open.in.search_attrs; - io2->generic.in.fname = io->open.in.fname; + io2->generic.in.file_attr = io->openold.in.search_attrs; + io2->generic.in.fname = io->openold.in.fname; io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; DEBUG(9,("ntvfs_map_open(OPEN): mapping flags=0x%x\n", - io->open.in.flags)); - switch (io->open.in.flags & OPEN_FLAGS_MODE_MASK) { + io->openold.in.flags)); + switch (io->openold.in.flags & OPEN_FLAGS_MODE_MASK) { case OPEN_FLAGS_OPEN_READ: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; - io->open.out.rmode = DOS_OPEN_RDONLY; + io->openold.out.rmode = DOS_OPEN_RDONLY; break; case OPEN_FLAGS_OPEN_WRITE: io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; - io->open.out.rmode = DOS_OPEN_WRONLY; + io->openold.out.rmode = DOS_OPEN_WRONLY; break; case OPEN_FLAGS_OPEN_RDWR: case 0xf: /* FCB mode */ io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; - io->open.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ + io->openold.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ break; default: DEBUG(2,("ntvfs_map_open(OPEN): invalid mode 0x%x\n", - io->open.in.flags & OPEN_FLAGS_MODE_MASK)); + io->openold.in.flags & OPEN_FLAGS_MODE_MASK)); return NT_STATUS_INVALID_PARAMETER; } - switch(io->open.in.flags & OPEN_FLAGS_DENY_MASK) { + switch(io->openold.in.flags & OPEN_FLAGS_DENY_MASK) { case OPEN_FLAGS_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ - if (is_exe_file(io->open.in.fname)) { + if (is_exe_file(io->openold.in.fname)) { io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; } else { - if ((io->open.in.flags & OPEN_FLAGS_MODE_MASK) == + if ((io->openold.in.flags & OPEN_FLAGS_MODE_MASK) == OPEN_FLAGS_OPEN_READ) { io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; } else { @@ -279,11 +279,11 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, break; default: DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", - io->open.in.flags & OPEN_FLAGS_DENY_MASK)); + io->openold.in.flags & OPEN_FLAGS_DENY_MASK)); return NT_STATUS_INVALID_PARAMETER; } DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", - io->open.in.flags, io2->generic.in.access_mask, io2->generic.in.share_access)); + io->openold.in.flags, io2->generic.in.access_mask, io2->generic.in.share_access)); status = ntvfs->ops->open(ntvfs, req, io2); if (!NT_STATUS_IS_OK(status)) { @@ -291,11 +291,11 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, } ZERO_STRUCT(io->openx.out); - io->open.out.fnum = io2->generic.out.fnum; - io->open.out.attrib = io2->generic.out.attrib; - io->open.out.write_time = nt_time_to_unix(io2->generic.out.write_time); - io->open.out.size = io2->generic.out.size; - io->open.out.rmode = DOS_OPEN_RDWR; + io->openold.out.fnum = io2->generic.out.fnum; + io->openold.out.attrib = io2->generic.out.attrib; + io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->openold.out.size = io2->generic.out.size; + io->openold.out.rmode = DOS_OPEN_RDWR; return NT_STATUS_OK; } -- cgit From 2df2d1b67f9bf2907f452688b2c54b73052cfb49 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 04:51:57 +0000 Subject: r3461: another place where "open" was used as a structure element (This used to be commit 1087ea830e7aead86d54a1836512e88554afc919) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/nbench/vfs_nbench.c | 10 +++++----- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/ntvfs_generic.c | 4 ++-- source4/ntvfs/ntvfs_interface.c | 12 ++++++------ source4/ntvfs/posix/vfs_posix.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 2 +- source4/ntvfs/unixuid/vfs_unixuid.c | 8 ++++---- 9 files changed, 22 insertions(+), 22 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 39befebae5..535b529a63 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -829,7 +829,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.chkpath = cvfs_chkpath; ops.qpathinfo = cvfs_qpathinfo; ops.setpathinfo = cvfs_setpathinfo; - ops.open = cvfs_open; + ops.openfile = cvfs_open; ops.mkdir = cvfs_mkdir; ops.rmdir = cvfs_rmdir; ops.rename = cvfs_rename; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 6b6dc97003..a0604a9d08 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -719,7 +719,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.chkpath = ipc_chkpath; ops.qpathinfo = ipc_qpathinfo; ops.setpathinfo = ipc_setpathinfo; - ops.open = ipc_open; + ops.openfile = ipc_open; ops.mkdir = ipc_mkdir; ops.rmdir = ipc_rmdir; ops.rename = ipc_rename; diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 8820279584..eef407638b 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -280,7 +280,7 @@ static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, /* open a file */ -static void nbench_open_send(struct smbsrv_request *req) +static void nbench_openfile_send(struct smbsrv_request *req) { union smb_open *io = req->async_states->private_data; @@ -306,12 +306,12 @@ static void nbench_open_send(struct smbsrv_request *req) PASS_THRU_REP_POST(req); } -static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) +static NTSTATUS nbench_openfile(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io)); + PASS_THRU_REQ(ntvfs, req, openfile, io, (ntvfs, req, io)); return status; } @@ -874,7 +874,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.chkpath = nbench_chkpath; ops.qpathinfo = nbench_qpathinfo; ops.setpathinfo = nbench_setpathinfo; - ops.open = nbench_open; + ops.openfile = nbench_openfile; ops.mkdir = nbench_mkdir; ops.rmdir = nbench_rmdir; ops.rename = nbench_rename; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 04e9b871c7..5e7088018b 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -51,7 +51,7 @@ struct ntvfs_ops { struct smbsrv_request *req, union smb_fileinfo *st); NTSTATUS (*setpathinfo)(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_setfileinfo *st); - NTSTATUS (*open)(struct ntvfs_module_context *ntvfs, + NTSTATUS (*openfile)(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_open *oi); NTSTATUS (*mkdir)(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_mkdir *md); diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 835011437f..8eaa3cf1b2 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -156,7 +156,7 @@ NTSTATUS ntvfs_map_open_openx(struct smbsrv_request *req, io2->generic.in.file_attr = io->openx.in.file_attrs; io2->generic.in.fname = io->openx.in.fname; - status = ntvfs->ops->open(ntvfs, req, io2); + status = ntvfs->ops->openfile(ntvfs, req, io2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -285,7 +285,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", io->openold.in.flags, io2->generic.in.access_mask, io2->generic.in.share_access)); - status = ntvfs->ops->open(ntvfs, req, io2); + status = ntvfs->ops->openfile(ntvfs, req, io2); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 7ba1c0d6be..95c01a0b50 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -77,13 +77,13 @@ NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st return ntvfs->ops->setpathinfo(ntvfs, req, st); } -NTSTATUS ntvfs_open(struct smbsrv_request *req, union smb_open *oi) +NTSTATUS ntvfs_openfile(struct smbsrv_request *req, union smb_open *oi) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->open) { + if (!ntvfs->ops->openfile) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->open(ntvfs, req, oi); + return ntvfs->ops->openfile(ntvfs, req, oi); } NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) @@ -360,13 +360,13 @@ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st); } -NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_openfile(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_open *oi) { - if (!ntvfs->next || !ntvfs->next->ops->open) { + if (!ntvfs->next || !ntvfs->next->ops->openfile) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->open(ntvfs->next, req, oi); + return ntvfs->next->ops->openfile(ntvfs->next, req, oi); } NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 8dc87b160d..7ebea2ea9a 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -213,7 +213,7 @@ NTSTATUS ntvfs_posix_init(void) ops.chkpath = pvfs_chkpath; ops.qpathinfo = pvfs_qpathinfo; ops.setpathinfo = pvfs_setpathinfo; - ops.open = pvfs_open; + ops.openfile = pvfs_open; ops.mkdir = pvfs_mkdir; ops.rmdir = pvfs_rmdir; ops.rename = pvfs_rename; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index c84483ea23..4df0bc9782 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -961,7 +961,7 @@ NTSTATUS ntvfs_simple_init(void) ops.chkpath = svfs_chkpath; ops.qpathinfo = svfs_qpathinfo; ops.setpathinfo = svfs_setpathinfo; - ops.open = svfs_open; + ops.openfile = svfs_open; ops.mkdir = svfs_mkdir; ops.rmdir = svfs_rmdir; ops.rename = svfs_rename; diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 296dadcfe4..9c74c12f91 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -469,12 +469,12 @@ static NTSTATUS unixuid_setpathinfo(struct ntvfs_module_context *ntvfs, /* open a file */ -static NTSTATUS unixuid_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) +static NTSTATUS unixuid_openfile(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, open, (ntvfs, req, io)); + PASS_THRU_REQ(ntvfs, req, openfile, (ntvfs, req, io)); return status; } @@ -760,7 +760,7 @@ NTSTATUS ntvfs_unixuid_init(void) ops.chkpath = unixuid_chkpath; ops.qpathinfo = unixuid_qpathinfo; ops.setpathinfo = unixuid_setpathinfo; - ops.open = unixuid_open; + ops.openfile = unixuid_openfile; ops.mkdir = unixuid_mkdir; ops.rmdir = unixuid_rmdir; ops.rename = unixuid_rename; -- cgit From 3643fb11092e28a9538ef32cedce8ff21ad86a28 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:42:15 +0000 Subject: r3463: separated out some more headers (asn_1.h, messages.h, dlinklist.h and ioctl.h) (This used to be commit b97e395c814762024336c1cf4d7c25be8da5813a) --- source4/ntvfs/common/brlock.c | 1 + source4/ntvfs/ipc/vfs_ipc.c | 1 + source4/ntvfs/ntvfs_base.c | 1 + source4/ntvfs/ntvfs_util.c | 1 + source4/ntvfs/posix/pvfs_ioctl.c | 1 + source4/ntvfs/posix/pvfs_lock.c | 2 ++ source4/ntvfs/posix/pvfs_open.c | 1 + source4/ntvfs/print/vfs_print.c | 1 + source4/ntvfs/simple/vfs_simple.c | 1 + 9 files changed, 10 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index a952cb1dc7..d1df0413ce 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -26,6 +26,7 @@ used. This allows us to provide the same semantics as NT */ #include "includes.h" +#include "messages.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index a0604a9d08..8bcf0382f9 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -27,6 +27,7 @@ #include "includes.h" #include "system/filesys.h" +#include "dlinklist.h" /* this is the private structure used to keep the state of an open ipc$ connection. It needs to keep information about all open diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 17900b3dfc..24470ebd65 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "dlinklist.h" /* the list of currently registered NTVFS backends, note that there diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 929ec037de..bd5a305e20 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#include "dlinklist.h" NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, void *private_data, diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 3eb016c5b4..9e2a834144 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -22,6 +22,7 @@ #include "include/includes.h" #include "vfs_posix.h" +#include "ioctl.h" /* old ioctl interface diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 3625fc7891..2668eec004 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -23,6 +23,8 @@ #include "include/includes.h" #include "vfs_posix.h" #include "system/time.h" +#include "dlinklist.h" +#include "messages.h" /* diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 89da0f4b34..f3ef72f4ed 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -24,6 +24,7 @@ #include "vfs_posix.h" #include "system/time.h" #include "system/filesys.h" +#include "dlinklist.h" /* create file handles with convenient numbers for sniffers diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index d487392e6f..b1155a0761 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -23,6 +23,7 @@ */ #include "includes.h" +#include "ioctl.h" /* connect to a share - used when a tree_connect operation comes diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 4df0bc9782..4e9fd4895e 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -29,6 +29,7 @@ #include "includes.h" #include "svfs.h" #include "system/time.h" +#include "dlinklist.h" #ifndef O_DIRECTORY #define O_DIRECTORY 0 -- cgit From a42142439aee9e75796e25cdf05e042174926abf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 06:52:59 +0000 Subject: r3464: split out registry.h, rap.h and ldap_server.h (This used to be commit 70d2090f6bf2c7e0caf1e9c020f330de88871f8e) --- source4/ntvfs/ipc/ipc_rap.c | 1 + source4/ntvfs/ipc/rap_server.c | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 840c389d6c..4fc5e182ca 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "rap.h" #define NERR_Success 0 #define NERR_badpass 86 diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index b414b40d7e..70b65442ff 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "rap.h" /* At this moment these are just dummy functions, but you might get the * idea. */ -- cgit From aa34fcebf8aa0660574a7c6976b33b3f37985e27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 07:18:24 +0000 Subject: r3466: split out request.h, signing.h, and smb_server.h (This used to be commit 7c4e6ebf05790dd6e29896dd316db0fff613aa4e) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + source4/ntvfs/ipc/vfs_ipc.c | 1 + source4/ntvfs/nbench/vfs_nbench.c | 1 + source4/ntvfs/ntvfs_base.c | 2 ++ source4/ntvfs/ntvfs_generic.c | 2 ++ source4/ntvfs/ntvfs_interface.c | 2 ++ source4/ntvfs/ntvfs_util.c | 2 ++ source4/ntvfs/posix/vfs_posix.h | 2 ++ source4/ntvfs/print/vfs_print.c | 1 + source4/ntvfs/simple/vfs_simple.c | 1 + source4/ntvfs/unixuid/vfs_unixuid.c | 1 + 11 files changed, 16 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 535b529a63..9e3c841dd3 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -27,6 +27,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "smb_server/smb_server.h" /* this is stored in ntvfs_private */ struct cvfs_private { diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 8bcf0382f9..dc43dff3aa 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -28,6 +28,7 @@ #include "includes.h" #include "system/filesys.h" #include "dlinklist.h" +#include "smb_server/smb_server.h" /* this is the private structure used to keep the state of an open ipc$ connection. It needs to keep information about all open diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index eef407638b..ef435c5d75 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -25,6 +25,7 @@ */ #include "includes.h" +#include "smb_server/smb_server.h" /* this is stored in ntvfs_private */ struct nbench_private { diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 24470ebd65..cc83b53473 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -25,6 +25,8 @@ #include "includes.h" #include "dlinklist.h" +#include "smb_server/smb_server.h" + /* the list of currently registered NTVFS backends, note that there diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 8eaa3cf1b2..6e8caf787b 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -32,6 +32,8 @@ */ #include "includes.h" +#include "smb_server/smb_server.h" + /* see if a filename ends in EXE COM DLL or SYM. This is needed for the diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 95c01a0b50..f1ab217533 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -20,6 +20,8 @@ */ #include "includes.h" +#include "smb_server/smb_server.h" + /* connect/disconnect */ NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index bd5a305e20..41e1b04d49 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -23,6 +23,8 @@ #include "includes.h" #include "dlinklist.h" +#include "smb_server/smb_server.h" + NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, void *private_data, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 231d9a2d08..530a2deae3 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -23,6 +23,8 @@ #ifndef _VFS_POSIX_H_ #define _VFS_POSIX_H_ +#include "smb_server/smb_server.h" + /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ struct pvfs_state { diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index b1155a0761..372f64e982 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -24,6 +24,7 @@ #include "includes.h" #include "ioctl.h" +#include "smb_server/smb_server.h" /* connect to a share - used when a tree_connect operation comes diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 4e9fd4895e..97dd8a7d60 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -30,6 +30,7 @@ #include "svfs.h" #include "system/time.h" #include "dlinklist.h" +#include "smb_server/smb_server.h" #ifndef O_DIRECTORY #define O_DIRECTORY 0 diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 9c74c12f91..9b62c38e13 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -23,6 +23,7 @@ #include "includes.h" #include "auth/auth.h" +#include "smb_server/smb_server.h" struct unixuid_private { void *samctx; -- cgit From a99b6219a810a1cd10bd62a6716780602808f0cd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Nov 2004 12:15:17 +0000 Subject: r3481: split out client.h and events.h (This used to be commit c6f486574470a311e0d336c026103f131451e21e) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + source4/ntvfs/posix/pvfs_wait.c | 1 + 2 files changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9e3c841dd3..4fd5650f9b 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -26,6 +26,7 @@ */ #include "includes.h" +#include "events.h" #include "libcli/raw/libcliraw.h" #include "smb_server/smb_server.h" diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 2a8cbbbe0d..f01bd0ea18 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -21,6 +21,7 @@ */ #include "include/includes.h" +#include "events.h" #include "vfs_posix.h" /* the context for a single wait instance */ -- cgit From dde07058075d357cfdc63624c8dcaa67ebd40add Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Nov 2004 10:09:48 +0000 Subject: r3507: - added deferred replies on sharing violation in pvfs open. The deferred reply is short-circuited immediately when the file is closed by another user, allowing it to be opened by the waiting user. - added a sane set of timeval manipulation routines - converted all the events code and code that uses it to use struct timeval instead of time_t, which allows for microsecond resolution instead of 1 second resolution. This was needed for doing the pvfs deferred open code, and is why the patch is so big. (This used to be commit 0d51511d408d91eb5f68a35e980e0875299b1831) --- source4/ntvfs/cifs/vfs_cifs.c | 5 +- source4/ntvfs/common/brlock.c | 7 +- source4/ntvfs/common/opendb.c | 122 +++++++++++++++++++ source4/ntvfs/posix/pvfs_lock.c | 7 +- source4/ntvfs/posix/pvfs_open.c | 254 +++++++++++++++++++++++++++++++--------- source4/ntvfs/posix/pvfs_wait.c | 12 +- source4/ntvfs/posix/vfs_posix.h | 2 + 7 files changed, 338 insertions(+), 71 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 4fd5650f9b..3e9899cb8c 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -78,7 +78,8 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin /* a handler for read events on a connection to a backend server */ -static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, time_t t, uint16_t flags) +static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, + struct timeval t, uint16_t flags) { struct cvfs_private *private = fde->private; struct smbsrv_tcon *tcon = private->tcon; @@ -149,7 +150,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); - smbcli_transport_idle_handler(private->transport, idle_func, 1, private); + smbcli_transport_idle_handler(private->transport, idle_func, 50000, private); private->transport->event.fde->handler = cifs_socket_handler; private->transport->event.fde->private = private; diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d1df0413ce..6fae7c6e4c 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -333,17 +333,14 @@ static void brl_notify_unlock(struct brl_context *brl, for (i=0;i= PENDING_READ_LOCK && brl_overlap(&locks[i], removed_lock)) { - DATA_BLOB data; - if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { continue; } if (locks[i].lock_type == PENDING_WRITE_LOCK) { last_notice = i; } - data.data = (void *)&locks[i].notify_ptr; - data.length = sizeof(void *); - messaging_send(brl->messaging_ctx, locks[i].context.server, MSG_BRL_RETRY, &data); + messaging_send_ptr(brl->messaging_ctx, locks[i].context.server, + MSG_BRL_RETRY, locks[i].notify_ptr); } } } diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 5dc68e5382..39d4f37ec2 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -39,6 +39,7 @@ */ #include "includes.h" +#include "messages.h" struct odb_context { struct tdb_wrap *w; @@ -58,6 +59,8 @@ struct odb_entry { uint32_t share_access; uint32_t create_options; uint32_t access_mask; + void *notify_ptr; + BOOL pending; }; @@ -152,6 +155,8 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) { #define CHECK_MASK(am, sa, right, share) if (((am) & (right)) && !((sa) & (share))) return True + if (e1->pending || e2->pending) return False; + /* if either open involves no read.write or delete access then it can't conflict */ if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_APPEND | @@ -219,6 +224,8 @@ NTSTATUS odb_open_file(struct odb_lock *lck, uint16_t fnum, e.share_access = share_access; e.create_options = create_options; e.access_mask = access_mask; + e.notify_ptr = NULL; + e.pending = False; /* check the existing file opens to see if they conflict */ @@ -254,6 +261,56 @@ NTSTATUS odb_open_file(struct odb_lock *lck, uint16_t fnum, } +/* + register a pending open file in the open files database +*/ +NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) +{ + struct odb_context *odb = lck->odb; + TDB_DATA dbuf; + struct odb_entry e; + char *tp; + struct odb_entry *elist; + int count; + + dbuf = tdb_fetch(odb->w->tdb, lck->key); + + e.server = odb->server; + e.tid = odb->tid; + e.fnum = 0; + e.share_access = 0; + e.create_options = 0; + e.access_mask = 0; + e.notify_ptr = private; + e.pending = True; + + /* check the existing file opens to see if they + conflict */ + elist = (struct odb_entry *)dbuf.dptr; + count = dbuf.dsize / sizeof(struct odb_entry); + + tp = Realloc(dbuf.dptr, (count+1) * sizeof(struct odb_entry)); + if (tp == NULL) { + if (dbuf.dptr) free(dbuf.dptr); + return NT_STATUS_NO_MEMORY; + } + + dbuf.dptr = tp; + dbuf.dsize = (count+1) * sizeof(struct odb_entry); + + memcpy(dbuf.dptr + (count*sizeof(struct odb_entry)), + &e, sizeof(struct odb_entry)); + + if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { + free(dbuf.dptr); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + free(dbuf.dptr); + return NT_STATUS_OK; +} + + /* remove a opendb entry */ @@ -274,6 +331,15 @@ NTSTATUS odb_close_file(struct odb_lock *lck, uint16_t fnum) elist = (struct odb_entry *)dbuf.dptr; count = dbuf.dsize / sizeof(struct odb_entry); + /* send any pending notifications */ + for (i=0;imessaging_ctx, elist[i].server, + MSG_PVFS_RETRY_OPEN, elist[i].notify_ptr); + + } + } + /* find the entry, and delete it */ for (i=0;iodb; + TDB_DATA dbuf; + struct odb_entry *elist; + int i, count; + NTSTATUS status; + + dbuf = tdb_fetch(odb->w->tdb, lck->key); + + if (dbuf.dptr == NULL) { + return NT_STATUS_UNSUCCESSFUL; + } + + elist = (struct odb_entry *)dbuf.dptr; + count = dbuf.dsize / sizeof(struct odb_entry); + + /* find the entry, and delete it */ + for (i=0;iserver == elist[i].server && + odb->tid == elist[i].tid) { + if (i < count-1) { + memmove(elist+i, elist+i+1, + (count - (i+1)) * sizeof(struct odb_entry)); + } + break; + } + } + + status = NT_STATUS_OK; + + if (i == count) { + status = NT_STATUS_UNSUCCESSFUL; + } else if (count == 1) { + if (tdb_delete(odb->w->tdb, lck->key) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } else { + dbuf.dsize = (count-1) * sizeof(struct odb_entry); + if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + free(dbuf.dptr); + + return status; +} + + /* update create options on an open file */ @@ -386,6 +506,8 @@ NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key, e.share_access = share_access; e.create_options = create_options; e.access_mask = access_mask; + e.notify_ptr = NULL; + e.pending = False; for (i=0;if = f; pending->req = req; - /* round up to the nearest second */ - pending->end_time = time(NULL) + ((lck->lockx.in.timeout+999)/1000); + pending->end_time = + timeval_current_ofs(lck->lockx.in.timeout/1000, + 1000*(lck->lockx.in.timeout%1000)); } if (lck->lockx.in.mode & LOCKING_ANDX_SHARED_LOCK) { diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index f3ef72f4ed..8ad6ad0389 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -25,6 +25,7 @@ #include "system/time.h" #include "system/filesys.h" #include "dlinklist.h" +#include "messages.h" /* create file handles with convenient numbers for sniffers @@ -33,6 +34,8 @@ #define PVFS_MIN_NEW_FNUM 0x200 #define PVFS_MIN_DIR_FNUM 0x300 +#define SHARING_VIOLATION_DELAY 1000000 + /* find open file handle given fnum */ @@ -125,7 +128,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); if (fnum == -1) { - talloc_free(f); return NT_STATUS_TOO_MANY_OPENED_FILES; } @@ -228,10 +230,12 @@ static int pvfs_fd_destructor(void *p) return 0; } - status = odb_close_file(lck, f->fnum); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", - f->name->full_name, nt_errstr(status))); + if (f->have_opendb_entry) { + status = odb_close_file(lck, f->fnum); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", + f->name->full_name, nt_errstr(status))); + } } talloc_free(lck); @@ -370,6 +374,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->access_mask = access_mask; f->seek_offset = 0; f->position = 0; + f->have_opendb_entry = True; DLIST_ADD(pvfs->open_files, f); @@ -398,6 +403,166 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } +/* + open am existing file - called from both the open retry code + and the main open code +*/ +NTSTATUS pvfs_open_existing(struct pvfs_file *f, + union smb_open *io, + int open_flags) +{ + int fd; + NTSTATUS status; + + /* do the actual open */ + fd = open(f->name->full_name, open_flags); + if (fd == -1) { + return pvfs_map_errno(f->pvfs, errno); + } + + f->fd = fd; + + /* re-resolve the open fd */ + status = pvfs_resolve_name_fd(f->pvfs, fd, f->name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.fnum = f->fnum; + io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; + io->generic.out.create_time = f->name->dos.create_time; + io->generic.out.access_time = f->name->dos.access_time; + io->generic.out.write_time = f->name->dos.write_time; + io->generic.out.change_time = f->name->dos.change_time; + io->generic.out.attrib = f->name->dos.attrib; + io->generic.out.alloc_size = f->name->dos.alloc_size; + io->generic.out.size = f->name->st.st_size; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 0; + + /* success - keep the file handle */ + talloc_steal(f->pvfs, f); + + return NT_STATUS_OK; +} + +/* + state of a pending open retry +*/ +struct pvfs_open_retry { + union smb_open *io; + struct pvfs_file *f; + struct smbsrv_request *req; + void *wait_handle; + struct timeval end_time; + int open_flags; +}; + +/* destroy a pending open request */ +static int pvfs_retry_destructor(void *ptr) +{ + struct pvfs_open_retry *r = ptr; + struct odb_lock *lck; + lck = odb_lock(r->req, r->f->pvfs->odb_context, &r->f->locking_key); + if (lck != NULL) { + odb_remove_pending(lck, r); + } + return 0; +} + +/* + retry an open +*/ +static void pvfs_open_retry(void *private, BOOL timed_out) +{ + struct pvfs_open_retry *r = private; + struct odb_lock *lck; + struct pvfs_file *f = r->f; + struct smbsrv_request *req = r->req; + NTSTATUS status; + + lck = odb_lock(req, f->pvfs->odb_context, &f->locking_key); + if (lck == NULL) { + req->async_states->status = NT_STATUS_INTERNAL_DB_CORRUPTION; + req->async_states->send_fn(req); + return; + } + + /* see if we are allowed to open at the same time as existing opens */ + status = odb_open_file(lck, f->fnum, f->share_access, + f->create_options, f->access_mask); + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) && !timed_out) { + talloc_free(lck); + return; + } + + talloc_free(r->wait_handle); + + if (!NT_STATUS_IS_OK(status)) { + req->async_states->status = status; + req->async_states->send_fn(req); + return; + } + + f->have_opendb_entry = True; + + /* do the rest of the open work */ + status = pvfs_open_existing(f, r->io, r->open_flags); + + if (NT_STATUS_IS_OK(status)) { + talloc_steal(f->pvfs, f); + } + + req->async_states->status = status; + req->async_states->send_fn(req); +} + +/* + setup for a open retry after a sharing violation +*/ +static NTSTATUS pvfs_open_setup_retry(struct smbsrv_request *req, + union smb_open *io, + struct pvfs_file *f, + struct odb_lock *lck, + int open_flags) +{ + struct pvfs_open_retry *r; + struct pvfs_state *pvfs = f->pvfs; + NTSTATUS status; + + r = talloc_p(req, struct pvfs_open_retry); + if (r == NULL) { + return NT_STATUS_NO_MEMORY; + } + + r->io = io; + r->f = f; + r->req = req; + r->end_time = timeval_current_ofs(0, SHARING_VIOLATION_DELAY); + r->open_flags = open_flags; + + /* setup a pending lock */ + status = odb_open_file_pending(lck, r); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + r->wait_handle = pvfs_wait_message(pvfs, req, MSG_PVFS_RETRY_OPEN, r->end_time, + pvfs_open_retry, r); + if (r->wait_handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + + talloc_free(lck); + talloc_steal(pvfs, req); + + talloc_set_destructor(r, pvfs_retry_destructor); + + return NT_STATUS_OK; +} + /* open a file */ @@ -405,7 +570,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_open *io) { struct pvfs_state *pvfs = ntvfs->private_data; - int fd, flags; + int flags; struct pvfs_filename *name; struct pvfs_file *f; NTSTATUS status; @@ -539,11 +704,26 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } + f->fnum = fnum; + f->fd = -1; + f->name = talloc_steal(f, name); + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->create_options = io->generic.in.create_options; + f->share_access = io->generic.in.share_access; + f->access_mask = access_mask; + f->seek_offset = 0; + f->position = 0; + f->have_opendb_entry = False; + /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f, &f->locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->idtree_fnum, f->fnum); return status; } @@ -558,65 +738,31 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, fnum, share_access, create_options, access_mask); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - return status; - } - - f->fnum = fnum; - f->fd = -1; - f->name = talloc_steal(f, name); - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; - f->pending_list = NULL; - f->lock_count = 0; - f->create_options = io->generic.in.create_options; - f->share_access = io->generic.in.share_access; - f->access_mask = access_mask; - f->seek_offset = 0; - f->position = 0; - DLIST_ADD(pvfs->open_files, f); /* setup a destructor to avoid file descriptor leaks on abnormal termination */ talloc_set_destructor(f, pvfs_fd_destructor); - /* do the actual open */ - fd = open(name->full_name, flags); - if (fd == -1) { - return pvfs_map_errno(pvfs, errno); - } - f->fd = fd; + /* see if we are allowed to open at the same time as existing opens */ + status = odb_open_file(lck, f->fnum, share_access, create_options, access_mask); + + /* on a sharing violation we need to retry when the file is closed by + the other user, or after 1 second */ + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_open_setup_retry(req, io, f, lck, flags); + } - /* re-resolve the open fd */ - status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { return status; } - io->generic.out.oplock_level = NO_OPLOCK; - io->generic.out.fnum = f->fnum; - io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; - io->generic.out.create_time = name->dos.create_time; - io->generic.out.access_time = name->dos.access_time; - io->generic.out.write_time = name->dos.write_time; - io->generic.out.change_time = name->dos.change_time; - io->generic.out.attrib = name->dos.attrib; - io->generic.out.alloc_size = name->dos.alloc_size; - io->generic.out.size = name->st.st_size; - io->generic.out.file_type = FILE_TYPE_DISK; - io->generic.out.ipc_state = 0; - io->generic.out.is_directory = 0; - - /* success - keep the file handle */ - talloc_steal(pvfs, f); + f->have_opendb_entry = True; - return NT_STATUS_OK; + /* do the rest of the open work */ + return pvfs_open_existing(f, io, flags); } @@ -677,7 +823,6 @@ NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, for (f=pvfs->open_files;f;f=next) { next = f->next; if (f->session == req->session) { - DLIST_REMOVE(pvfs->open_files, f); talloc_free(f); } } @@ -698,7 +843,6 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, for (f=pvfs->open_files;f;f=next) { next = f->next; if (f->smbpid == req->smbpid) { - DLIST_REMOVE(pvfs->open_files, f); talloc_free(f); } } diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index f01bd0ea18..0faab8ef55 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -58,10 +58,9 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin struct pvfs_wait *pwait = private; struct smbsrv_request *req; - /* we need to check that this one is for us. This sender sends - the private pointer as the body of the message. This might - seem a little unusual, but as the pointer is guaranteed - unique for this server, it is a good token */ + /* we need to check that this one is for us. See + messaging_send_ptr() for the other side of this. + */ if (data->length != sizeof(void *) || *(void **)data->data != pwait->private) { return; @@ -82,7 +81,8 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin /* receive a timeout on a message wait */ -static void pvfs_wait_timeout(struct event_context *ev, struct timed_event *te, time_t t) +static void pvfs_wait_timeout(struct event_context *ev, + struct timed_event *te, struct timeval t) { struct pvfs_wait *pwait = te->private; struct smbsrv_request *req = pwait->req; @@ -116,7 +116,7 @@ static int pvfs_wait_destructor(void *ptr) void *pvfs_wait_message(struct pvfs_state *pvfs, struct smbsrv_request *req, int msg_type, - time_t end_time, + struct timeval end_time, void (*fn)(void *, BOOL), void *private) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 530a2deae3..265649f5a3 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -112,6 +112,8 @@ struct pvfs_file { /* yes, we need 2 independent positions ... */ uint64_t seek_offset; uint64_t position; + + BOOL have_opendb_entry; }; -- cgit From 00a1262f8932a2554a75756e34523fe83a56eb50 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Nov 2004 07:36:53 +0000 Subject: r3522: added async support to most of the ntvfs_map_*() functions, allowing functions like SMBopenx, SMBread and SMBwrite to be performed async (This used to be commit 9e80eb18ae8c4a4a8cdf2f32f0c869fbbc3832b4) --- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/ntvfs_generic.c | 705 +++++++++++++++++++++++++----------------- 2 files changed, 430 insertions(+), 277 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 5e7088018b..62a735774c 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -156,7 +156,7 @@ struct ntvfs_context { struct ntvfs_async_state { struct ntvfs_async_state *prev, *next; /* the async handling infos */ - unsigned state; + uint_t state; void *private_data; void (*send_fn)(struct smbsrv_request *); NTSTATUS status; diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 6e8caf787b..01a1a2dc60 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -34,6 +34,84 @@ #include "includes.h" #include "smb_server/smb_server.h" +/* a second stage function converts from the out parameters of the generic + call onto the out parameters of the specific call made */ +typedef NTSTATUS (*second_stage_t)(struct smbsrv_request *, + struct ntvfs_module_context *, + void *, void *, NTSTATUS); + +/* + this structure holds the async state for pending mapped async calls +*/ +struct ntvfs_map_async { + struct ntvfs_module_context *ntvfs; + void *io, *io2; + second_stage_t fn; +}; + +/* + this is a async wrapper, called from the backend when it has completed + a function that it has decided to reply to in an async fashion +*/ +static void ntvfs_map_async_send(struct smbsrv_request *req) +{ + struct ntvfs_map_async *m = req->async_states->private_data; + + ntvfs_async_state_pop(req); + + /* call the _finish function setup in ntvfs_map_async_setup() */ + req->async_states->status = m->fn(req, m->ntvfs, m->io, m->io2, req->async_states->status); + + /* call the send function from the next module up */ + req->async_states->send_fn(req); +} + +/* + prepare for calling a ntvfs backend with async support + io is the original call structure + io2 is the new call structure for the mapped call + fn is a second stage function for processing the out arguments +*/ +static NTSTATUS ntvfs_map_async_setup(struct smbsrv_request *req, + struct ntvfs_module_context *ntvfs, + void *io, void *io2, + second_stage_t fn) +{ + struct ntvfs_map_async *m; + m = talloc_p(req, struct ntvfs_map_async); + if (m == NULL) { + return NT_STATUS_NO_MEMORY; + } + m->ntvfs = ntvfs; + m->io = io; + m->io2 = io2; + m->fn = fn; + return ntvfs_async_state_push(req, m, ntvfs_map_async_send, ntvfs); +} + + +/* + called when first stage processing is complete. +*/ +static NTSTATUS ntvfs_map_async_finish(struct smbsrv_request *req, NTSTATUS status) +{ + struct ntvfs_map_async *m; + + /* if the backend has decided to reply in an async fashion then + we don't need to do any work here */ + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { + return status; + } + + /* the backend is replying immediately. call the 2nd stage function after popping our local + async state */ + m = req->async_states->private_data; + + ntvfs_async_state_pop(req); + + return m->fn(req, m->ntvfs, m->io, m->io2, status); +} + /* see if a filename ends in EXE COM DLL or SYM. This is needed for the @@ -60,137 +138,65 @@ static BOOL is_exe_file(const char *fname) /* NTVFS openx to ntcreatex mapper */ -NTSTATUS ntvfs_map_open_openx(struct smbsrv_request *req, - union smb_open *io, - union smb_open *io2, - struct ntvfs_module_context *ntvfs) +static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, + struct ntvfs_module_context *ntvfs, + union smb_open *io, + union smb_open *io2, + NTSTATUS status) { - NTSTATUS status; - - ZERO_STRUCT(io2->generic.in); - io2->generic.level = RAW_OPEN_GENERIC; - if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) { - io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; - } - if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { - io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; - } - - switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { - case OPENX_MODE_ACCESS_READ: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; - io->openx.out.access = OPENX_MODE_ACCESS_READ; - break; - case OPENX_MODE_ACCESS_WRITE: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; - io->openx.out.access = OPENX_MODE_ACCESS_WRITE; - break; - case OPENX_MODE_ACCESS_RDWR: - case OPENX_MODE_ACCESS_FCB: - case OPENX_MODE_ACCESS_EXEC: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; - io->openx.out.access = OPENX_MODE_ACCESS_RDWR; - break; - default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; - } - - switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { - case OPENX_MODE_DENY_READ: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPENX_MODE_DENY_WRITE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - break; - case OPENX_MODE_DENY_ALL: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - case OPENX_MODE_DENY_NONE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPENX_MODE_DENY_DOS: - /* DENY_DOS is quite strange - it depends on the filename! */ - if (is_exe_file(io->openx.in.fname)) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - } else { - if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == - OPENX_MODE_ACCESS_READ) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - } else { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - } - } - break; - case OPENX_MODE_DENY_FCB: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; - } - - switch (io->openx.in.open_func) { - case (OPENX_OPEN_FUNC_OPEN): - io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; - break; - case (OPENX_OPEN_FUNC_TRUNC): - io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; - break; - case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; - case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; - break; - case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; - break; - default: - /* this one is very strange */ - if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == - OPENX_MODE_ACCESS_EXEC) { - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; - } - return NT_STATUS_INVALID_LOCK_SEQUENCE; - } - - io2->generic.in.alloc_size = 0; - io2->generic.in.file_attr = io->openx.in.file_attrs; - io2->generic.in.fname = io->openx.in.fname; - - status = ntvfs->ops->openfile(ntvfs, req, io2); if (!NT_STATUS_IS_OK(status)) { return status; } - - io->openx.out.fnum = io2->generic.out.fnum; - io->openx.out.attrib = io2->generic.out.attrib; - io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); - io->openx.out.size = io2->generic.out.size; - io->openx.out.ftype = 0; - io->openx.out.devstate = 0; - io->openx.out.action = io2->generic.out.create_action; - io->openx.out.unique_fid = 0; - io->openx.out.access_mask = io2->generic.in.access_mask; - io->openx.out.unknown = 0; - - /* we need to extend the file to the requested size if - it was newly created */ - if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED && - io->openx.in.size != 0) { - union smb_setfileinfo *sf; - sf = talloc_p(req, union smb_setfileinfo); - if (sf != NULL) { - sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; - sf->generic.file.fnum = io2->generic.out.fnum; + + switch (io->generic.level) { + case RAW_OPEN_OPEN: + io->openold.out.fnum = io2->generic.out.fnum; + io->openold.out.attrib = io2->generic.out.attrib; + io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->openold.out.size = io2->generic.out.size; + io->openold.out.rmode = DOS_OPEN_RDWR; + break; + + case RAW_OPEN_OPENX: + io->openx.out.fnum = io2->generic.out.fnum; + io->openx.out.attrib = io2->generic.out.attrib; + io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->openx.out.size = io2->generic.out.size; + io->openx.out.ftype = 0; + io->openx.out.devstate = 0; + io->openx.out.action = io2->generic.out.create_action; + io->openx.out.unique_fid = 0; + io->openx.out.access_mask = io2->generic.in.access_mask; + io->openx.out.unknown = 0; + + /* we need to extend the file to the requested size if + it was newly created */ + if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED && + io->openx.in.size != 0) { + union smb_setfileinfo *sf; + uint_t state; + + /* doing this secondary request async is more + trouble than its worth */ + state = req->async_states->state; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + + sf = talloc_p(req, union smb_setfileinfo); + sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; + sf->generic.file.fnum = io2->generic.out.fnum; sf->end_of_file_info.in.size = io->openx.in.size; status = ntvfs->ops->setfileinfo(ntvfs, req, sf); if (NT_STATUS_IS_OK(status)) { io->openx.out.size = io->openx.in.size; } + req->async_states->state = state; } + break; + + default: + return NT_STATUS_INVALID_LEVEL; } - + return NT_STATUS_OK; } @@ -203,54 +209,141 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, NTSTATUS status; union smb_open *io2; - io2 = talloc_p(req, union smb_open); + io2 = talloc_zero_p(req, union smb_open); if (io2 == NULL) { return NT_STATUS_NO_MEMORY; } - /* must be synchronous, or we won't be called to do the - translation */ - req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + status = ntvfs_map_async_setup(req, ntvfs, io, io2, + (second_stage_t)ntvfs_map_open_finish); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + io2->generic.level = RAW_OPEN_GENERIC; + switch (io->generic.level) { - case RAW_OPEN_GENERIC: - return NT_STATUS_INVALID_LEVEL; - case RAW_OPEN_OPENX: - return ntvfs_map_open_openx(req, io, io2, ntvfs); - - + if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) { + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; + } + if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + } + + switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { + case OPENX_MODE_ACCESS_READ: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io->openx.out.access = OPENX_MODE_ACCESS_READ; + break; + case OPENX_MODE_ACCESS_WRITE: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_WRITE; + break; + case OPENX_MODE_ACCESS_RDWR: + case OPENX_MODE_ACCESS_FCB: + case OPENX_MODE_ACCESS_EXEC: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + io->openx.out.access = OPENX_MODE_ACCESS_RDWR; + break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { + case OPENX_MODE_DENY_READ: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_WRITE: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + break; + case OPENX_MODE_DENY_ALL: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + case OPENX_MODE_DENY_NONE: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_DOS: + /* DENY_DOS is quite strange - it depends on the filename! */ + if (is_exe_file(io->openx.in.fname)) { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + } else { + if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == + OPENX_MODE_ACCESS_READ) { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + } else { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + } + } + break; + case OPENX_MODE_DENY_FCB: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + switch (io->openx.in.open_func) { + case (OPENX_OPEN_FUNC_OPEN): + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; + break; + case (OPENX_OPEN_FUNC_TRUNC): + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; + break; + case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + break; + case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; + break; + default: + /* this one is very strange */ + if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == + OPENX_MODE_ACCESS_EXEC) { + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + } + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + io2->generic.in.alloc_size = 0; + io2->generic.in.file_attr = io->openx.in.file_attrs; + io2->generic.in.fname = io->openx.in.fname; + + status = ntvfs->ops->openfile(ntvfs, req, io2); + break; + + case RAW_OPEN_OPEN: - ZERO_STRUCT(io2->generic.in); - io2->generic.level = RAW_OPEN_GENERIC; io2->generic.in.file_attr = io->openold.in.search_attrs; io2->generic.in.fname = io->openold.in.fname; io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; - DEBUG(9,("ntvfs_map_open(OPEN): mapping flags=0x%x\n", - io->openold.in.flags)); switch (io->openold.in.flags & OPEN_FLAGS_MODE_MASK) { - case OPEN_FLAGS_OPEN_READ: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; - io->openold.out.rmode = DOS_OPEN_RDONLY; - break; - case OPEN_FLAGS_OPEN_WRITE: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; - io->openold.out.rmode = DOS_OPEN_WRONLY; - break; - case OPEN_FLAGS_OPEN_RDWR: - case 0xf: /* FCB mode */ - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | - GENERIC_RIGHTS_FILE_WRITE; - io->openold.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ - break; - default: - DEBUG(2,("ntvfs_map_open(OPEN): invalid mode 0x%x\n", - io->openold.in.flags & OPEN_FLAGS_MODE_MASK)); - return NT_STATUS_INVALID_PARAMETER; + case OPEN_FLAGS_OPEN_READ: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io->openold.out.rmode = DOS_OPEN_RDONLY; + break; + case OPEN_FLAGS_OPEN_WRITE: + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io->openold.out.rmode = DOS_OPEN_WRONLY; + break; + case OPEN_FLAGS_OPEN_RDWR: + case 0xf: /* FCB mode */ + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | + GENERIC_RIGHTS_FILE_WRITE; + io->openold.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ + break; + default: + DEBUG(2,("ntvfs_map_open(OPEN): invalid mode 0x%x\n", + io->openold.in.flags & OPEN_FLAGS_MODE_MASK)); + return NT_STATUS_INVALID_PARAMETER; } - switch(io->openold.in.flags & OPEN_FLAGS_DENY_MASK) { - case OPEN_FLAGS_DENY_DOS: + switch (io->openold.in.flags & OPEN_FLAGS_DENY_MASK) { + case OPEN_FLAGS_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ if (is_exe_file(io->openold.in.fname)) { io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; @@ -263,46 +356,36 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, } } break; - case OPEN_FLAGS_DENY_ALL: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - case OPEN_FLAGS_DENY_WRITE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - break; - case OPEN_FLAGS_DENY_READ: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPEN_FLAGS_DENY_NONE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | - NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE; - break; - case 0x70: /* FCB mode */ - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - default: - DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", - io->openold.in.flags & OPEN_FLAGS_DENY_MASK)); - return NT_STATUS_INVALID_PARAMETER; + case OPEN_FLAGS_DENY_ALL: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + case OPEN_FLAGS_DENY_WRITE: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + break; + case OPEN_FLAGS_DENY_READ: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPEN_FLAGS_DENY_NONE: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE; + break; + case 0x70: /* FCB mode */ + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + default: + DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", + io->openold.in.flags & OPEN_FLAGS_DENY_MASK)); + return NT_STATUS_INVALID_PARAMETER; } - DEBUG(9,("ntvfs_map_open(OPEN): mapped flags=0x%x to access_mask=0x%x and share_access=0x%x\n", - io->openold.in.flags, io2->generic.in.access_mask, io2->generic.in.share_access)); status = ntvfs->ops->openfile(ntvfs, req, io2); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - ZERO_STRUCT(io->openx.out); - io->openold.out.fnum = io2->generic.out.fnum; - io->openold.out.attrib = io2->generic.out.attrib; - io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); - io->openold.out.size = io2->generic.out.size; - io->openold.out.rmode = DOS_OPEN_RDWR; - - return NT_STATUS_OK; + break; + + default: + return NT_STATUS_INVALID_LEVEL; } - return NT_STATUS_INVALID_LEVEL; + return ntvfs_map_async_finish(req, status); } @@ -323,6 +406,10 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, if (fs->generic.level == RAW_QFS_GENERIC) { return NT_STATUS_INVALID_LEVEL; } + + /* this map function is only used by the simple backend, which + doesn't do async */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; /* ask the backend for the generic info */ fs2->generic.level = RAW_QFS_GENERIC; @@ -705,8 +792,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf info2->generic.level = RAW_FILEINFO_GENERIC; info2->generic.in.fname = info->generic.in.fname; - /* must be synchronous, or we won't be called to do the - translation */ + /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; status = ntvfs->ops->qpathinfo(ntvfs, req, info2); @@ -767,112 +853,176 @@ NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck, /* NTVFS write generic to any mapper */ -NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, - struct ntvfs_module_context *ntvfs) +static NTSTATUS ntvfs_map_write_finish(struct smbsrv_request *req, + struct ntvfs_module_context *ntvfs, + union smb_write *wr, + union smb_write *wr2, + NTSTATUS status) + { - union smb_write *wr2; union smb_lock *lck; union smb_close *cl; - NTSTATUS status; + uint_t state; - wr2 = talloc_p(req, union smb_write); - if (wr2 == NULL) { - return NT_STATUS_NO_MEMORY; + if (NT_STATUS_IS_ERR(status)) { + return status; } - wr2->generic.level = RAW_WRITE_GENERIC; - - /* we can't map asynchronously */ - req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; - switch (wr->generic.level) { - case RAW_WRITE_WRITEX: - status = NT_STATUS_INVALID_LEVEL; - break; - case RAW_WRITE_WRITE: - wr2->generic.in.fnum = wr->write.in.fnum; - wr2->generic.in.offset = wr->write.in.offset; - wr2->generic.in.wmode = 0; - wr2->generic.in.remaining = wr->write.in.remaining; - wr2->generic.in.count = wr->write.in.count; - wr2->generic.in.data = wr->write.in.data; - status = ntvfs->ops->write(ntvfs, req, wr2); wr->write.out.nwritten = wr2->generic.out.nwritten; break; case RAW_WRITE_WRITEUNLOCK: + wr->writeunlock.out.nwritten = wr2->generic.out.nwritten; + lck = talloc_p(wr2, union smb_lock); if (lck == NULL) { return NT_STATUS_NO_MEMORY; } - wr2->generic.in.fnum = wr->writeunlock.in.fnum; - wr2->generic.in.offset = wr->writeunlock.in.offset; - wr2->generic.in.wmode = 0; - wr2->generic.in.remaining = wr->writeunlock.in.remaining; - wr2->generic.in.count = wr->writeunlock.in.count; - wr2->generic.in.data = wr->writeunlock.in.data; - lck->unlock.level = RAW_LOCK_UNLOCK; lck->unlock.in.fnum = wr->writeunlock.in.fnum; lck->unlock.in.count = wr->writeunlock.in.count; lck->unlock.in.offset = wr->writeunlock.in.offset; - status = ntvfs->ops->write(ntvfs, req, wr2); - - wr->writeunlock.out.nwritten = wr2->generic.out.nwritten; - - if (NT_STATUS_IS_OK(status) && - lck->unlock.in.count != 0) { + if (lck->unlock.in.count != 0) { + /* do the lock sync for now */ + state = req->async_states->state; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; status = ntvfs->ops->lock(ntvfs, req, lck); + req->async_states->state = state; } break; case RAW_WRITE_WRITECLOSE: + wr->writeclose.out.nwritten = wr2->generic.out.nwritten; + cl = talloc_p(wr2, union smb_close); if (cl == NULL) { return NT_STATUS_NO_MEMORY; } - wr2->generic.in.fnum = wr->writeclose.in.fnum; - wr2->generic.in.offset = wr->writeclose.in.offset; - wr2->generic.in.wmode = 0; - wr2->generic.in.remaining = 0; - wr2->generic.in.count = wr->writeclose.in.count; - wr2->generic.in.data = wr->writeclose.in.data; - cl->close.level = RAW_CLOSE_CLOSE; cl->close.in.fnum = wr->writeclose.in.fnum; cl->close.in.write_time = wr->writeclose.in.mtime; - status = ntvfs->ops->write(ntvfs, req, wr2); - wr->writeclose.out.nwritten = wr2->generic.out.nwritten; - - if (NT_STATUS_IS_OK(status) && - wr2->generic.in.count != 0) { + if (wr2->generic.in.count != 0) { + /* do the close sync for now */ + state = req->async_states->state; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; status = ntvfs->ops->close(ntvfs, req, cl); + req->async_states->state = state; } break; case RAW_WRITE_SPLWRITE: - wr2->generic.in.fnum = wr->splwrite.in.fnum; - wr2->generic.in.offset = 0; - wr2->generic.in.wmode = 0; - wr2->generic.in.remaining = 0; - wr2->generic.in.count = wr->splwrite.in.count; - wr2->generic.in.data = wr->splwrite.in.data; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + return status; +} + + +/* + NTVFS write generic to any mapper +*/ +NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, + struct ntvfs_module_context *ntvfs) +{ + union smb_write *wr2; + NTSTATUS status; + + wr2 = talloc_p(req, union smb_write); + if (wr2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = ntvfs_map_async_setup(req, ntvfs, wr, wr2, + (second_stage_t)ntvfs_map_write_finish); + + wr2->writex.level = RAW_WRITE_GENERIC; + + switch (wr->generic.level) { + case RAW_WRITE_WRITEX: + status = NT_STATUS_INVALID_LEVEL; + break; + + case RAW_WRITE_WRITE: + wr2->writex.in.fnum = wr->write.in.fnum; + wr2->writex.in.offset = wr->write.in.offset; + wr2->writex.in.wmode = 0; + wr2->writex.in.remaining = wr->write.in.remaining; + wr2->writex.in.count = wr->write.in.count; + wr2->writex.in.data = wr->write.in.data; + status = ntvfs->ops->write(ntvfs, req, wr2); + break; + + case RAW_WRITE_WRITEUNLOCK: + wr2->writex.in.fnum = wr->writeunlock.in.fnum; + wr2->writex.in.offset = wr->writeunlock.in.offset; + wr2->writex.in.wmode = 0; + wr2->writex.in.remaining = wr->writeunlock.in.remaining; + wr2->writex.in.count = wr->writeunlock.in.count; + wr2->writex.in.data = wr->writeunlock.in.data; + status = ntvfs->ops->write(ntvfs, req, wr2); + break; + + case RAW_WRITE_WRITECLOSE: + wr2->writex.in.fnum = wr->writeclose.in.fnum; + wr2->writex.in.offset = wr->writeclose.in.offset; + wr2->writex.in.wmode = 0; + wr2->writex.in.remaining = 0; + wr2->writex.in.count = wr->writeclose.in.count; + wr2->writex.in.data = wr->writeclose.in.data; + status = ntvfs->ops->write(ntvfs, req, wr2); + break; + + case RAW_WRITE_SPLWRITE: + wr2->writex.in.fnum = wr->splwrite.in.fnum; + wr2->writex.in.offset = 0; + wr2->writex.in.wmode = 0; + wr2->writex.in.remaining = 0; + wr2->writex.in.count = wr->splwrite.in.count; + wr2->writex.in.data = wr->splwrite.in.data; status = ntvfs->ops->write(ntvfs, req, wr2); break; } + return ntvfs_map_async_finish(req, status); +} + + +/* + NTVFS read generic to any mapper - finish the out mapping +*/ +static NTSTATUS ntvfs_map_read_finish(struct smbsrv_request *req, + struct ntvfs_module_context *ntvfs, + union smb_read *rd, + union smb_read *rd2, + NTSTATUS status) +{ + switch (rd->generic.level) { + case RAW_READ_READ: + rd->read.out.nread = rd2->generic.out.nread; + break; + case RAW_READ_READBRAW: + rd->readbraw.out.nread = rd2->generic.out.nread; + break; + case RAW_READ_LOCKREAD: + rd->lockread.out.nread = rd2->generic.out.nread; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } return status; } - /* - NTVFS read generic to any mapper + NTVFS read* to readx mapper */ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, struct ntvfs_module_context *ntvfs) @@ -880,16 +1030,20 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, union smb_read *rd2; union smb_lock *lck; NTSTATUS status; + uint_t state; rd2 = talloc_p(req, union smb_read); if (rd2 == NULL) { return NT_STATUS_NO_MEMORY; } - rd2->generic.level = RAW_READ_GENERIC; + status = ntvfs_map_async_setup(req, ntvfs, rd, rd2, + (second_stage_t)ntvfs_map_read_finish); + if (!NT_STATUS_IS_OK(status)) { + return status; + } - /* we can't map asynchronously */ - req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + rd2->readx.level = RAW_READ_READX; switch (rd->generic.level) { case RAW_READ_READX: @@ -897,56 +1051,55 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, break; case RAW_READ_READ: - rd2->generic.in.fnum = rd->read.in.fnum; - rd2->generic.in.offset = rd->read.in.offset; - rd2->generic.in.mincnt = rd->read.in.count; - rd2->generic.in.maxcnt = rd->read.in.count; - rd2->generic.in.remaining = rd->read.in.remaining; - rd2->generic.out.data = rd->read.out.data; + rd2->readx.in.fnum = rd->read.in.fnum; + rd2->readx.in.offset = rd->read.in.offset; + rd2->readx.in.mincnt = rd->read.in.count; + rd2->readx.in.maxcnt = rd->read.in.count; + rd2->readx.in.remaining = rd->read.in.remaining; + rd2->readx.out.data = rd->read.out.data; status = ntvfs->ops->read(ntvfs, req, rd2); - rd->read.out.nread = rd2->generic.out.nread; break; case RAW_READ_READBRAW: - rd2->generic.in.fnum = rd->readbraw.in.fnum; - rd2->generic.in.offset = rd->readbraw.in.offset; - rd2->generic.in.mincnt = rd->readbraw.in.mincnt; - rd2->generic.in.maxcnt = rd->readbraw.in.maxcnt; - rd2->generic.in.remaining = 0; - rd2->generic.out.data = rd->readbraw.out.data; + rd2->readx.in.fnum = rd->readbraw.in.fnum; + rd2->readx.in.offset = rd->readbraw.in.offset; + rd2->readx.in.mincnt = rd->readbraw.in.mincnt; + rd2->readx.in.maxcnt = rd->readbraw.in.maxcnt; + rd2->readx.in.remaining = 0; + rd2->readx.out.data = rd->readbraw.out.data; status = ntvfs->ops->read(ntvfs, req, rd2); - rd->readbraw.out.nread = rd2->generic.out.nread; break; case RAW_READ_LOCKREAD: + /* do the initial lock sync for now */ + state = req->async_states->state; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + lck = talloc_p(rd2, union smb_lock); if (lck == NULL) { return NT_STATUS_NO_MEMORY; } - - rd2->generic.in.fnum = rd->lockread.in.fnum; - rd2->generic.in.offset = rd->lockread.in.offset; - rd2->generic.in.mincnt = rd->lockread.in.count; - rd2->generic.in.maxcnt = rd->lockread.in.count; - rd2->generic.in.remaining = rd->lockread.in.remaining; - rd2->generic.out.data = rd->lockread.out.data; - lck->lock.level = RAW_LOCK_LOCK; lck->lock.in.fnum = rd->lockread.in.fnum; lck->lock.in.count = rd->lockread.in.count; lck->lock.in.offset = rd->lockread.in.offset; - status = ntvfs->ops->lock(ntvfs, req, lck); + req->async_states->state = state; + + rd2->readx.in.fnum = rd->lockread.in.fnum; + rd2->readx.in.offset = rd->lockread.in.offset; + rd2->readx.in.mincnt = rd->lockread.in.count; + rd2->readx.in.maxcnt = rd->lockread.in.count; + rd2->readx.in.remaining = rd->lockread.in.remaining; + rd2->readx.out.data = rd->lockread.out.data; if (NT_STATUS_IS_OK(status)) { status = ntvfs->ops->read(ntvfs, req, rd2); - rd->lockread.out.nread = rd2->generic.out.nread; } break; } - - return status; + return ntvfs_map_async_finish(req, status); } -- cgit From c870ae8b898d3bcc81ed9fd1afd505d78dea52cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Nov 2004 11:28:38 +0000 Subject: r3528: added support for the SMBntcancel() operation, which cancels any outstanding async operation (triggering an immediate timeout). pvfs now passes the RAW-MUX test (This used to be commit 3423e2f41461d054067ef168b9b986f62cc8f77c) --- source4/ntvfs/cifs/vfs_cifs.c | 10 ++++++++++ source4/ntvfs/common/brlock.c | 15 ++++++++------- source4/ntvfs/ipc/vfs_ipc.c | 10 ++++++++++ source4/ntvfs/nbench/vfs_nbench.c | 20 ++++++++++++++++++++ source4/ntvfs/ntvfs.h | 4 ++++ source4/ntvfs/ntvfs_generic.c | 3 +++ source4/ntvfs/ntvfs_interface.c | 24 ++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_open.c | 1 - source4/ntvfs/posix/pvfs_wait.c | 31 +++++++++++++++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 1 + source4/ntvfs/posix/vfs_posix.h | 4 ++++ source4/ntvfs/simple/vfs_simple.c | 13 +++++++++++++ source4/ntvfs/unixuid/vfs_unixuid.c | 14 ++++++++++++++ 13 files changed, 142 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 3e9899cb8c..ea169b7ee6 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -650,6 +650,15 @@ static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + cancel an async call +*/ +static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + return NT_STATUS_NOT_IMPLEMENTED; +} + /* lock a byte range */ @@ -855,6 +864,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.trans = cvfs_trans; ops.logoff = cvfs_logoff; ops.async_setup = cvfs_async_setup; + ops.cancel = cvfs_cancel; if (lp_parm_bool(-1, "cifs", "maptrans2", False)) { ops.trans2 = cvfs_trans2; diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 6fae7c6e4c..2b30270eff 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -63,7 +63,7 @@ struct brl_context { servid_t server; uint16_t tid; struct messaging_context *messaging_ctx; - struct lock_struct last_lock_failure; + struct lock_struct last_lock; }; @@ -95,7 +95,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, brl->server = server; brl->tid = tid; brl->messaging_ctx = messaging_ctx; - ZERO_STRUCT(brl->last_lock_failure); + ZERO_STRUCT(brl->last_lock); return brl; } @@ -194,13 +194,14 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck */ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) { - if (brl_same_context(&lock->context, &brl->last_lock_failure.context) && - lock->fnum == brl->last_lock_failure.fnum && - lock->start == brl->last_lock_failure.start && - lock->size == brl->last_lock_failure.size) { + if (lock->context.server == brl->last_lock.context.server && + lock->context.tid == brl->last_lock.context.tid && + lock->fnum == brl->last_lock.fnum && + lock->start == brl->last_lock.start && + lock->size == brl->last_lock.size) { return NT_STATUS_FILE_LOCK_CONFLICT; } - brl->last_lock_failure = *lock; + brl->last_lock = *lock; if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { /* amazing the little things you learn with a test diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index dc43dff3aa..271be09ac3 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -519,6 +519,15 @@ static NTSTATUS ipc_async_setup(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + cancel an async call +*/ +static NTSTATUS ipc_cancel(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + return NT_STATUS_UNSUCCESSFUL; +} + /* lock a byte range */ @@ -744,6 +753,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.trans = ipc_trans; ops.logoff = ipc_logoff; ops.async_setup = ipc_async_setup; + ops.cancel = ipc_cancel; /* register ourselves with the NTVFS subsystem. */ ret = register_backend("ntvfs", &ops); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index ef435c5d75..1bcfda1371 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -643,6 +643,25 @@ static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, return status; } + +static void nbench_cancel_send(struct smbsrv_request *req) +{ + PASS_THRU_REP_POST(req); +} + +/* + cancel an existing async request +*/ +static NTSTATUS nbench_cancel(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, cancel, NULL, (ntvfs, req)); + + return status; +} + /* lock a byte range */ @@ -898,6 +917,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.trans = nbench_trans; ops.logoff = nbench_logoff; ops.async_setup = nbench_async_setup; + ops.cancel = nbench_cancel; /* we don't register a trans2 handler as we want to be able to log individual trans2 requests */ diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 62a735774c..3a6a78c032 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -117,6 +117,10 @@ struct ntvfs_ops { /* async_setup - called when a backend is processing a async request */ NTSTATUS (*async_setup)(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, void *private); + + /* cancel - cancels any pending async request */ + NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req); }; struct ntvfs_module_context { diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 01a1a2dc60..885eb9719e 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -942,6 +942,9 @@ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, status = ntvfs_map_async_setup(req, ntvfs, wr, wr2, (second_stage_t)ntvfs_map_write_finish); + if (!NT_STATUS_IS_OK(status)) { + return status; + } wr2->writex.level = RAW_WRITE_GENERIC; diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index f1ab217533..6ab5aad790 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -306,6 +306,20 @@ NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private) return ntvfs->ops->async_setup(ntvfs, req, private); } + +/* + cancel an outstanding async request +*/ +NTSTATUS ntvfs_cancel(struct smbsrv_request *req) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->cancel) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->cancel(ntvfs, req); +} + + /* initial setup */ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) @@ -588,3 +602,13 @@ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, } return ntvfs->next->ops->async_setup(ntvfs->next, req, private); } + +/* cancel - called to cancel an outstanding async request */ +NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + if (!ntvfs->next || !ntvfs->next->ops->cancel) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->cancel(ntvfs->next, req); +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 8ad6ad0389..2c0f55cf22 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -556,7 +556,6 @@ static NTSTATUS pvfs_open_setup_retry(struct smbsrv_request *req, } talloc_free(lck); - talloc_steal(pvfs, req); talloc_set_destructor(r, pvfs_retry_destructor); diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 0faab8ef55..df7f045e00 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -22,10 +22,13 @@ #include "include/includes.h" #include "events.h" +#include "dlinklist.h" #include "vfs_posix.h" /* the context for a single wait instance */ struct pvfs_wait { + struct pvfs_wait *next, *prev; + struct pvfs_state *pvfs; void (*handler)(void *, BOOL); void *private; struct timed_event *te; @@ -103,6 +106,7 @@ static int pvfs_wait_destructor(void *ptr) struct pvfs_wait *pwait = ptr; messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); event_remove_timed(pwait->ev, pwait->te); + DLIST_REMOVE(pwait->pvfs->wait_list, pwait); return 0; } @@ -134,6 +138,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; pwait->req = req; + pwait->pvfs = pvfs; /* setup a timer */ te.next_event = end_time; @@ -152,8 +157,34 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, asynchronously */ req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + DLIST_ADD(pvfs->wait_list, pwait); + /* make sure we cleanup the timer and message handler */ talloc_set_destructor(pwait, pvfs_wait_destructor); + /* make sure that on a disconnect the request is not destroyed + before pvfs */ + talloc_steal(pvfs, req); + return pwait; } + + +/* + cancel an outstanding async request +*/ +NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_wait *pwait; + for (pwait=pvfs->wait_list;pwait;pwait=pwait->next) { + if (SVAL(req->in.hdr, HDR_MID) == SVAL(pwait->req->in.hdr, HDR_MID) && + req->smbpid == pwait->req->smbpid) { + /* trigger an early timeout */ + pvfs_wait_timeout(pwait->ev, pwait->te, timeval_current()); + return NT_STATUS_OK; + } + } + + return NT_STATUS_UNSUCCESSFUL; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 7ebea2ea9a..9ad1d3cb35 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -236,6 +236,7 @@ NTSTATUS ntvfs_posix_init(void) ops.trans = pvfs_trans; ops.logoff = pvfs_logoff; ops.async_setup = pvfs_async_setup; + ops.cancel = pvfs_cancel; /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 265649f5a3..ce6e7ad24d 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -46,6 +46,10 @@ struct pvfs_state { /* an id tree mapping open file handle -> struct pvfs_file */ struct idr_context *idtree_fnum; + + /* a list of pending async requests. Needed to support + ntcancel */ + struct pvfs_wait *wait_list; }; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 97dd8a7d60..807f51a43d 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -608,6 +608,14 @@ static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + cancel an async call +*/ +static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) +{ + return NT_STATUS_UNSUCCESSFUL; +} + /* lock a byte range */ @@ -668,6 +676,10 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } break; + default: + DEBUG(2,("svfs_setfileinfo: level %d not implemented\n", + info->generic.level)); + return NT_STATUS_NOT_IMPLEMENTED; } return NT_STATUS_OK; } @@ -986,6 +998,7 @@ NTSTATUS ntvfs_simple_init(void) ops.trans = svfs_trans; ops.logoff = svfs_logoff; ops.async_setup = svfs_async_setup; + ops.cancel = svfs_cancel; /* register ourselves with the NTVFS subsystem. We register under names 'simple' diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 9b62c38e13..7f8f8acf99 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -640,6 +640,19 @@ static NTSTATUS unixuid_async_setup(struct ntvfs_module_context *ntvfs, return status; } +/* + cancel an async request +*/ +static NTSTATUS unixuid_cancel(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, cancel, (ntvfs, req)); + + return status; +} + /* lock a byte range */ @@ -784,6 +797,7 @@ NTSTATUS ntvfs_unixuid_init(void) ops.trans = unixuid_trans; ops.logoff = unixuid_logoff; ops.async_setup = unixuid_async_setup; + ops.cancel = unixuid_cancel; ops.name = "unixuid"; -- cgit From 8fa7f264c62eca51868307796cdfd2dcc0abceff Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Nov 2004 12:12:09 +0000 Subject: r3530: make sure we match ntvfs_async_state_pop() with ntvfs_async_state_push() (This used to be commit 730ae0600e6c75a7048f7aaf3995604e8cdbba39) --- source4/ntvfs/ntvfs_generic.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 885eb9719e..274d5caa87 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -247,7 +247,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io->openx.out.access = OPENX_MODE_ACCESS_RDWR; break; default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; + status = NT_STATUS_INVALID_LOCK_SEQUENCE; + goto done; } switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { @@ -280,7 +281,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; + status = NT_STATUS_INVALID_LOCK_SEQUENCE; + goto done; } switch (io->openx.in.open_func) { @@ -306,7 +308,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; break; } - return NT_STATUS_INVALID_LOCK_SEQUENCE; + status = NT_STATUS_INVALID_LOCK_SEQUENCE; + goto done; } io2->generic.in.alloc_size = 0; @@ -339,7 +342,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, default: DEBUG(2,("ntvfs_map_open(OPEN): invalid mode 0x%x\n", io->openold.in.flags & OPEN_FLAGS_MODE_MASK)); - return NT_STATUS_INVALID_PARAMETER; + status = NT_STATUS_INVALID_PARAMETER; + goto done; } switch (io->openold.in.flags & OPEN_FLAGS_DENY_MASK) { @@ -375,16 +379,19 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, default: DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", io->openold.in.flags & OPEN_FLAGS_DENY_MASK)); - return NT_STATUS_INVALID_PARAMETER; + status = NT_STATUS_INVALID_PARAMETER; + goto done; } status = ntvfs->ops->openfile(ntvfs, req, io2); break; default: - return NT_STATUS_INVALID_LEVEL; + status = NT_STATUS_INVALID_LEVEL; + break; } +done: return ntvfs_map_async_finish(req, status); } @@ -1080,7 +1087,8 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, lck = talloc_p(rd2, union smb_lock); if (lck == NULL) { - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto done; } lck->lock.level = RAW_LOCK_LOCK; lck->lock.in.fnum = rd->lockread.in.fnum; @@ -1102,6 +1110,7 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, break; } +done: return ntvfs_map_async_finish(req, status); } -- cgit From 39cd0639e9007bfd8b896b335aea50ace8631112 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Nov 2004 13:15:22 +0000 Subject: r3531: add support for RAW_OPEN_MKNEW, RAW_OPEN_CREATE and RAW_OPEN_CTEMP in pvfs (This used to be commit 1d2f0a55c1de01cbbf6552371584847223841bc3) --- source4/ntvfs/ntvfs_generic.c | 109 +++++++++++++++++++++++++++++++++++------- 1 file changed, 91 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 274d5caa87..ed41b3d4d2 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -144,6 +144,11 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, union smb_open *io2, NTSTATUS status) { + time_t write_time = 0; + uint32_t set_size = 0; + union smb_setfileinfo *sf; + uint_t state; + if (!NT_STATUS_IS_OK(status)) { return status; } @@ -171,32 +176,56 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, /* we need to extend the file to the requested size if it was newly created */ - if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED && - io->openx.in.size != 0) { - union smb_setfileinfo *sf; - uint_t state; + if (io2->generic.out.create_action == NTCREATEX_ACTION_CREATED) { + set_size = io->openx.in.size; + } + break; - /* doing this secondary request async is more - trouble than its worth */ - state = req->async_states->state; - req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + case RAW_OPEN_MKNEW: + case RAW_OPEN_CREATE: + io->mknew.out.fnum = io2->generic.out.fnum; + write_time = io->mknew.in.write_time; + break; - sf = talloc_p(req, union smb_setfileinfo); - sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; - sf->generic.file.fnum = io2->generic.out.fnum; - sf->end_of_file_info.in.size = io->openx.in.size; - status = ntvfs->ops->setfileinfo(ntvfs, req, sf); - if (NT_STATUS_IS_OK(status)) { - io->openx.out.size = io->openx.in.size; - } - req->async_states->state = state; - } + case RAW_OPEN_CTEMP: + io->ctemp.out.fnum = io2->generic.out.fnum; + io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + + strlen(io->ctemp.in.directory) + 1); + write_time = io->ctemp.in.write_time; break; default: return NT_STATUS_INVALID_LEVEL; } + /* doing a secondary request async is more trouble than its + worth */ + state = req->async_states->state; + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + + if (write_time != 0) { + sf = talloc_p(req, union smb_setfileinfo); + sf->generic.level = RAW_SFILEINFO_STANDARD; + sf->generic.file.fnum = io2->generic.out.fnum; + sf->standard.in.create_time = 0; + sf->standard.in.write_time = write_time; + sf->standard.in.access_time = 0; + status = ntvfs->ops->setfileinfo(ntvfs, req, sf); + } + + if (set_size != 0) { + sf = talloc_p(req, union smb_setfileinfo); + sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; + sf->generic.file.fnum = io2->generic.out.fnum; + sf->end_of_file_info.in.size = io->openx.in.size; + status = ntvfs->ops->setfileinfo(ntvfs, req, sf); + if (NT_STATUS_IS_OK(status)) { + io->openx.out.size = io->openx.in.size; + } + } + + req->async_states->state = state; + return NT_STATUS_OK; } @@ -386,6 +415,50 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, status = ntvfs->ops->openfile(ntvfs, req, io2); break; + + case RAW_OPEN_MKNEW: + io2->generic.in.file_attr = io->mknew.in.attrib; + io2->generic.in.fname = io->mknew.in.fname; + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + io2->generic.in.access_mask = + GENERIC_RIGHTS_FILE_READ | + GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + status = ntvfs->ops->openfile(ntvfs, req, io2); + break; + + case RAW_OPEN_CREATE: + io2->generic.in.file_attr = io->mknew.in.attrib; + io2->generic.in.fname = io->mknew.in.fname; + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io2->generic.in.access_mask = + GENERIC_RIGHTS_FILE_READ | + GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + status = ntvfs->ops->openfile(ntvfs, req, io2); + break; + + case RAW_OPEN_CTEMP: + io2->generic.in.file_attr = io->ctemp.in.attrib; + io2->generic.in.file_attr = 0; + io2->generic.in.fname = + talloc_asprintf(io2, "%s\\SRV%s", + io->ctemp.in.directory, + generate_random_str_list(io2, 5, "0123456789")); + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + io2->generic.in.access_mask = + GENERIC_RIGHTS_FILE_READ | + GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + status = ntvfs->ops->openfile(ntvfs, req, io2); + break; + default: status = NT_STATUS_INVALID_LEVEL; break; -- cgit From b2617daeb658af9959ea71432d87fa4273b7f1a4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Nov 2004 13:27:29 +0000 Subject: r3532: make sharing violation delay in pvfs configurable with "posix:sharedelay = usecs" (This used to be commit c4758776491e5ed9f5b8c387226d1e75bc70eb2e) --- source4/ntvfs/posix/pvfs_open.c | 4 +--- source4/ntvfs/posix/vfs_posix.c | 7 +++++++ source4/ntvfs/posix/vfs_posix.h | 3 +++ 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 2c0f55cf22..06191cee0a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -34,8 +34,6 @@ #define PVFS_MIN_NEW_FNUM 0x200 #define PVFS_MIN_DIR_FNUM 0x300 -#define SHARING_VIOLATION_DELAY 1000000 - /* find open file handle given fnum */ @@ -540,7 +538,7 @@ static NTSTATUS pvfs_open_setup_retry(struct smbsrv_request *req, r->io = io; r->f = f; r->req = req; - r->end_time = timeval_current_ofs(0, SHARING_VIOLATION_DELAY); + r->end_time = timeval_current_ofs(0, pvfs->sharing_violation_delay); r->open_flags = open_flags; /* setup a pending lock */ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 9ad1d3cb35..2f0f38dd22 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -34,6 +34,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) { int snum = pvfs->tcon->service; + int delay; if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; @@ -43,6 +44,12 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; + pvfs->sharing_violation_delay = 1000000; + delay = lp_parm_int(snum, "posix", "sharedelay"); + if (delay != -1) { + pvfs->sharing_violation_delay = delay; + } + pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index ce6e7ad24d..e0d8e7fe37 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -50,6 +50,9 @@ struct pvfs_state { /* a list of pending async requests. Needed to support ntcancel */ struct pvfs_wait *wait_list; + + /* the sharing violation timeout */ + uint_t sharing_violation_delay; }; -- cgit From 80eef3ea6647a9f8600466b2b468d38bd2eb0664 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 01:14:06 +0000 Subject: r3539: much nicer async open delay code. The previous code didn't handle the case where the file got renamed or deleted while waiting for the sharing violation delay. To handle this we need to make the 2nd open a full open call, including the name resolve call etc. Luckily this simplifies the logic. I also expanded the RAW-MUX test to include the case where we do open/open/open/close/close, with the 3rd open async, and that open gets retried after both the first close and the 2nd close, with the first retry failing and the 2nd retry working. The tests the "async reply after a async reply" logic in pvfs_open(). (This used to be commit eded2ad9c91f5ba587ef4f7f5f5a6dceb4b51ff3) --- source4/ntvfs/common/opendb.c | 6 +- source4/ntvfs/posix/pvfs_open.c | 178 +++++++++++++++++++--------------------- 2 files changed, 87 insertions(+), 97 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 39d4f37ec2..bed4910be4 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -331,12 +331,14 @@ NTSTATUS odb_close_file(struct odb_lock *lck, uint16_t fnum) elist = (struct odb_entry *)dbuf.dptr; count = dbuf.dsize / sizeof(struct odb_entry); - /* send any pending notifications */ + /* send any pending notifications, removing them once sent */ for (i=0;imessaging_ctx, elist[i].server, MSG_PVFS_RETRY_OPEN, elist[i].notify_ptr); - + memmove(&elist[i], &elist[i+1], sizeof(struct odb_entry)*(count-(i+1))); + i--; + count--; } } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 06191cee0a..73b1949acb 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -401,71 +401,28 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } -/* - open am existing file - called from both the open retry code - and the main open code -*/ -NTSTATUS pvfs_open_existing(struct pvfs_file *f, - union smb_open *io, - int open_flags) -{ - int fd; - NTSTATUS status; - - /* do the actual open */ - fd = open(f->name->full_name, open_flags); - if (fd == -1) { - return pvfs_map_errno(f->pvfs, errno); - } - - f->fd = fd; - - /* re-resolve the open fd */ - status = pvfs_resolve_name_fd(f->pvfs, fd, f->name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - io->generic.out.oplock_level = NO_OPLOCK; - io->generic.out.fnum = f->fnum; - io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; - io->generic.out.create_time = f->name->dos.create_time; - io->generic.out.access_time = f->name->dos.access_time; - io->generic.out.write_time = f->name->dos.write_time; - io->generic.out.change_time = f->name->dos.change_time; - io->generic.out.attrib = f->name->dos.attrib; - io->generic.out.alloc_size = f->name->dos.alloc_size; - io->generic.out.size = f->name->st.st_size; - io->generic.out.file_type = FILE_TYPE_DISK; - io->generic.out.ipc_state = 0; - io->generic.out.is_directory = 0; - - /* success - keep the file handle */ - talloc_steal(f->pvfs, f); - - return NT_STATUS_OK; -} - /* state of a pending open retry */ struct pvfs_open_retry { - union smb_open *io; - struct pvfs_file *f; + struct ntvfs_module_context *ntvfs; struct smbsrv_request *req; + union smb_open *io; void *wait_handle; - struct timeval end_time; - int open_flags; + DATA_BLOB locking_key; }; /* destroy a pending open request */ static int pvfs_retry_destructor(void *ptr) { struct pvfs_open_retry *r = ptr; - struct odb_lock *lck; - lck = odb_lock(r->req, r->f->pvfs->odb_context, &r->f->locking_key); - if (lck != NULL) { - odb_remove_pending(lck, r); + struct pvfs_state *pvfs = r->ntvfs->private_data; + if (r->locking_key.data) { + struct odb_lock *lck; + lck = odb_lock(r->req, pvfs->odb_context, &r->locking_key); + if (lck != NULL) { + odb_remove_pending(lck, r); + } } return 0; } @@ -476,70 +433,70 @@ static int pvfs_retry_destructor(void *ptr) static void pvfs_open_retry(void *private, BOOL timed_out) { struct pvfs_open_retry *r = private; - struct odb_lock *lck; - struct pvfs_file *f = r->f; + struct ntvfs_module_context *ntvfs = r->ntvfs; struct smbsrv_request *req = r->req; + union smb_open *io = r->io; NTSTATUS status; - - lck = odb_lock(req, f->pvfs->odb_context, &f->locking_key); - if (lck == NULL) { - req->async_states->status = NT_STATUS_INTERNAL_DB_CORRUPTION; - req->async_states->send_fn(req); - return; - } - - /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, f->fnum, f->share_access, - f->create_options, f->access_mask); - if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) && !timed_out) { - talloc_free(lck); - return; - } talloc_free(r->wait_handle); - if (!NT_STATUS_IS_OK(status)) { - req->async_states->status = status; + if (timed_out) { + /* if it timed out, then give the failure + immediately */ + talloc_free(r); + req->async_states->status = NT_STATUS_SHARING_VIOLATION; req->async_states->send_fn(req); return; } - f->have_opendb_entry = True; + /* the pending odb entry is already removed. We use a null locking + key to indicate this */ + data_blob_free(&r->locking_key); + talloc_free(r); - /* do the rest of the open work */ - status = pvfs_open_existing(f, r->io, r->open_flags); + /* try the open again, which could trigger another retry setup + if it wants to, so we have to unmark the async flag so we + will know if it does a second async reply */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC; - if (NT_STATUS_IS_OK(status)) { - talloc_steal(f->pvfs, f); + status = pvfs_open(ntvfs, req, io); + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { + /* the 2nd try also replied async, so we don't send + the reply yet */ + return; } + /* send the reply up the chain */ req->async_states->status = status; req->async_states->send_fn(req); } + /* setup for a open retry after a sharing violation */ -static NTSTATUS pvfs_open_setup_retry(struct smbsrv_request *req, +static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io, - struct pvfs_file *f, - struct odb_lock *lck, - int open_flags) + struct pvfs_file *f, + struct odb_lock *lck) { + struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_open_retry *r; - struct pvfs_state *pvfs = f->pvfs; NTSTATUS status; + struct timeval end_time; r = talloc_p(req, struct pvfs_open_retry); if (r == NULL) { return NT_STATUS_NO_MEMORY; } - r->io = io; - r->f = f; + r->ntvfs = ntvfs; r->req = req; - r->end_time = timeval_current_ofs(0, pvfs->sharing_violation_delay); - r->open_flags = open_flags; + r->io = io; + r->locking_key = data_blob_talloc(r, f->locking_key.data, f->locking_key.length); + + end_time = timeval_add(&req->request_time, 0, pvfs->sharing_violation_delay); /* setup a pending lock */ status = odb_open_file_pending(lck, r); @@ -547,16 +504,17 @@ static NTSTATUS pvfs_open_setup_retry(struct smbsrv_request *req, return status; } - r->wait_handle = pvfs_wait_message(pvfs, req, MSG_PVFS_RETRY_OPEN, r->end_time, + talloc_free(lck); + talloc_free(f); + + talloc_set_destructor(r, pvfs_retry_destructor); + + r->wait_handle = pvfs_wait_message(pvfs, req, MSG_PVFS_RETRY_OPEN, end_time, pvfs_open_retry, r); if (r->wait_handle == NULL) { return NT_STATUS_NO_MEMORY; } - talloc_free(lck); - - talloc_set_destructor(r, pvfs_retry_destructor); - return NT_STATUS_OK; } @@ -571,7 +529,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; struct pvfs_file *f; NTSTATUS status; - int fnum; + int fnum, fd; struct odb_lock *lck; uint32_t create_options; uint32_t share_access; @@ -749,7 +707,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, the other user, or after 1 second */ if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) && (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return pvfs_open_setup_retry(req, io, f, lck, flags); + return pvfs_open_setup_retry(ntvfs, req, io, f, lck); } if (!NT_STATUS_IS_OK(status)) { @@ -758,8 +716,38 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->have_opendb_entry = True; - /* do the rest of the open work */ - return pvfs_open_existing(f, io, flags); + /* do the actual open */ + fd = open(f->name->full_name, flags); + if (fd == -1) { + return pvfs_map_errno(f->pvfs, errno); + } + + f->fd = fd; + + /* re-resolve the open fd */ + status = pvfs_resolve_name_fd(f->pvfs, fd, f->name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.fnum = f->fnum; + io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; + io->generic.out.create_time = f->name->dos.create_time; + io->generic.out.access_time = f->name->dos.access_time; + io->generic.out.write_time = f->name->dos.write_time; + io->generic.out.change_time = f->name->dos.change_time; + io->generic.out.attrib = f->name->dos.attrib; + io->generic.out.alloc_size = f->name->dos.alloc_size; + io->generic.out.size = f->name->st.st_size; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 0; + + /* success - keep the file handle */ + talloc_steal(f->pvfs, f); + + return NT_STATUS_OK; } -- cgit From 1d97e7b9d8a8e716cd50bb42065687a65d542b2d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 02:22:07 +0000 Subject: r3540: added testing of SMBntcancel in the open/open/close mux testing. Interestingly, w2k3 does not allow the cancel of an outstanding async open request, whereas it does allow the cancel of an outstanding async lock request. To support this I have changed the pvfs_wait interface to provide a enum on why the event is happening, so the callback can decide what to do. (This used to be commit f23d6a28008a13588cde24b5012ec21e488ac47a) --- source4/ntvfs/posix/pvfs_lock.c | 6 +++++- source4/ntvfs/posix/pvfs_open.c | 10 ++++++++-- source4/ntvfs/posix/pvfs_wait.c | 19 ++++++++++--------- source4/ntvfs/posix/vfs_posix.h | 13 +++++++++++++ 4 files changed, 36 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 82ac9ebad5..f778b59d95 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -91,7 +91,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, range, so we should try the lock again. Note that on timeout we do retry the lock, giving it a last chance. */ -static void pvfs_pending_lock_continue(void *private, BOOL timed_out) +static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reason) { struct pvfs_pending_lock *pending = private; struct pvfs_state *pvfs = pending->pvfs; @@ -102,6 +102,10 @@ static void pvfs_pending_lock_continue(void *private, BOOL timed_out) enum brl_type rw; NTSTATUS status; int i; + BOOL timed_out; + + /* we consider a cancel to be a timeout */ + timed_out = (reason != PVFS_WAIT_EVENT); locks = lck->lockx.in.locks + lck->lockx.in.ulock_cnt; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 73b1949acb..c8f96849ec 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -430,7 +430,7 @@ static int pvfs_retry_destructor(void *ptr) /* retry an open */ -static void pvfs_open_retry(void *private, BOOL timed_out) +static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) { struct pvfs_open_retry *r = private; struct ntvfs_module_context *ntvfs = r->ntvfs; @@ -438,9 +438,15 @@ static void pvfs_open_retry(void *private, BOOL timed_out) union smb_open *io = r->io; NTSTATUS status; + /* w2k3 ignores SMBntcancel for outstanding open requests. It's probably + just a bug in their server, but we better do the same */ + if (reason == PVFS_WAIT_CANCEL) { + return; + } + talloc_free(r->wait_handle); - if (timed_out) { + if (reason == PVFS_WAIT_TIMEOUT) { /* if it timed out, then give the failure immediately */ talloc_free(r); diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index df7f045e00..dd7afaf653 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -29,14 +29,14 @@ struct pvfs_wait { struct pvfs_wait *next, *prev; struct pvfs_state *pvfs; - void (*handler)(void *, BOOL); + void (*handler)(void *, enum pvfs_wait_notice); void *private; struct timed_event *te; int msg_type; struct messaging_context *msg_ctx; struct event_context *ev; struct smbsrv_request *req; - BOOL timed_out; + enum pvfs_wait_notice reason; }; /* @@ -48,7 +48,7 @@ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, void *private) { struct pvfs_wait *pwait = private; - pwait->handler(pwait->private, pwait->timed_out); + pwait->handler(pwait->private, pwait->reason); return NT_STATUS_OK; } @@ -68,7 +68,7 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin *(void **)data->data != pwait->private) { return; } - pwait->timed_out = False; + pwait->reason = PVFS_WAIT_EVENT; req = pwait->req; /* the extra reference here is to ensure that the req @@ -90,7 +90,7 @@ static void pvfs_wait_timeout(struct event_context *ev, struct pvfs_wait *pwait = te->private; struct smbsrv_request *req = pwait->req; - pwait->timed_out = True; + pwait->reason = PVFS_WAIT_TIMEOUT; talloc_increase_ref_count(req); ntvfs_async_setup(pwait->req, pwait); @@ -117,11 +117,11 @@ static int pvfs_wait_destructor(void *ptr) the return value is a handle. To stop waiting talloc_free this handle. */ -void *pvfs_wait_message(struct pvfs_state *pvfs, + void *pvfs_wait_message(struct pvfs_state *pvfs, struct smbsrv_request *req, int msg_type, struct timeval end_time, - void (*fn)(void *, BOOL), + void (*fn)(void *, enum pvfs_wait_notice), void *private) { struct timed_event te; @@ -180,8 +180,9 @@ NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request * for (pwait=pvfs->wait_list;pwait;pwait=pwait->next) { if (SVAL(req->in.hdr, HDR_MID) == SVAL(pwait->req->in.hdr, HDR_MID) && req->smbpid == pwait->req->smbpid) { - /* trigger an early timeout */ - pvfs_wait_timeout(pwait->ev, pwait->te, timeval_current()); + /* trigger a cancel on the request */ + pwait->reason = PVFS_WAIT_CANCEL; + ntvfs_async_setup(pwait->req, pwait); return NT_STATUS_OK; } } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index e0d8e7fe37..4ee06723ac 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -165,4 +165,17 @@ struct pvfs_mangle_context { /* forward declare some anonymous structures */ struct pvfs_dir; +/* types of notification for pvfs wait events */ +enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; + + +/* putting this prototype here avoids us having to expose this whole header in the + rest of Samba */ +void *pvfs_wait_message(struct pvfs_state *pvfs, + struct smbsrv_request *req, + int msg_type, + struct timeval end_time, + void (*fn)(void *, enum pvfs_wait_notice), + void *private); + #endif /* _VFS_POSIX_H_ */ -- cgit From 0a8dff9e475aea5312ecc4bc283e8007ee653185 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 07:24:25 +0000 Subject: r3544: fixed some #include lines to make them more consistent (This used to be commit a1a0118bd3f1cae034a1c564d05c3aa8019ff932) --- source4/ntvfs/posix/pvfs_flush.c | 2 +- source4/ntvfs/posix/pvfs_fsinfo.c | 2 +- source4/ntvfs/posix/pvfs_ioctl.c | 2 +- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_mkdir.c | 2 +- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_search.c | 2 +- source4/ntvfs/posix/pvfs_seek.c | 2 +- source4/ntvfs/posix/pvfs_shortname.c | 5 +---- source4/ntvfs/posix/pvfs_unlink.c | 2 +- source4/ntvfs/posix/pvfs_wait.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 2 +- 14 files changed, 14 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 43893af80d..6195d254ff 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" /* diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 6ddef98ea0..7b2226579a 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 9e2a834144..45d29b530d 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "ioctl.h" diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index f778b59d95..446ff1f30b 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/time.h" #include "dlinklist.h" diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 73e778016c..3b5204c934 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" /* diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index db4951fff0..4c699d63ce 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 0082f74212..f5df26f3d1 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/filesys.h" diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index ad69f092ad..552148a891 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" /* diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 0eb1573006..831b799716 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/time.h" #include "system/filesys.h" diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index f965e584ee..c90db952fc 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" /* diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index c80e68b274..3627820bb0 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/iconv.h" @@ -56,9 +56,6 @@ */ -#include "includes.h" -#include "vfs_posix.h" - #if 1 #define M_DEBUG(level, x) DEBUG(level, x) #else diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index ff02d77613..ab8f1abf62 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index dd7afaf653..a226918877 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "events.h" #include "dlinklist.h" #include "vfs_posix.h" diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 018f43e6d0..ccf3a775a8 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" -- cgit From 9fe5fa11d637252f1fbe79c7baf778e2d3cdade2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 07:29:02 +0000 Subject: r3545: initial support for using extended attributes to hold extended dos attributes of files. I decided to use IDL/NDR to encode the attribute, as it gives us a simple way to describe and extend the saved attributes. The xattr code needs to hook into quite a few more places in the pvfs code, but this at least gets the basics done. I will start encoding alternate data streams streams, DOS EAs etc soon using the same basic mechanism. I'll probably stick to "version 1" for the xattr.idl for quite a while even though it will be changing, as I don't expect anyone to be deploying this in production just yet. Once we have production users we will need to keep compatibility by supporting all the old version numbers in xattr.idl. (This used to be commit c54253ed1b7dce1d14f43e747da61089aea87094) --- source4/ntvfs/posix/config.m4 | 13 ++- source4/ntvfs/posix/config.mk | 9 ++ source4/ntvfs/posix/pvfs_fileinfo.c | 56 ++++++---- source4/ntvfs/posix/pvfs_open.c | 14 ++- source4/ntvfs/posix/pvfs_resolve.c | 10 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 17 ++- source4/ntvfs/posix/pvfs_xattr.c | 197 +++++++++++++++++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 6 +- source4/ntvfs/posix/vfs_posix.h | 1 + 9 files changed, 291 insertions(+), 32 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_xattr.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index b1de4c20e5..2fb69b65b0 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -1,4 +1,3 @@ -SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) dnl ############################################# @@ -22,4 +21,16 @@ if test x"$ac_cv_decl_have_stat_tv_nsec" = x"yes"; then AC_DEFINE(HAVE_STAT_TV_NSEC,1,[Whether stat has tv_nsec nanosecond fields]) fi +dnl ############################################ +dnl use flistxattr as the key function for having +dnl sufficient xattr support for posix xattr backend +AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) +AC_SEARCH_LIBS(flistxattr, [attr]) + +if test x"$ac_cv_func_flistxattr" = x"yes"; then + SMB_MODULE_DEFAULT(posix_xattr, STATIC) + AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) +fi +SMB_MODULE_MK(posix_xattr, NTVFS, NOT, ntvfs/posix/config.mk) +SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 4918ee61eb..d44200d8c3 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,3 +1,12 @@ +################################################ +# Start MODULE posix_xattr +[MODULE::posix_xattr] +INIT_OBJ_FILES = \ + ntvfs/posix/pvfs_xattr.o +# End MODULE posix_xattr +################################################ + + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 42aad1a20e..49678e5998 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" @@ -45,14 +45,16 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) if ((st->st_mode & S_IWUSR) == 0) result |= FILE_ATTRIBUTE_READONLY; - if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0)) - result |= FILE_ATTRIBUTE_ARCHIVE; - - if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0)) - result |= FILE_ATTRIBUTE_SYSTEM; - - if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0)) - result |= FILE_ATTRIBUTE_HIDDEN; + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0)) + result |= FILE_ATTRIBUTE_ARCHIVE; + + if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0)) + result |= FILE_ATTRIBUTE_SYSTEM; + + if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0)) + result |= FILE_ATTRIBUTE_HIDDEN; + } if (S_ISDIR(st->st_mode)) result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY); @@ -74,7 +76,7 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) /* fill in the dos file attributes for a file */ -NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) +NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) { /* make directories appear as size 0 */ if (S_ISDIR(name->st.st_mode)) { @@ -98,6 +100,12 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name) name->dos.ea_size = 0; name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; +#if HAVE_XATTR_SUPPORT + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + return pvfs_xattr_load(pvfs, name, fd); + } +#endif + return NT_STATUS_OK; } @@ -117,19 +125,21 @@ mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32 attrib) mode |= S_IWUSR; } - if ((attrib & FILE_ATTRIBUTE_ARCHIVE) && - (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) { - mode |= S_IXUSR; - } - - if ((attrib & FILE_ATTRIBUTE_SYSTEM) && - (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) { - mode |= S_IXGRP; - } - - if ((attrib & FILE_ATTRIBUTE_HIDDEN) && - (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) { - mode |= S_IXOTH; + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + if ((attrib & FILE_ATTRIBUTE_ARCHIVE) && + (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) { + mode |= S_IXUSR; + } + + if ((attrib & FILE_ATTRIBUTE_SYSTEM) && + (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) { + mode |= S_IXGRP; + } + + if ((attrib & FILE_ATTRIBUTE_HIDDEN) && + (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) { + mode |= S_IXOTH; + } } return mode; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c8f96849ec..ed6da83e73 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/time.h" #include "system/filesys.h" @@ -330,6 +330,14 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } + +#if HAVE_XATTR_SUPPORT + name->dos.attrib = io->ntcreatex.in.file_attr; + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + status = pvfs_xattr_save(pvfs, name, fd); + } +#endif + /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f, &f->locking_key); @@ -472,6 +480,10 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) return; } + /* re-mark it async, just in case someone up the chain does + paranoid checking */ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + /* send the reply up the chain */ req->async_states->status = status; req->async_states->send_fn(req); diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 551b05b248..30602b964a 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -27,7 +27,7 @@ */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/dir.h" @@ -175,7 +175,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * name->full_name = partial_name; if (name->exists) { - return pvfs_fill_dos_info(pvfs, name); + return pvfs_fill_dos_info(pvfs, name, -1); } return NT_STATUS_OK; @@ -446,7 +446,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* if we can stat() the full name now then we are done */ if (stat((*name)->full_name, &(*name)->st) == 0) { (*name)->exists = True; - return pvfs_fill_dos_info(pvfs, *name); + return pvfs_fill_dos_info(pvfs, *name, -1); } /* search for a matching filename */ @@ -489,7 +489,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, (*name)->original_name = talloc_strdup(*name, fname); (*name)->stream_name = NULL; - status = pvfs_fill_dos_info(pvfs, *name); + status = pvfs_fill_dos_info(pvfs, *name, -1); return status; } @@ -534,5 +534,5 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, name->exists = True; - return pvfs_fill_dos_info(pvfs, name); + return pvfs_fill_dos_info(pvfs, name, fd); } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 8a4c6e433d..fe489c2e69 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -20,7 +20,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" #include "system/time.h" @@ -163,6 +163,13 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } } + *f->name = newstats; + +#if HAVE_XATTR_SUPPORT + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + return pvfs_xattr_save(pvfs, f->name, f->fd); + } +#endif return NT_STATUS_OK; } @@ -287,6 +294,14 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } } + *name = newstats; + +#if HAVE_XATTR_SUPPORT + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + return pvfs_xattr_save(pvfs, name, -1); + } +#endif + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c new file mode 100644 index 0000000000..24fa49108a --- /dev/null +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -0,0 +1,197 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - xattr support + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_xattr.h" + + +/* + pull a xattr as a blob, from either a file or a file descriptor +*/ +static NTSTATUS pull_xattr_blob(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *fname, + int fd, + size_t estimated_size, + DATA_BLOB *blob) +{ + int ret; + + *blob = data_blob_talloc(mem_ctx, NULL, estimated_size); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + +again: + if (fd != -1) { + ret = fgetxattr(fd, attr_name, blob->data, estimated_size); + } else { + ret = getxattr(fname, attr_name, blob->data, estimated_size); + } + if (ret == -1 && errno == ERANGE) { + estimated_size *= 2; + blob->data = talloc_realloc(mem_ctx, blob->data, estimated_size); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + blob->length = estimated_size; + goto again; + } + + if (ret == -1) { + data_blob_free(blob); + return map_nt_error_from_unix(errno); + } + + blob->length = ret; + + return NT_STATUS_OK; +} + +/* + push a xattr as a blob, from either a file or a file descriptor +*/ +static NTSTATUS push_xattr_blob(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *fname, + int fd, + const DATA_BLOB *blob) +{ + int ret; + + if (fd != -1) { + ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0); + } else { + ret = setxattr(fname, attr_name, blob->data, blob->length, 0); + } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + + +/* + fill in file attributes from extended attributes +*/ +NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +{ + DATA_BLOB blob; + NTSTATUS status; + struct xattr_DosAttrib attrib; + TALLOC_CTX *mem_ctx = talloc(name, 0); + struct xattr_DosInfo1 *info1; + + status = pull_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, + fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob); + + /* if the filesystem doesn't support them, then tell pvfs not to try again */ + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + DEBUG(5,("pvfs_xattr: xattr not supported in filesystem\n")); + pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + + /* not having a DosAttrib is not an error */ + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + /* pull the blob */ + status = ndr_pull_struct_blob(&blob, mem_ctx, &attrib, + (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + switch (attrib.version) { + case 1: + info1 = &attrib.info.info1; + name->dos.attrib = info1->attrib; + name->dos.ea_size = info1->ea_size; + if (name->st.st_size == info1->size) { + name->dos.alloc_size = info1->alloc_size; + } + if (info1->create_time != 0) { + name->dos.create_time = info1->create_time; + } + if (info1->change_time != 0) { + name->dos.change_time = info1->change_time; + } + break; + + default: + DEBUG(0,("ERROR: Unsupported xattr DosAttrib version %d on '%s'\n", + attrib.version, name->full_name)); + talloc_free(mem_ctx); + return NT_STATUS_INVALID_LEVEL; + } + + talloc_free(mem_ctx); + return NT_STATUS_OK; +} + + +/* + save the file attribute into into the xattr +*/ +NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +{ + struct xattr_DosAttrib attrib; + struct xattr_DosInfo1 *info1; + TALLOC_CTX *mem_ctx = talloc(name, 0); + DATA_BLOB blob; + NTSTATUS status; + + attrib.version = 1; + info1 = &attrib.info.info1; + + info1->attrib = name->dos.attrib; + info1->ea_size = name->dos.ea_size; + info1->size = name->st.st_size; + info1->alloc_size = name->dos.alloc_size; + info1->create_time = name->dos.create_time; + info1->change_time = name->dos.change_time; + + status = ndr_push_struct_blob(&blob, mem_ctx, &attrib, + (ndr_push_flags_fn_t)ndr_push_xattr_DosAttrib); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + status = push_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, fd, &blob); + talloc_free(mem_ctx); + + return status; +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 2f0f38dd22..da4296d062 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -24,7 +24,7 @@ This is the default backend */ -#include "include/includes.h" +#include "includes.h" #include "vfs_posix.h" @@ -44,6 +44,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; +#if HAVE_XATTR_SUPPORT + if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; +#endif + pvfs->sharing_violation_delay = 1000000; delay = lp_parm_int(snum, "posix", "sharedelay"); if (delay != -1) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 4ee06723ac..64b9a0d653 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -161,6 +161,7 @@ struct pvfs_mangle_context { #define PVFS_FLAG_READONLY (1<<4) #define PVFS_FLAG_STRICT_SYNC (1<<5) #define PVFS_FLAG_STRICT_LOCKING (1<<6) +#define PVFS_FLAG_XATTR_ENABLE (1<<7) /* forward declare some anonymous structures */ struct pvfs_dir; -- cgit From 12f4a44cf549b4ccd729494c242a5ec186d2d670 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 11:31:35 +0000 Subject: r3549: added support for DOS extended attribute lists (name/value pairs) stored in posix xattrs (This used to be commit bad6a88371264cffce2bf5d6ce904b7b357081de) --- source4/ntvfs/posix/config.m4 | 2 - source4/ntvfs/posix/config.mk | 10 +-- source4/ntvfs/posix/pvfs_fileinfo.c | 26 +++---- source4/ntvfs/posix/pvfs_open.c | 10 +-- source4/ntvfs/posix/pvfs_qfileinfo.c | 39 ++++++++-- source4/ntvfs/posix/pvfs_setfileinfo.c | 78 ++++++++++++++++---- source4/ntvfs/posix/pvfs_xattr.c | 128 +++++++++++++++++++++++++-------- 7 files changed, 212 insertions(+), 81 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 2fb69b65b0..975da5f2a9 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -28,9 +28,7 @@ AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) AC_SEARCH_LIBS(flistxattr, [attr]) if test x"$ac_cv_func_flistxattr" = x"yes"; then - SMB_MODULE_DEFAULT(posix_xattr, STATIC) AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) fi -SMB_MODULE_MK(posix_xattr, NTVFS, NOT, ntvfs/posix/config.mk) SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index d44200d8c3..dd72468216 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,12 +1,3 @@ -################################################ -# Start MODULE posix_xattr -[MODULE::posix_xattr] -INIT_OBJ_FILES = \ - ntvfs/posix/pvfs_xattr.o -# End MODULE posix_xattr -################################################ - - ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -33,6 +24,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_wait.o \ ntvfs/posix/pvfs_seek.o \ ntvfs/posix/pvfs_ioctl.o \ + ntvfs/posix/pvfs_xattr.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 49678e5998..2419893049 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -45,16 +45,14 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) if ((st->st_mode & S_IWUSR) == 0) result |= FILE_ATTRIBUTE_READONLY; - if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { - if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0)) - result |= FILE_ATTRIBUTE_ARCHIVE; - - if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0)) - result |= FILE_ATTRIBUTE_SYSTEM; - - if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0)) - result |= FILE_ATTRIBUTE_HIDDEN; - } + if ((pvfs->flags & PVFS_FLAG_MAP_ARCHIVE) && ((st->st_mode & S_IXUSR) != 0)) + result |= FILE_ATTRIBUTE_ARCHIVE; + + if ((pvfs->flags & PVFS_FLAG_MAP_SYSTEM) && ((st->st_mode & S_IXGRP) != 0)) + result |= FILE_ATTRIBUTE_SYSTEM; + + if ((pvfs->flags & PVFS_FLAG_MAP_HIDDEN) && ((st->st_mode & S_IXOTH) != 0)) + result |= FILE_ATTRIBUTE_HIDDEN; if (S_ISDIR(st->st_mode)) result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY); @@ -100,13 +98,7 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.ea_size = 0; name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; -#if HAVE_XATTR_SUPPORT - if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { - return pvfs_xattr_load(pvfs, name, fd); - } -#endif - - return NT_STATUS_OK; + return pvfs_dosattrib_load(pvfs, name, fd); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index ed6da83e73..d640bae279 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -330,13 +330,13 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } - -#if HAVE_XATTR_SUPPORT name->dos.attrib = io->ntcreatex.in.file_attr; - if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { - status = pvfs_xattr_save(pvfs, name, fd); + status = pvfs_dosattrib_save(pvfs, name, fd); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; } -#endif /* form the lock context used for byte range locking and opendb locking */ diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 4c699d63ce..51aadc07a5 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -22,13 +22,42 @@ #include "includes.h" #include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_xattr.h" +/* + reply to a RAW_FILEINFO_ALL_EAS call +*/ +static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + struct pvfs_filename *name, int fd, struct smb_all_eas *eas) +{ + NTSTATUS status; + int i; + struct xattr_DosEAs *ealist = talloc_p(mem_ctx, struct xattr_DosEAs); + + ZERO_STRUCTP(eas); + status = pvfs_doseas_load(pvfs, name, fd, ealist); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + eas->num_eas = ealist->num_eas; + eas->eas = talloc_array_p(mem_ctx, struct ea_struct, eas->num_eas); + if (eas->eas == NULL) { + return NT_STATUS_NO_MEMORY; + } + for (i=0;inum_eas;i++) { + eas->eas[i].flags = 0; + eas->eas[i].name.s = ealist->eas[i].name; + eas->eas[i].value = ealist->eas[i].value; + } + return NT_STATUS_OK; +} /* approximately map a struct pvfs_filename to a generic fileinfo struct */ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, - struct pvfs_filename *name, union smb_fileinfo *info) + struct pvfs_filename *name, union smb_fileinfo *info, + int fd) { switch (info->generic.level) { case RAW_FILEINFO_GENERIC: @@ -61,9 +90,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; case RAW_FILEINFO_ALL_EAS: - info->all_eas.out.num_eas = 0; - info->all_eas.out.eas = NULL; - return NT_STATUS_OK; + return pvfs_query_all_eas(pvfs, mem_ctx, name, fd, &info->all_eas.out); case RAW_FILEINFO_IS_NAME_VALID: return NT_STATUS_OK; @@ -202,7 +229,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = pvfs_map_fileinfo(pvfs, req, name, info); + status = pvfs_map_fileinfo(pvfs, req, name, info, -1); return status; } @@ -228,7 +255,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_map_fileinfo(pvfs, req, f->name, info); + status = pvfs_map_fileinfo(pvfs, req, f->name, info, f->fd); /* a qfileinfo can fill in a bit more info than a qpathinfo - now modify the levels that need to be fixed up */ diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index fe489c2e69..e570743aba 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -23,6 +23,62 @@ #include "includes.h" #include "vfs_posix.h" #include "system/time.h" +#include "librpc/gen_ndr/ndr_xattr.h" + + +/* + add a single DOS EA +*/ +static NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, + struct pvfs_filename *name, + int fd, struct ea_struct *ea) +{ + struct xattr_DosEAs *ealist = talloc_p(pvfs, struct xattr_DosEAs); + int i; + NTSTATUS status; + + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_NOT_SUPPORTED; + } + + /* load the current list */ + status = pvfs_doseas_load(pvfs, name, fd, ealist); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* see if its already there */ + for (i=0;inum_eas;i++) { + if (StrCaseCmp(ealist->eas[i].name, ea->name.s) == 0) { + ealist->eas[i].value = ea->value; + goto save; + } + } + + /* add it */ + ealist->eas = talloc_realloc_p(ealist, ealist->eas, struct xattr_EA, ealist->num_eas+1); + if (ealist->eas == NULL) { + return NT_STATUS_NO_MEMORY; + } + ealist->eas[i].name = ea->name.s; + ealist->eas[i].value = ea->value; + ealist->num_eas++; + +save: + status = pvfs_doseas_save(pvfs, name, fd, ealist); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + name->dos.ea_size = 4; + for (i=0;inum_eas;i++) { + name->dos.ea_size += 4 + strlen(ealist->eas[i].name)+1 + + ealist->eas[i].value.length; + } + + /* update the ea_size attrib */ + return pvfs_dosattrib_save(pvfs, name, fd); +} /* set info on a open file @@ -77,6 +133,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } break; + case RAW_SFILEINFO_EA_SET: + return pvfs_setfileinfo_ea_set(pvfs, f->name, f->fd, &info->ea_set.in.ea); + case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: if (info->basic_info.in.create_time) { @@ -165,13 +224,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, *f->name = newstats; -#if HAVE_XATTR_SUPPORT - if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { - return pvfs_xattr_save(pvfs, f->name, f->fd); - } -#endif - - return NT_STATUS_OK; + return pvfs_dosattrib_save(pvfs, f->name, f->fd); } @@ -227,6 +280,9 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } break; + case RAW_SFILEINFO_EA_SET: + return pvfs_setfileinfo_ea_set(pvfs, name, -1, &info->ea_set.in.ea); + case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: if (info->basic_info.in.create_time) { @@ -296,12 +352,6 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, *name = newstats; -#if HAVE_XATTR_SUPPORT - if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { - return pvfs_xattr_save(pvfs, name, -1); - } -#endif - - return NT_STATUS_OK; + return pvfs_dosattrib_save(pvfs, name, -1); } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 24fa49108a..e086a019ba 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -25,7 +25,6 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" - /* pull a xattr as a blob, from either a file or a file descriptor */ @@ -36,6 +35,7 @@ static NTSTATUS pull_xattr_blob(TALLOC_CTX *mem_ctx, size_t estimated_size, DATA_BLOB *blob) { +#if HAVE_XATTR_SUPPORT int ret; *blob = data_blob_talloc(mem_ctx, NULL, estimated_size); @@ -67,17 +67,20 @@ again: blob->length = ret; return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif } /* push a xattr as a blob, from either a file or a file descriptor */ -static NTSTATUS push_xattr_blob(TALLOC_CTX *mem_ctx, - const char *attr_name, +static NTSTATUS push_xattr_blob(const char *attr_name, const char *fname, int fd, const DATA_BLOB *blob) { +#if HAVE_XATTR_SUPPORT int ret; if (fd != -1) { @@ -90,22 +93,74 @@ static NTSTATUS push_xattr_blob(TALLOC_CTX *mem_ctx, } return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif } +/* + load a NDR structure from a xattr +*/ +static NTSTATUS pvfs_xattr_ndr_load(TALLOC_CTX *mem_ctx, + const char *fname, int fd, const char *attr_name, + void *p, ndr_pull_flags_fn_t pull_fn) +{ + NTSTATUS status; + DATA_BLOB blob; + + status = pull_xattr_blob(mem_ctx, attr_name, fname, + fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* pull the blob */ + status = ndr_pull_struct_blob(&blob, mem_ctx, p, pull_fn); + + data_blob_free(&blob); + + return status; +} /* - fill in file attributes from extended attributes + save a NDR structure into a xattr */ -NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +static NTSTATUS pvfs_xattr_ndr_save(const char *fname, int fd, const char *attr_name, + void *p, ndr_push_flags_fn_t push_fn) { + TALLOC_CTX *mem_ctx = talloc(NULL, 0); DATA_BLOB blob; NTSTATUS status; + + status = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + status = push_xattr_blob(attr_name, fname, fd, &blob); + talloc_free(mem_ctx); + + return status; +} + + +/* + fill in file attributes from extended attributes +*/ +NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +{ + NTSTATUS status; struct xattr_DosAttrib attrib; TALLOC_CTX *mem_ctx = talloc(name, 0); struct xattr_DosInfo1 *info1; - status = pull_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, - fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob); + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + + status = pvfs_xattr_ndr_load(mem_ctx, name->full_name, fd, XATTR_DOSATTRIB_NAME, + &attrib, (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); /* if the filesystem doesn't support them, then tell pvfs not to try again */ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { @@ -126,14 +181,6 @@ NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, in return status; } - /* pull the blob */ - status = ndr_pull_struct_blob(&blob, mem_ctx, &attrib, - (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return status; - } - switch (attrib.version) { case 1: info1 = &attrib.info.info1; @@ -163,15 +210,16 @@ NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, struct pvfs_filename *name, in /* - save the file attribute into into the xattr + save the file attribute into the xattr */ -NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) { struct xattr_DosAttrib attrib; struct xattr_DosInfo1 *info1; - TALLOC_CTX *mem_ctx = talloc(name, 0); - DATA_BLOB blob; - NTSTATUS status; + + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } attrib.version = 1; info1 = &attrib.info.info1; @@ -183,15 +231,39 @@ NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, struct pvfs_filename *name, in info1->create_time = name->dos.create_time; info1->change_time = name->dos.change_time; - status = ndr_push_struct_blob(&blob, mem_ctx, &attrib, - (ndr_push_flags_fn_t)ndr_push_xattr_DosAttrib); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return status; - } + return pvfs_xattr_ndr_save(name->full_name, fd, XATTR_DOSATTRIB_NAME, &attrib, + (ndr_push_flags_fn_t)ndr_push_xattr_DosAttrib); +} - status = push_xattr_blob(mem_ctx, XATTR_DOSATTRIB_NAME, name->full_name, fd, &blob); - talloc_free(mem_ctx); +/* + load the set of DOS EAs +*/ +NTSTATUS pvfs_doseas_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosEAs *eas) +{ + NTSTATUS status; + ZERO_STRUCTP(eas); + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + status = pvfs_xattr_ndr_load(eas, name->full_name, fd, XATTR_DOSEAS_NAME, + eas, (ndr_pull_flags_fn_t)ndr_pull_xattr_DosEAs); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + return NT_STATUS_OK; + } return status; } + +/* + save the set of DOS EAs +*/ +NTSTATUS pvfs_doseas_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosEAs *eas) +{ + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + return pvfs_xattr_ndr_save(name->full_name, fd, XATTR_DOSEAS_NAME, eas, + (ndr_push_flags_fn_t)ndr_push_xattr_DosEAs); +} -- cgit From d8ddb03e906d47a9b75238a2848d860228ab35a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 5 Nov 2004 11:49:37 +0000 Subject: r3550: fixed initial attribute on file create (inlusion of FILE_ATTRIBUTE_ARCHIVE) (This used to be commit b07feaafd16e42e84ba51004a6a9d4a3cb8f9a37) --- source4/ntvfs/posix/pvfs_open.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index d640bae279..2430f9becb 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -284,6 +284,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t share_access = io->generic.in.share_access; uint32_t access_mask = io->generic.in.access_mask; mode_t mode; + uint32_t attrib; if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { @@ -313,7 +314,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } - mode = pvfs_fileperms(pvfs, io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE); + attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE; + mode = pvfs_fileperms(pvfs, attrib); /* create the file */ fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode); @@ -330,7 +332,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } - name->dos.attrib = io->ntcreatex.in.file_attr; + name->dos.attrib = attrib; status = pvfs_dosattrib_save(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, fnum); -- cgit From 439c1524fba3b58abe9e353f9ff2bd7f103f3d12 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 6 Nov 2004 07:58:45 +0000 Subject: r3573: added trans2open support to smbd and pvfs, and fine-tuned the open->generic ntvfs mapping code. (This used to be commit ed844192d7f7ed487290f719df65f256a5b0b9bc) --- source4/ntvfs/ntvfs_generic.c | 49 ++++++++++++++++++++++++++++------ source4/ntvfs/posix/pvfs_open.c | 37 +++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 8 +++++- 3 files changed, 85 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index ed41b3d4d2..370463c41d 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -149,6 +149,13 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, union smb_setfileinfo *sf; uint_t state; + /* this is really strange, but matches w2k3 */ + if (io->generic.level == RAW_OPEN_T2OPEN && + io->t2open.in.open_func != OPENX_OPEN_FUNC_OPEN && + NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + return NT_STATUS_ACCESS_DENIED; + } + if (!NT_STATUS_IS_OK(status)) { return status; } @@ -159,7 +166,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->openold.out.attrib = io2->generic.out.attrib; io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openold.out.size = io2->generic.out.size; - io->openold.out.rmode = DOS_OPEN_RDWR; + io->openold.out.rmode = io->openold.in.flags; break; case RAW_OPEN_OPENX: @@ -181,6 +188,18 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, } break; + case RAW_OPEN_T2OPEN: + io->t2open.out.fnum = io2->openx.out.fnum; + io->t2open.out.attrib = io2->openx.out.attrib; + io->t2open.out.write_time = 0; + io->t2open.out.size = io2->openx.out.size; + io->t2open.out.access = io->t2open.in.open_mode; + io->t2open.out.ftype = io2->openx.out.ftype; + io->t2open.out.devstate = io2->openx.out.devstate; + io->t2open.out.action = io2->openx.out.action; + io->t2open.out.unknown = 0; + break; + case RAW_OPEN_MKNEW: case RAW_OPEN_CREATE: io->mknew.out.fnum = io2->generic.out.fnum; @@ -191,7 +210,6 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->ctemp.out.fnum = io2->generic.out.fnum; io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + strlen(io->ctemp.in.directory) + 1); - write_time = io->ctemp.in.write_time; break; default: @@ -217,7 +235,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, sf = talloc_p(req, union smb_setfileinfo); sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; sf->generic.file.fnum = io2->generic.out.fnum; - sf->end_of_file_info.in.size = io->openx.in.size; + sf->end_of_file_info.in.size = set_size; status = ntvfs->ops->setfileinfo(ntvfs, req, sf); if (NT_STATUS_IS_OK(status)) { io->openx.out.size = io->openx.in.size; @@ -262,17 +280,17 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { case OPENX_MODE_ACCESS_READ: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io2->generic.in.access_mask = STANDARD_RIGHTS_READ_ACCESS; io->openx.out.access = OPENX_MODE_ACCESS_READ; break; case OPENX_MODE_ACCESS_WRITE: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = STANDARD_RIGHTS_WRITE_ACCESS; io->openx.out.access = OPENX_MODE_ACCESS_WRITE; break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: case OPENX_MODE_ACCESS_EXEC: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = STANDARD_RIGHTS_ALL_ACCESS; io->openx.out.access = OPENX_MODE_ACCESS_RDWR; break; default: @@ -402,8 +420,10 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE; break; - case 0x70: /* FCB mode */ - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + case OPEN_FLAGS_DENY_MASK: + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ| + NTCREATEX_SHARE_ACCESS_WRITE; break; default: DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", @@ -415,6 +435,19 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, status = ntvfs->ops->openfile(ntvfs, req, io2); break; + case RAW_OPEN_T2OPEN: + io2->generic.level = RAW_OPEN_OPENX; + io2->openx.in.flags = io->t2open.in.flags; + io2->openx.in.open_mode = io->t2open.in.open_mode; + io2->openx.in.search_attrs = 0; + io2->openx.in.file_attrs = io->t2open.in.file_attrs; + io2->openx.in.write_time = io->t2open.in.write_time; + io2->openx.in.open_func = OPENX_OPEN_FUNC_OPEN; + io2->openx.in.size = io->t2open.in.size; + io2->openx.in.timeout = io->t2open.in.timeout; + io2->openx.in.fname = io->t2open.in.fname; + status = ntvfs->ops->openfile(ntvfs, req, io2); + break; case RAW_OPEN_MKNEW: io2->generic.in.file_attr = io->mknew.in.attrib; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 2430f9becb..6f1fb1c87f 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -538,6 +538,39 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + special handling for t2open +*/ +static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_filename *name; + NTSTATUS status; + + status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, + PVFS_RESOLVE_NO_WILDCARD, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (io->t2open.in.open_func & OPENX_OPEN_FUNC_CREATE) { + if (!name->exists) return NT_STATUS_ACCESS_DENIED; + } + if (io->t2open.in.open_func & OPENX_OPEN_FUNC_TRUNC) { + if (name->exists) return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + if ((io->t2open.in.open_func & 0xF) == OPENX_OPEN_FUNC_FAIL) { + if (!name->exists) return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + talloc_free(name); + + return ntvfs_map_open(req, io, ntvfs); +} + /* open a file */ @@ -555,6 +588,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t share_access; uint32_t access_mask; + if (io->generic.level == RAW_OPEN_T2OPEN) { + return pvfs_open_t2open(ntvfs, req, io); + } + /* use the generic mapping code to avoid implementing all the different open calls. This won't allow openx to work perfectly as the mapping code has no way of knowing if two diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index e570743aba..22997be94d 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -188,10 +188,16 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file size */ if (newstats.st.st_size != f->name->st.st_size) { + int ret; if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (ftruncate(f->fd, newstats.st.st_size) == -1) { + if (f->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + ret = ftruncate(f->fd, newstats.st.st_size); + } else { + ret = truncate(f->name->full_name, newstats.st.st_size); + } + if (ret == -1) { return pvfs_map_errno(pvfs, errno); } } -- cgit From a9158e0d47636e25ce374391cd9b02df3d27b390 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 6 Nov 2004 09:12:53 +0000 Subject: r3574: the RAW-OPEN test changes broke a couple of the other tests. This fixes most of them, although RAW-SEARCH still fails (due to an interaction with the new xattr code) (This used to be commit 09b4652b40c4cfca027765178bd5a0adbaa666c2) --- source4/ntvfs/ntvfs_generic.c | 21 +++++++++++++-------- source4/ntvfs/posix/pvfs_open.c | 27 ++++++++++++++++++++++++++- source4/ntvfs/posix/pvfs_rename.c | 2 +- 3 files changed, 40 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 370463c41d..9ef2481d26 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -178,7 +178,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->openx.out.devstate = 0; io->openx.out.action = io2->generic.out.create_action; io->openx.out.unique_fid = 0; - io->openx.out.access_mask = io2->generic.in.access_mask; + io->openx.out.access_mask = STANDARD_RIGHTS_ALL_ACCESS; io->openx.out.unknown = 0; /* we need to extend the file to the requested size if @@ -280,17 +280,17 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { case OPENX_MODE_ACCESS_READ: - io2->generic.in.access_mask = STANDARD_RIGHTS_READ_ACCESS; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; io->openx.out.access = OPENX_MODE_ACCESS_READ; break; case OPENX_MODE_ACCESS_WRITE: - io2->generic.in.access_mask = STANDARD_RIGHTS_WRITE_ACCESS; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; io->openx.out.access = OPENX_MODE_ACCESS_WRITE; break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: case OPENX_MODE_ACCESS_EXEC: - io2->generic.in.access_mask = STANDARD_RIGHTS_ALL_ACCESS; + io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE | GENERIC_RIGHTS_FILE_READ; io->openx.out.access = OPENX_MODE_ACCESS_RDWR; break; default: @@ -309,12 +309,16 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; case OPENX_MODE_DENY_NONE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; break; case OPENX_MODE_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ if (is_exe_file(io->openx.in.fname)) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; } else { if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == OPENX_MODE_ACCESS_READ) { @@ -417,8 +421,9 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; break; case OPEN_FLAGS_DENY_NONE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE | - NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE; + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_READ; break; case OPEN_FLAGS_DENY_MASK: io2->generic.in.share_access = diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 6f1fb1c87f..f0c1478e66 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -944,7 +944,32 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, struct pvfs_filename *name) NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE, - 0, STD_RIGHT_DELETE_ACCESS); + NTCREATEX_OPTIONS_DELETE_ON_CLOSE, + STD_RIGHT_DELETE_ACCESS); + + return status; +} + +/* + determine if a file can be renamed, or if it is prevented by an + already open file +*/ +NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, struct pvfs_filename *name) +{ + NTSTATUS status; + DATA_BLOB key; + + status = pvfs_locking_key(name, name, &key); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_NO_MEMORY; + } + + status = odb_can_open(pvfs->odb_context, &key, + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE, + 0, + STD_RIGHT_DELETE_ACCESS); return status; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 552148a891..a621165ce4 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -62,7 +62,7 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_can_delete(pvfs, name1); + status = pvfs_can_rename(pvfs, name1); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From b5acd1963a43b91036351506a415081601fd1ba6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 6 Nov 2004 09:34:17 +0000 Subject: r3575: fixed attribute normalisation in xattr code. RAW-SEARCH now passes again. (This used to be commit 66bdc6e78c2c7ce4e215919959f0d0623ef06723) --- source4/ntvfs/posix/pvfs_util.c | 16 ++++++++++++++++ source4/ntvfs/posix/pvfs_xattr.c | 4 +++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 50a78c2965..92d696970a 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -63,3 +63,19 @@ NTSTATUS pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, } return NT_STATUS_OK; } + + +/* + normalise a file attribute +*/ +uint32_t pvfs_attrib_normalise(uint32_t attrib) +{ + if (attrib == 0) { + attrib = FILE_ATTRIBUTE_NORMAL; + } + if (attrib != FILE_ATTRIBUTE_NORMAL) { + attrib &= ~FILE_ATTRIBUTE_NORMAL; + } + return attrib; +} + diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index e086a019ba..f4063b48b5 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -184,7 +184,7 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name switch (attrib.version) { case 1: info1 = &attrib.info.info1; - name->dos.attrib = info1->attrib; + name->dos.attrib = pvfs_attrib_normalise(info1->attrib); name->dos.ea_size = info1->ea_size; if (name->st.st_size == info1->size) { name->dos.alloc_size = info1->alloc_size; @@ -224,6 +224,8 @@ NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name attrib.version = 1; info1 = &attrib.info.info1; + name->dos.attrib = pvfs_attrib_normalise(name->dos.attrib); + info1->attrib = name->dos.attrib; info1->ea_size = name->dos.ea_size; info1->size = name->st.st_size; -- cgit From f45846084249540f3dee24fe92cfaab2974461cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 6 Nov 2004 12:35:31 +0000 Subject: r3580: - on file overwrite in ntcreatex we need to replace the file permissions. - pvfs now passes BASE-OPENATTR - pvfs also passes the BASE-DEFER_OPEN test, but it is not a well formed test for regular running so I am removing it from the list of tests to run in test_posix.sh (the test is covered better by RAW-MUX anyway) (This used to be commit cb76bd218ed4194ea151264d495aa902ddf03b3c) --- source4/ntvfs/posix/pvfs_open.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index f0c1478e66..f30d53d51a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -787,6 +787,22 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + if (io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE || + io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE_IF) { + /* for overwrite we need to replace file permissions */ + uint32_t attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE; + mode_t mode = pvfs_fileperms(pvfs, attrib); + if (fchmod(fd, mode) == -1) { + return map_nt_error_from_unix(errno); + } + name->dos.attrib = attrib; + status = pvfs_dosattrib_save(pvfs, name, fd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + io->generic.out.oplock_level = NO_OPLOCK; io->generic.out.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; -- cgit From 71db46ea665606384f2be1be708c74c97c9adfb2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Nov 2004 23:23:15 +0000 Subject: r3586: Fix some of the issues with the module init functions. Both subsystems and modules can now have init functions, which can be specified in .mk files (INIT_FUNCTION = ...) The build system will define : - SUBSYSTEM_init_static_modules that calls the init functions of all statically compiled modules. Failing to load will generate an error which is not fatal - BINARY_init_subsystems that calls the init functions (if defined) for the subsystems the binary depends on This removes the hack with the "static bool Initialised = " and the "lazy_init" functions (This used to be commit 7a8244761bfdfdfb48f8264d76951ebdfbf7bd8a) --- source4/ntvfs/config.mk | 6 ++++++ source4/ntvfs/ntvfs_base.c | 9 ++++----- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/unixuid/config.mk | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index e2320e0684..c15470076f 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -3,6 +3,7 @@ ################################################ # Start MODULE ntvfs_cifs [MODULE::ntvfs_cifs] +INIT_FUNCTION = ntvfs_cifs_init INIT_OBJ_FILES = \ ntvfs/cifs/vfs_cifs.o REQUIRED_SUBSYSTEMS = \ @@ -13,6 +14,7 @@ REQUIRED_SUBSYSTEMS = \ ################################################ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] +INIT_FUNCTION = ntvfs_simple_init INIT_OBJ_FILES = \ ntvfs/simple/vfs_simple.o ADD_OBJ_FILES = \ @@ -23,6 +25,7 @@ ADD_OBJ_FILES = \ ################################################ # Start MODULE ntvfs_print [MODULE::ntvfs_print] +INIT_FUNCTION = ntvfs_print_init INIT_OBJ_FILES = \ ntvfs/print/vfs_print.o # End MODULE ntvfs_print @@ -31,6 +34,7 @@ INIT_OBJ_FILES = \ ################################################ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] +INIT_FUNCTION = ntvfs_ipc_init INIT_OBJ_FILES = \ ntvfs/ipc/vfs_ipc.o \ ntvfs/ipc/ipc_rap.o \ @@ -43,6 +47,7 @@ INIT_OBJ_FILES = \ ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] +INIT_FUNCTION = ntvfs_nbench_init INIT_OBJ_FILES = \ ntvfs/nbench/vfs_nbench.o # End MODULE ntvfs_nbench @@ -51,6 +56,7 @@ INIT_OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::NTVFS] +INIT_FUNCTION = ntvfs_init INIT_OBJ_FILES = \ ntvfs/ntvfs_base.o ADD_OBJ_FILES = \ diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index cc83b53473..c168467eae 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -119,20 +119,19 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) /* initialise the NTVFS subsystem */ -BOOL ntvfs_init(void) +NTSTATUS ntvfs_init(void) { NTSTATUS status; status = register_subsystem("ntvfs", ntvfs_register); if (!NT_STATUS_IS_OK(status)) { - return False; + return status; } - /* FIXME: Perhaps panic if a basic backend, such as IPC, fails to initialise? */ - static_init_ntvfs; + ntvfs_init_static_modules; DEBUG(3,("NTVFS subsystem version %d initialised\n", NTVFS_INTERFACE_VERSION)); - return True; + return status; } diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index dd72468216..f54d2e24fb 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,6 +1,7 @@ ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] +INIT_FUNCTION = ntvfs_posix_init INIT_OBJ_FILES = \ ntvfs/posix/vfs_posix.o ADD_OBJ_FILES = \ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 76e7aebc76..611be650d1 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -1,6 +1,7 @@ ################################################ # Start MODULE ntvfs_unixuid [MODULE::ntvfs_unixuid] +INIT_FUNCTION = ntvfs_unixuid_init INIT_OBJ_FILES = \ ntvfs/unixuid/vfs_unixuid.o # End MODULE ntvfs_unixuid -- cgit From 2db915e06564b42bf7ebfa526b1af2e42e591590 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 7 Nov 2004 10:05:35 +0000 Subject: r3595: - fixed a talloc_free ordering problem on cleanup with pending requests - added initial support for MODE_INFORMATION in setfileinfo (I have no idea what "mode information" on a file is - it takes a value of 0, 2, 4 or 6. What could it be?) (This used to be commit e53ec2f6b68e1d19149c36ea8fcd25a204db38fb) --- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 10 ++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 31 +++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_wait.c | 6 +----- source4/ntvfs/posix/vfs_posix.h | 3 +++ 5 files changed, 46 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 446ff1f30b..c8fc6c2de3 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -295,7 +295,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, if (lck->lockx.in.timeout != 0 && (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - pending = talloc_p(req, struct pvfs_pending_lock); + pending = talloc_p(f, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index f30d53d51a..1a25f57df1 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -142,6 +142,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->share_access = io->generic.in.share_access; f->seek_offset = 0; f->position = 0; + f->mode = 0; DLIST_ADD(pvfs->open_files, f); @@ -362,6 +363,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } status = odb_open_file(lck, fnum, share_access, create_options, access_mask); + talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { /* bad news, we must have hit a race */ idr_remove(pvfs->idtree_fnum, fnum); @@ -382,6 +384,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->access_mask = access_mask; f->seek_offset = 0; f->position = 0; + f->mode = 0; f->have_opendb_entry = True; DLIST_ADD(pvfs->open_files, f); @@ -433,6 +436,7 @@ static int pvfs_retry_destructor(void *ptr) if (lck != NULL) { odb_remove_pending(lck, r); } + talloc_free(lck); } return 0; } @@ -768,6 +772,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); return status; } @@ -776,6 +781,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* do the actual open */ fd = open(f->name->full_name, flags); if (fd == -1) { + talloc_free(lck); return pvfs_map_errno(f->pvfs, errno); } @@ -784,6 +790,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* re-resolve the open fd */ status = pvfs_resolve_name_fd(f->pvfs, fd, f->name); if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); return status; } @@ -793,15 +800,18 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE; mode_t mode = pvfs_fileperms(pvfs, attrib); if (fchmod(fd, mode) == -1) { + talloc_free(lck); return map_nt_error_from_unix(errno); } name->dos.attrib = attrib; status = pvfs_dosattrib_save(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); return status; } } + talloc_free(lck); io->generic.out.oplock_level = NO_OPLOCK; io->generic.out.fnum = f->fnum; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 22997be94d..15b7f168f2 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -171,6 +171,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: newstats.dos.alloc_size = info->allocation_info.in.alloc_size; + if (newstats.dos.alloc_size < newstats.st.st_size) { + newstats.st.st_size = newstats.dos.alloc_size; + } break; case RAW_SFILEINFO_END_OF_FILE_INFO: @@ -182,6 +185,17 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, f->position = info->position_information.in.position; break; + case RAW_SFILEINFO_MODE_INFORMATION: + /* this one is a puzzle */ + if (info->mode_information.in.mode != 0 && + info->mode_information.in.mode != 2 && + info->mode_information.in.mode != 4 && + info->mode_information.in.mode != 6) { + return NT_STATUS_INVALID_PARAMETER; + } + f->mode = info->mode_information.in.mode; + break; + default: return NT_STATUS_INVALID_LEVEL; } @@ -310,7 +324,15 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: + if (info->allocation_info.in.alloc_size > newstats.dos.alloc_size) { + /* strange. Increasing the allocation size via setpathinfo + should be silently ignored */ + break; + } newstats.dos.alloc_size = info->allocation_info.in.alloc_size; + if (newstats.dos.alloc_size < newstats.st.st_size) { + newstats.st.st_size = newstats.dos.alloc_size; + } break; case RAW_SFILEINFO_END_OF_FILE_INFO: @@ -318,6 +340,15 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, newstats.st.st_size = info->end_of_file_info.in.size; break; + case RAW_SFILEINFO_MODE_INFORMATION: + if (info->mode_information.in.mode != 0 && + info->mode_information.in.mode != 2 && + info->mode_information.in.mode != 4 && + info->mode_information.in.mode != 6) { + return NT_STATUS_INVALID_PARAMETER; + } + return NT_STATUS_OK; + case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: case RAW_SFILEINFO_POSITION_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index a226918877..968f659421 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -137,7 +137,7 @@ static int pvfs_wait_destructor(void *ptr) pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging_ctx; pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; - pwait->req = req; + pwait->req = talloc_reference(pwait, req); pwait->pvfs = pvfs; /* setup a timer */ @@ -162,10 +162,6 @@ static int pvfs_wait_destructor(void *ptr) /* make sure we cleanup the timer and message handler */ talloc_set_destructor(pwait, pvfs_wait_destructor); - /* make sure that on a disconnect the request is not destroyed - before pvfs */ - talloc_steal(pvfs, req); - return pwait; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 64b9a0d653..91940e6355 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -116,6 +116,9 @@ struct pvfs_file { uint32_t share_access; uint32_t access_mask; + /* this is set by the mode_information level. What does it do? */ + uint32_t mode; + /* yes, we need 2 independent positions ... */ uint64_t seek_offset; uint64_t position; -- cgit From 8e7f33e93df9557228d17a50b83b7abd9c8fdd43 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 7 Nov 2004 10:09:50 +0000 Subject: r3596: MODE_INFORMATION tests now pass. Only RENAME_INFORMATION level left to support RAW-SFILEINFO (This used to be commit 20fc3a25ef775fc366711501ca83914335e8fae1) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 51aadc07a5..5847b1a2cc 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -182,7 +182,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; case RAW_FILEINFO_MODE_INFORMATION: - info->mode_information.out.mode = 0; /* what is this? */ + info->mode_information.out.mode = 0; return NT_STATUS_OK; case RAW_FILEINFO_ALIGNMENT_INFORMATION: @@ -284,6 +284,10 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, info->access_information.out.access_flags = f->access_mask; break; + case RAW_FILEINFO_MODE_INFORMATION: + info->mode_information.out.mode = f->mode; + break; + default: break; } -- cgit From 0c5f2ba38e8e6d27dd35844e8268a9a26e614e06 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 7 Nov 2004 10:20:50 +0000 Subject: r3597: implement a suggestion from abartlet. By taking a refernce to the database in the opendb lck, we ensure that the database is not closed before the lock is gone. That ensures the lock destructor doesn't work on a closed database. (This used to be commit 218e01441aa1def3e8e884c8d618a95c9ffdfc1b) --- source4/ntvfs/common/opendb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index bed4910be4..a1d4ed1ddb 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -130,7 +130,7 @@ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, return NULL; } - lck->odb = odb; + lck->odb = talloc_reference(lck, odb); lck->key.dptr = talloc_memdup(lck, file_key->data, file_key->length); lck->key.dsize = file_key->length; if (lck->key.dptr == NULL) { -- cgit From 19fc6e8f511f028aa40122cc7e40c83908d07ebe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Nov 2004 03:54:12 +0000 Subject: r3615: split out struct pvfs_file_handle from struct pvfs_file. This is in preparation for adding code to pass the BASE-DENY1 and BASE-DENYDOS tests, which require a shared filesystem handle for some specific combinations of two DENY_DOS opens on the same connection. (This used to be commit 6e4fdf01d19051e3923d7703dbf990fc1722b09a) --- source4/ntvfs/common/opendb.c | 35 ++--- source4/ntvfs/posix/pvfs_flush.c | 4 +- source4/ntvfs/posix/pvfs_lock.c | 21 +-- source4/ntvfs/posix/pvfs_open.c | 262 +++++++++++++++++++-------------- source4/ntvfs/posix/pvfs_qfileinfo.c | 16 +- source4/ntvfs/posix/pvfs_read.c | 8 +- source4/ntvfs/posix/pvfs_seek.c | 12 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 93 +++++++++--- source4/ntvfs/posix/pvfs_write.c | 8 +- source4/ntvfs/posix/vfs_posix.c | 1 - source4/ntvfs/posix/vfs_posix.h | 56 ++++--- 11 files changed, 309 insertions(+), 207 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index a1d4ed1ddb..a07b657c33 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -44,7 +44,6 @@ struct odb_context { struct tdb_wrap *w; servid_t server; - uint16_t tid; struct messaging_context *messaging_ctx; }; @@ -54,8 +53,7 @@ struct odb_context { */ struct odb_entry { servid_t server; - uint16_t tid; - uint16_t fnum; + void *file_handle; uint32_t share_access; uint32_t create_options; uint32_t access_mask; @@ -78,7 +76,7 @@ struct odb_lock { talloc_free(). We need the messaging_ctx to allow for pending open notifications. */ -struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, +struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, struct messaging_context *messaging_ctx) { char *path; @@ -100,7 +98,6 @@ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, } odb->server = server; - odb->tid = tid; odb->messaging_ctx = messaging_ctx; return odb; @@ -205,7 +202,7 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) register an open file in the open files database. This implements the share_access rules */ -NTSTATUS odb_open_file(struct odb_lock *lck, uint16_t fnum, +NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, uint32_t share_access, uint32_t create_options, uint32_t access_mask) { @@ -219,8 +216,7 @@ NTSTATUS odb_open_file(struct odb_lock *lck, uint16_t fnum, dbuf = tdb_fetch(odb->w->tdb, lck->key); e.server = odb->server; - e.tid = odb->tid; - e.fnum = fnum; + e.file_handle = file_handle; e.share_access = share_access; e.create_options = create_options; e.access_mask = access_mask; @@ -276,8 +272,7 @@ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) dbuf = tdb_fetch(odb->w->tdb, lck->key); e.server = odb->server; - e.tid = odb->tid; - e.fnum = 0; + e.file_handle = NULL; e.share_access = 0; e.create_options = 0; e.access_mask = 0; @@ -314,7 +309,7 @@ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) /* remove a opendb entry */ -NTSTATUS odb_close_file(struct odb_lock *lck, uint16_t fnum) +NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) { struct odb_context *odb = lck->odb; TDB_DATA dbuf; @@ -344,9 +339,8 @@ NTSTATUS odb_close_file(struct odb_lock *lck, uint16_t fnum) /* find the entry, and delete it */ for (i=0;iserver == elist[i].server && - odb->tid == elist[i].tid) { + if (file_handle == elist[i].file_handle && + odb->server == elist[i].server) { if (i < count-1) { memmove(elist+i, elist+i+1, (count - (i+1)) * sizeof(struct odb_entry)); @@ -399,8 +393,7 @@ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) /* find the entry, and delete it */ for (i=0;iserver == elist[i].server && - odb->tid == elist[i].tid) { + odb->server == elist[i].server) { if (i < count-1) { memmove(elist+i, elist+i+1, (count - (i+1)) * sizeof(struct odb_entry)); @@ -434,7 +427,7 @@ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) update create options on an open file */ NTSTATUS odb_set_create_options(struct odb_lock *lck, - uint16_t fnum, uint32_t create_options) + void *file_handle, uint32_t create_options) { struct odb_context *odb = lck->odb; TDB_DATA dbuf; @@ -452,9 +445,8 @@ NTSTATUS odb_set_create_options(struct odb_lock *lck, /* find the entry, and modify it */ for (i=0;iserver == elist[i].server && - odb->tid == elist[i].tid) { + if (file_handle == elist[i].file_handle && + odb->server == elist[i].server) { elist[i].create_options = create_options; break; } @@ -503,8 +495,7 @@ NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key, } e.server = odb->server; - e.tid = odb->tid; - e.fnum = -1; + e.file_handle = NULL; e.share_access = share_access; e.create_options = create_options; e.access_mask = access_mask; diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 6195d254ff..66a0cc5edf 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -28,11 +28,11 @@ */ static void pvfs_flush_file(struct pvfs_state *pvfs, struct pvfs_file *f) { - if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return; } if (pvfs->flags & PVFS_FLAG_STRICT_SYNC) { - fsync(f->fd); + fsync(f->handle->fd); } } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index c8fc6c2de3..a2691cb550 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -41,7 +41,7 @@ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, } return brl_locktest(pvfs->brl_context, - &f->locking_key, + &f->handle->locking_key, f->fnum, smbpid, offset, count, rw); @@ -73,7 +73,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, /* undo the locks we just did */ for (i=i-1;i>=0;i--) { brl_unlock(pvfs->brl_context, - &f->locking_key, + &f->handle->locking_key, locks[i].pid, f->fnum, locks[i].offset, @@ -118,7 +118,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas DLIST_REMOVE(f->pending_list, pending); status = brl_lock(pvfs->brl_context, - &f->locking_key, + &f->handle->locking_key, req->smbpid, f->fnum, locks[pending->pending_lock].offset, @@ -133,7 +133,8 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas don't need the pending lock any more */ if (NT_STATUS_IS_OK(status) || timed_out) { NTSTATUS status2; - status2 = brl_remove_pending(pvfs->brl_context, &f->locking_key, pending); + status2 = brl_remove_pending(pvfs->brl_context, + &f->handle->locking_key, pending); if (!NT_STATUS_IS_OK(status2)) { DEBUG(0,("pvfs_lock: failed to remove pending lock - %s\n", nt_errstr(status2))); } @@ -170,7 +171,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas } status = brl_lock(pvfs->brl_context, - &f->locking_key, + &f->handle->locking_key, req->smbpid, f->fnum, locks[i].offset, @@ -214,7 +215,7 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) if (f->lock_count || f->pending_list) { DEBUG(5,("pvfs_lock: removing %.0f locks on close\n", (double)f->lock_count)); - brl_close(f->pvfs->brl_context, &f->locking_key, f->fnum); + brl_close(f->pvfs->brl_context, &f->handle->locking_key, f->fnum); f->lock_count = 0; } @@ -289,7 +290,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } @@ -337,7 +338,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, for (i=0;ilockx.in.ulock_cnt;i++) { status = brl_unlock(pvfs->brl_context, - &f->locking_key, + &f->handle->locking_key, locks[i].pid, f->fnum, locks[i].offset, @@ -356,7 +357,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } status = brl_lock(pvfs->brl_context, - &f->locking_key, + &f->handle->locking_key, locks[i].pid, f->fnum, locks[i].offset, @@ -379,7 +380,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, /* undo the locks we just did */ for (i=i-1;i>=0;i--) { brl_unlock(pvfs->brl_context, - &f->locking_key, + &f->handle->locking_key, locks[i].pid, f->fnum, locks[i].offset, diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1a25f57df1..5411f83e8d 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -47,6 +47,10 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, return NULL; } + if (f->fnum != fnum) { + smb_panic("pvfs_find_fd: idtree_fnum corruption\n"); + } + if (req->session != f->session) { DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n", fnum)); @@ -60,22 +64,31 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, /* cleanup a open directory handle */ -static int pvfs_dir_fd_destructor(void *p) +static int pvfs_dir_handle_destructor(void *p) { - struct pvfs_file *f = p; - DLIST_REMOVE(f->pvfs->open_files, f); - idr_remove(f->pvfs->idtree_fnum, f->fnum); + struct pvfs_file_handle *h = p; - if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { - if (rmdir(f->name->full_name) != 0) { + if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (rmdir(h->name->full_name) != 0) { DEBUG(0,("pvfs_close: failed to rmdir '%s' - %s\n", - f->name->full_name, strerror(errno))); + h->name->full_name, strerror(errno))); } } return 0; } +/* + cleanup a open directory fnum +*/ +static int pvfs_dir_fnum_destructor(void *p) +{ + struct pvfs_file *f = p; + DLIST_REMOVE(f->pvfs->open_files, f); + idr_remove(f->pvfs->idtree_fnum, f->fnum); + return 0; +} + /* open a directory @@ -124,34 +137,41 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } + f->handle = talloc_p(f, struct pvfs_file_handle); + if (f->handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } - f->fnum = fnum; - f->fd = -1; - f->name = talloc_steal(f, name); - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; + f->fnum = fnum; + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; f->pending_list = NULL; - f->lock_count = 0; - f->locking_key = data_blob(NULL, 0); - f->create_options = io->generic.in.create_options; - f->share_access = io->generic.in.share_access; - f->seek_offset = 0; - f->position = 0; - f->mode = 0; + f->lock_count = 0; + + f->handle->pvfs = pvfs; + f->handle->name = talloc_steal(f->handle, name); + f->handle->fd = -1; + f->handle->locking_key = data_blob(NULL, 0); + f->handle->create_options = io->generic.in.create_options; + f->handle->share_access = io->generic.in.share_access; + f->handle->seek_offset = 0; + f->handle->position = 0; + f->handle->mode = 0; DLIST_ADD(pvfs->open_files, f); /* TODO: should we check in the opendb? Do directory opens follow the share_access rules? */ - - /* setup a destructor to avoid leaks on abnormal termination */ - talloc_set_destructor(f, pvfs_dir_fd_destructor); + /* setup destructors to avoid leaks on abnormal termination */ + talloc_set_destructor(f->handle, pvfs_dir_handle_destructor); + talloc_set_destructor(f, pvfs_dir_fnum_destructor); if (!name->exists) { uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY; @@ -193,51 +213,61 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_OK; } - /* - by using a destructor we make sure that abnormal cleanup will not - leak file descriptors (assuming at least the top level pointer is freed, which - will cascade down to here) + destroy a struct pvfs_file_handle */ -static int pvfs_fd_destructor(void *p) +static int pvfs_handle_destructor(void *p) { - struct pvfs_file *f = p; - struct odb_lock *lck; - NTSTATUS status; - - DLIST_REMOVE(f->pvfs->open_files, f); - - pvfs_lock_close(f->pvfs, f); + struct pvfs_file_handle *h = p; - if (f->fd != -1) { - close(f->fd); - f->fd = -1; + if (h->fd != -1) { + if (close(h->fd) != 0) { + DEBUG(0,("pvfs_handle_destructor: close(%d) failed for %s - %s\n", + h->fd, h->name->full_name, strerror(errno))); + } + h->fd = -1; } - idr_remove(f->pvfs->idtree_fnum, f->fnum); - - if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { - if (unlink(f->name->full_name) != 0) { + if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (unlink(h->name->full_name) != 0) { DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", - f->name->full_name, strerror(errno))); + h->name->full_name, strerror(errno))); } } - lck = odb_lock(f, f->pvfs->odb_context, &f->locking_key); - if (lck == NULL) { - DEBUG(0,("Unable to lock opendb for close\n")); - return 0; - } + if (h->have_opendb_entry) { + struct odb_lock *lck; + NTSTATUS status; - if (f->have_opendb_entry) { - status = odb_close_file(lck, f->fnum); + lck = odb_lock(h, h->pvfs->odb_context, &h->locking_key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for close\n")); + return 0; + } + + status = odb_close_file(lck, h); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", - f->name->full_name, nt_errstr(status))); + h->name->full_name, nt_errstr(status))); } + + talloc_free(lck); } - talloc_free(lck); + return 0; +} + + +/* + destroy a struct pvfs_file +*/ +static int pvfs_fnum_destructor(void *p) +{ + struct pvfs_file *f = p; + + DLIST_REMOVE(f->pvfs->open_files, f); + pvfs_lock_close(f->pvfs, f); + idr_remove(f->pvfs->idtree_fnum, f->fnum); return 0; } @@ -310,6 +340,11 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } + f->handle = talloc_p(f, struct pvfs_file_handle); + if (f->handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_NEW_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; @@ -343,7 +378,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* form the lock context used for byte range locking and opendb locking */ - status = pvfs_locking_key(name, f, &f->locking_key); + status = pvfs_locking_key(name, f->handle, &f->handle->locking_key); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, fnum); close(fd); @@ -351,7 +386,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } /* grab a lock on the open file record */ - lck = odb_lock(req, pvfs->odb_context, &f->locking_key); + lck = odb_lock(req, pvfs->odb_context, &f->handle->locking_key); if (lck == NULL) { DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", name->full_name)); @@ -362,7 +397,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_open_file(lck, fnum, share_access, create_options, access_mask); + status = odb_open_file(lck, f->handle, + share_access, create_options, access_mask); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { /* bad news, we must have hit a race */ @@ -372,26 +408,29 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } f->fnum = fnum; - f->fd = fd; - f->name = talloc_steal(f, name); f->session = req->session; f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; f->lock_count = 0; - f->create_options = io->generic.in.create_options; - f->share_access = io->generic.in.share_access; - f->access_mask = access_mask; - f->seek_offset = 0; - f->position = 0; - f->mode = 0; - f->have_opendb_entry = True; + + f->handle->pvfs = pvfs; + f->handle->name = talloc_steal(f->handle, name); + f->handle->fd = fd; + f->handle->create_options = io->generic.in.create_options; + f->handle->share_access = io->generic.in.share_access; + f->handle->access_mask = access_mask; + f->handle->seek_offset = 0; + f->handle->position = 0; + f->handle->mode = 0; + f->handle->have_opendb_entry = True; DLIST_ADD(pvfs->open_files, f); /* setup a destructor to avoid file descriptor leaks on abnormal termination */ - talloc_set_destructor(f, pvfs_fd_destructor); + talloc_set_destructor(f, pvfs_fnum_destructor); + talloc_set_destructor(f->handle, pvfs_handle_destructor); io->generic.out.oplock_level = NO_OPLOCK; io->generic.out.fnum = f->fnum; @@ -518,7 +557,9 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, r->ntvfs = ntvfs; r->req = req; r->io = io; - r->locking_key = data_blob_talloc(r, f->locking_key.data, f->locking_key.length); + r->locking_key = data_blob_talloc(r, + f->handle->locking_key.data, + f->handle->locking_key.length); end_time = timeval_add(&req->request_time, 0, pvfs->sharing_violation_delay); @@ -714,37 +755,44 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } + f->handle = talloc_p(f, struct pvfs_file_handle); + if (f->handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + /* allocate a fnum */ fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_FILE_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } - f->fnum = fnum; - f->fd = -1; - f->name = talloc_steal(f, name); - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; + f->fnum = fnum; + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; f->pending_list = NULL; - f->lock_count = 0; - f->create_options = io->generic.in.create_options; - f->share_access = io->generic.in.share_access; - f->access_mask = access_mask; - f->seek_offset = 0; - f->position = 0; - f->have_opendb_entry = False; + f->lock_count = 0; + + f->handle->pvfs = pvfs; + f->handle->fd = -1; + f->handle->name = talloc_steal(f->handle, name); + f->handle->create_options = io->generic.in.create_options; + f->handle->share_access = io->generic.in.share_access; + f->handle->access_mask = access_mask; + f->handle->seek_offset = 0; + f->handle->position = 0; + f->handle->have_opendb_entry = False; /* form the lock context used for byte range locking and opendb locking */ - status = pvfs_locking_key(name, f, &f->locking_key); + status = pvfs_locking_key(name, f->handle, &f->handle->locking_key); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, f->fnum); return status; } /* get a lock on this file before the actual open */ - lck = odb_lock(req, pvfs->odb_context, &f->locking_key); + lck = odb_lock(req, pvfs->odb_context, &f->handle->locking_key); if (lck == NULL) { DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", name->full_name)); @@ -758,11 +806,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* setup a destructor to avoid file descriptor leaks on abnormal termination */ - talloc_set_destructor(f, pvfs_fd_destructor); + talloc_set_destructor(f, pvfs_fnum_destructor); + talloc_set_destructor(f->handle, pvfs_handle_destructor); /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, f->fnum, share_access, create_options, access_mask); + status = odb_open_file(lck, f->handle, + share_access, create_options, access_mask); /* on a sharing violation we need to retry when the file is closed by the other user, or after 1 second */ @@ -776,19 +826,19 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } - f->have_opendb_entry = True; + f->handle->have_opendb_entry = True; /* do the actual open */ - fd = open(f->name->full_name, flags); + fd = open(f->handle->name->full_name, flags); if (fd == -1) { talloc_free(lck); return pvfs_map_errno(f->pvfs, errno); } - f->fd = fd; + f->handle->fd = fd; /* re-resolve the open fd */ - status = pvfs_resolve_name_fd(f->pvfs, fd, f->name); + status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); return status; @@ -816,13 +866,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, io->generic.out.oplock_level = NO_OPLOCK; io->generic.out.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; - io->generic.out.create_time = f->name->dos.create_time; - io->generic.out.access_time = f->name->dos.access_time; - io->generic.out.write_time = f->name->dos.write_time; - io->generic.out.change_time = f->name->dos.change_time; - io->generic.out.attrib = f->name->dos.attrib; - io->generic.out.alloc_size = f->name->dos.alloc_size; - io->generic.out.size = f->name->st.st_size; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; io->generic.out.file_type = FILE_TYPE_DISK; io->generic.out.ipc_state = 0; io->generic.out.is_directory = 0; @@ -842,7 +892,6 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - NTSTATUS status; struct utimbuf unix_times; if (io->generic.level == RAW_CLOSE_SPLCLOSE) { @@ -861,21 +910,12 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, if (!null_time(io->close.in.write_time)) { unix_times.actime = 0; unix_times.modtime = io->close.in.write_time; - utime(f->name->full_name, &unix_times); + utime(f->handle->name->full_name, &unix_times); } - if (f->fd != -1 && - close(f->fd) == -1) { - status = pvfs_map_errno(pvfs, errno); - } else { - status = NT_STATUS_OK; - } - f->fd = -1; - - /* the destructor takes care of the rest */ talloc_free(f); - return status; + return NT_STATUS_OK; } @@ -929,23 +969,23 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, struct odb_lock *lck; NTSTATUS status; - if (f->create_options == create_options) { + if (f->handle->create_options == create_options) { return NT_STATUS_OK; } - if ((f->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && + if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return NT_STATUS_CANNOT_DELETE; } - lck = odb_lock(req, pvfs->odb_context, &f->locking_key); + lck = odb_lock(req, pvfs->odb_context, &f->handle->locking_key); if (lck == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_set_create_options(lck, f->fnum, create_options); + status = odb_set_create_options(lck, f->handle, create_options); if (NT_STATUS_IS_OK(status)) { - f->create_options = create_options; + f->handle->create_options = create_options; } return status; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 5847b1a2cc..fee3b19c9f 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -242,27 +242,29 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; + struct pvfs_file_handle *h; NTSTATUS status; f = pvfs_find_fd(pvfs, req, info->generic.in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } + h = f->handle; /* update the file information */ - status = pvfs_resolve_name_fd(pvfs, f->fd, f->name); + status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); if (!NT_STATUS_IS_OK(status)) { return status; } - status = pvfs_map_fileinfo(pvfs, req, f->name, info, f->fd); + status = pvfs_map_fileinfo(pvfs, req, h->name, info, h->fd); /* a qfileinfo can fill in a bit more info than a qpathinfo - now modify the levels that need to be fixed up */ switch (info->generic.level) { case RAW_FILEINFO_STANDARD_INFO: case RAW_FILEINFO_STANDARD_INFORMATION: - if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { info->standard_info.out.delete_pending = 1; info->standard_info.out.nlink--; } @@ -270,22 +272,22 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, case RAW_FILEINFO_ALL_INFO: case RAW_FILEINFO_ALL_INFORMATION: - if (f->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { info->all_info.out.delete_pending = 1; info->all_info.out.nlink--; } break; case RAW_FILEINFO_POSITION_INFORMATION: - info->position_information.out.position = f->position; + info->position_information.out.position = h->position; break; case RAW_FILEINFO_ACCESS_INFORMATION: - info->access_information.out.access_flags = f->access_mask; + info->access_information.out.access_flags = h->access_mask; break; case RAW_FILEINFO_MODE_INFORMATION: - info->mode_information.out.mode = f->mode; + info->mode_information.out.mode = h->mode; break; default: diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index f5df26f3d1..b14a1e601c 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -46,7 +46,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } @@ -54,7 +54,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, if (req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) { mask |= SA_RIGHT_FILE_EXECUTE; } - if (!(f->access_mask & mask)) { + if (!(f->handle->access_mask & mask)) { return NT_STATUS_ACCESS_DENIED; } @@ -71,7 +71,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return status; } - ret = pread(f->fd, + ret = pread(f->handle->fd, rd->readx.out.data, maxcnt, rd->readx.in.offset); @@ -79,7 +79,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } - f->position = f->seek_offset = rd->readx.in.offset + ret; + f->handle->position = f->handle->seek_offset = rd->readx.in.offset + ret; rd->readx.out.nread = ret; rd->readx.out.remaining = 0xFFFF; diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index c90db952fc..c4dd30bd85 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -31,31 +31,33 @@ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; + struct pvfs_file_handle *h; NTSTATUS status; f = pvfs_find_fd(pvfs, req, io->in.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } + h = f->handle; status = NT_STATUS_OK; switch (io->in.mode) { case SEEK_MODE_START: - f->seek_offset = io->in.offset; + h->seek_offset = io->in.offset; break; case SEEK_MODE_CURRENT: - f->seek_offset += io->in.offset; + h->seek_offset += io->in.offset; break; case SEEK_MODE_END: - status = pvfs_resolve_name_fd(pvfs, f->fd, f->name); - f->seek_offset = f->name->st.st_size + io->in.offset; + status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + h->seek_offset = h->name->st.st_size + io->in.offset; break; } - io->out.offset = f->seek_offset; + io->out.offset = h->seek_offset; return status; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 15b7f168f2..cad51c751c 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -26,6 +26,47 @@ #include "librpc/gen_ndr/ndr_xattr.h" +/* + rename_information level +*/ +static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + struct smb_rename_information *r) +{ +#if 0 + NTSTATUS status; + struct pvfs_filename *name2; + char *base_dir, *p; + + /* renames are only allowed within a directory */ + if (strchr_m(r->new_name, '\\')) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + /* don't allow this for now */ + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + + /* work out the base directory that the source file is in */ + base_dir = talloc_strdup(name, name->full_name); + p = strrchr(base_dir, '/'); + *p = 0; + + /* resolve the new name */ + status = pvfs_resolve_partial(pvfs, req, base_dir, r->new_name, &name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (name2->exists && !r->overwrite) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } +#endif + return NT_STATUS_UNSUCCESSFUL; +} + /* add a single DOS EA */ @@ -90,6 +131,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct utimbuf unix_times; struct pvfs_file *f; + struct pvfs_file_handle *h; uint32_t create_options; struct pvfs_filename newstats; NTSTATUS status; @@ -99,8 +141,10 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } + h = f->handle; + /* update the file information */ - status = pvfs_resolve_name_fd(pvfs, f->fd, f->name); + status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -108,7 +152,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* we take a copy of the current file stats, then update newstats in each of the elements below. At the end we compare, and make any changes needed */ - newstats = *f->name; + newstats = *h->name; switch (info->generic.level) { case RAW_SFILEINFO_SETATTR: @@ -134,7 +178,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, break; case RAW_SFILEINFO_EA_SET: - return pvfs_setfileinfo_ea_set(pvfs, f->name, f->fd, &info->ea_set.in.ea); + return pvfs_setfileinfo_ea_set(pvfs, h->name, h->fd, + &info->ea_set.in.ea); case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: @@ -157,10 +202,10 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - if (!(f->access_mask & STD_RIGHT_DELETE_ACCESS)) { + if (!(h->access_mask & STD_RIGHT_DELETE_ACCESS)) { return NT_STATUS_ACCESS_DENIED; } - create_options = f->create_options; + create_options = h->create_options; if (info->disposition_info.in.delete_on_close) { create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; } else { @@ -182,7 +227,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, break; case RAW_SFILEINFO_POSITION_INFORMATION: - f->position = info->position_information.in.position; + h->position = info->position_information.in.position; break; case RAW_SFILEINFO_MODE_INFORMATION: @@ -193,23 +238,27 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, info->mode_information.in.mode != 6) { return NT_STATUS_INVALID_PARAMETER; } - f->mode = info->mode_information.in.mode; + h->mode = info->mode_information.in.mode; break; + case RAW_SFILEINFO_RENAME_INFORMATION: + return pvfs_setfileinfo_rename(pvfs, req, h->name, + &info->rename_information.in); + default: return NT_STATUS_INVALID_LEVEL; } /* possibly change the file size */ - if (newstats.st.st_size != f->name->st.st_size) { + if (newstats.st.st_size != h->name->st.st_size) { int ret; - if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (f->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { - ret = ftruncate(f->fd, newstats.st.st_size); + if (h->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + ret = ftruncate(h->fd, newstats.st.st_size); } else { - ret = truncate(f->name->full_name, newstats.st.st_size); + ret = truncate(h->name->full_name, newstats.st.st_size); } if (ret == -1) { return pvfs_map_errno(pvfs, errno); @@ -218,33 +267,33 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file timestamps */ ZERO_STRUCT(unix_times); - if (newstats.dos.access_time != f->name->dos.access_time) { + if (newstats.dos.access_time != h->name->dos.access_time) { unix_times.actime = nt_time_to_unix(newstats.dos.access_time); } - if (newstats.dos.write_time != f->name->dos.write_time) { + if (newstats.dos.write_time != h->name->dos.write_time) { unix_times.modtime = nt_time_to_unix(newstats.dos.write_time); } if (unix_times.actime != 0 || unix_times.modtime != 0) { - if (utime(f->name->full_name, &unix_times) == -1) { + if (utime(h->name->full_name, &unix_times) == -1) { return pvfs_map_errno(pvfs, errno); } } /* possibly change the attribute */ - if (newstats.dos.attrib != f->name->dos.attrib) { + if (newstats.dos.attrib != h->name->dos.attrib) { mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib); - if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { /* ignore on directories for now */ return NT_STATUS_OK; } - if (fchmod(f->fd, mode) == -1) { + if (fchmod(h->fd, mode) == -1) { return pvfs_map_errno(pvfs, errno); } } - *f->name = newstats; + *h->name = newstats; - return pvfs_dosattrib_save(pvfs, f->name, f->fd); + return pvfs_dosattrib_save(pvfs, h->name, h->fd); } @@ -349,6 +398,10 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } return NT_STATUS_OK; + case RAW_SFILEINFO_RENAME_INFORMATION: + return pvfs_setfileinfo_rename(pvfs, req, name, + &info->rename_information.in); + case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: case RAW_SFILEINFO_POSITION_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index ccf3a775a8..7b38123971 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -44,11 +44,11 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (f->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (!(f->access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { + if (!(f->handle->access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { return NT_STATUS_ACCESS_VIOLATION; } @@ -60,7 +60,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return status; } - ret = pwrite(f->fd, + ret = pwrite(f->handle->fd, wr->writex.in.data, wr->writex.in.count, wr->writex.in.offset); @@ -71,7 +71,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return map_nt_error_from_unix(errno); } - f->seek_offset = wr->writex.in.offset + ret; + f->handle->seek_offset = wr->writex.in.offset + ret; wr->writex.out.nwritten = ret; wr->writex.out.remaining = 0; /* should fill this in? */ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index da4296d062..39f6717cae 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -108,7 +108,6 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->odb_context = odb_init(pvfs, pvfs->tcon->smb_conn->connection->server_id, - pvfs->tcon->service, pvfs->tcon->smb_conn->connection->messaging_ctx); if (pvfs->odb_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 91940e6355..3f74de4b63 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -84,12 +84,45 @@ struct pvfs_filename { }; +/* open file handle state - encapsulates the posix fd + + Note that this is separated from the pvfs_file structure in order + to cope with the openx DENY_DOS semantics where a 2nd DENY_DOS open + on the same connection gets the same low level filesystem handle, + rather than a new handle +*/ +struct pvfs_file_handle { + int fd; + + struct pvfs_filename *name; + + /* a unique file key to be used for file locking */ + DATA_BLOB locking_key; + + uint32_t create_options; + uint32_t share_access; + uint32_t access_mask; + + /* this is set by the mode_information level. What does it do? */ + uint32_t mode; + + /* yes, we need 2 independent positions ... */ + uint64_t seek_offset; + uint64_t position; + + BOOL have_opendb_entry; + + /* we need this hook back to our parent for lock destruction */ + struct pvfs_state *pvfs; +}; + /* open file state */ struct pvfs_file { struct pvfs_file *next, *prev; - int fd; + struct pvfs_file_handle *handle; uint16_t fnum; - struct pvfs_filename *name; + + struct pvfs_state *pvfs; /* we need to remember the session it was opened on, as it is illegal to operate on someone elses fnum */ @@ -99,31 +132,12 @@ struct pvfs_file { opened the file so SMBexit works */ uint16_t smbpid; - /* a unique file key to be used for file locking */ - DATA_BLOB locking_key; - - /* we need this hook back to our parent for lock destruction */ - struct pvfs_state *pvfs; - /* a list of pending locks - used for locking cancel operations */ struct pvfs_pending_lock *pending_list; /* a count of active locks - used to avoid calling brl_close on file close */ uint64_t lock_count; - - uint32_t create_options; - uint32_t share_access; - uint32_t access_mask; - - /* this is set by the mode_information level. What does it do? */ - uint32_t mode; - - /* yes, we need 2 independent positions ... */ - uint64_t seek_offset; - uint64_t position; - - BOOL have_opendb_entry; }; -- cgit From c077300a22806bab94d11a87c8ef96b6b541ada5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 Nov 2004 11:35:49 +0000 Subject: r3618: - this adds the special case for DENY_DOS semantics, as shown by the BASE-DENYDOS test. - pvfs now passes BASE-DENY1 and BASE-DENYDOS. (This used to be commit aa09df22ee729c02552638859236d9068e9748ae) --- source4/ntvfs/ntvfs_generic.c | 10 ++- source4/ntvfs/posix/pvfs_open.c | 154 +++++++++++++++++++++++++-------- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 4 +- source4/ntvfs/posix/pvfs_write.c | 2 +- source4/ntvfs/posix/vfs_posix.h | 6 +- 7 files changed, 135 insertions(+), 45 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 9ef2481d26..a9bc8120c8 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -117,7 +117,7 @@ static NTSTATUS ntvfs_map_async_finish(struct smbsrv_request *req, NTSTATUS stat see if a filename ends in EXE COM DLL or SYM. This is needed for the DENY_DOS mapping for OpenX */ -static BOOL is_exe_file(const char *fname) +BOOL is_exe_filename(const char *fname) { char *p; p = strrchr(fname, '.'); @@ -315,7 +315,9 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, break; case OPENX_MODE_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ - if (is_exe_file(io->openx.in.fname)) { + io2->generic.in.create_options |= + NTCREATEX_OPTIONS_PRIVATE_DENY_DOS; + if (is_exe_filename(io->openx.in.fname)) { io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; @@ -329,6 +331,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, } break; case OPENX_MODE_DENY_FCB: + io2->generic.in.create_options |= + NTCREATEX_OPTIONS_PRIVATE_DENY_FCB; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; default: @@ -400,7 +404,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch (io->openold.in.flags & OPEN_FLAGS_DENY_MASK) { case OPEN_FLAGS_DENY_DOS: /* DENY_DOS is quite strange - it depends on the filename! */ - if (is_exe_file(io->openold.in.fname)) { + if (is_exe_filename(io->openold.in.fname)) { io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; } else { if ((io->openold.in.flags & OPEN_FLAGS_MODE_MASK) == diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5411f83e8d..cfd2b0f159 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -147,19 +147,20 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } - f->fnum = fnum; - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; - f->pending_list = NULL; - f->lock_count = 0; + f->fnum = fnum; + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->share_access = io->generic.in.share_access; + f->impersonation = io->generic.in.impersonation; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); f->handle->fd = -1; f->handle->locking_key = data_blob(NULL, 0); f->handle->create_options = io->generic.in.create_options; - f->handle->share_access = io->generic.in.share_access; f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; @@ -326,11 +327,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; } - if ((access_mask & SA_RIGHT_FILE_READ_EXEC) && - (access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { + if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { flags = O_RDWR; - } else if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { - flags = O_WRONLY; } else { flags = O_RDONLY; } @@ -407,19 +405,20 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } - f->fnum = fnum; - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; - f->pending_list = NULL; - f->lock_count = 0; + f->fnum = fnum; + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->share_access = io->generic.in.share_access; + f->access_mask = access_mask; + f->impersonation = io->generic.in.impersonation; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); f->handle->fd = fd; f->handle->create_options = io->generic.in.create_options; - f->handle->share_access = io->generic.in.share_access; - f->handle->access_mask = access_mask; f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; @@ -535,6 +534,86 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) } +/* + special handling for openx DENY_DOS semantics + + This function attempts a reference open using an existing handle. If its allowed, + then it returns NT_STATUS_OK, otherwise it returns any other code and normal + open processing continues. +*/ +static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *io, + struct pvfs_file *f, struct odb_lock *lck) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f2; + struct pvfs_filename *name; + + /* search for an existing open with the right parameters. Note + the magic ntcreatex options flag, which is set in the + generic mapping code. This might look ugly, but its + actually pretty much now w2k does it internally as well. + + If you look at the BASE-DENYDOS test you will see that a + DENY_DOS is a very special case, and in the right + circumstances you actually get the _same_ handle back + twice, rather than a new handle. + */ + for (f2=pvfs->open_files;f2;f2=f2->next) { + if (f2 != f && + f2->session == req->session && + f2->smbpid == req->smbpid && + (f2->handle->create_options & + (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | + NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && + (f2->access_mask & SA_RIGHT_FILE_WRITE_DATA) && + StrCaseCmp(f2->handle->name->original_name, + io->generic.in.fname)==0) { + break; + } + } + + if (!f2) { + return NT_STATUS_SHARING_VIOLATION; + } + + /* quite an insane set of semantics ... */ + if (is_exe_filename(io->generic.in.fname) && + (f2->handle->create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) { + return NT_STATUS_SHARING_VIOLATION; + } + + /* + setup a reference to the existing handle + */ + talloc_free(f->handle); + f->handle = talloc_reference(f, f2->handle); + + talloc_free(lck); + + name = f->handle->name; + + io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.fnum = f->fnum; + io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 0; + + talloc_steal(f->pvfs, f); + + return NT_STATUS_OK; +} + + + /* setup for a open retry after a sharing violation */ @@ -549,6 +628,16 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct timeval end_time; + if (io->generic.in.create_options & + (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) { + /* see if we can satisfy the request using the special DENY_DOS + code */ + status = pvfs_open_deny_dos(ntvfs, req, io, f, lck); + if (NT_STATUS_IS_OK(status)) { + return status; + } + } + r = talloc_p(req, struct pvfs_open_retry); if (r == NULL) { return NT_STATUS_NO_MEMORY; @@ -638,10 +727,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* use the generic mapping code to avoid implementing all the - different open calls. This won't allow openx to work - perfectly as the mapping code has no way of knowing if two - opens are on the same connection, so this will need to - change eventually */ + different open calls. */ if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(req, io, ntvfs); } @@ -715,11 +801,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - if ((access_mask & SA_RIGHT_FILE_READ_EXEC) && - (access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { + if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { flags |= O_RDWR; - } else if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { - flags |= O_WRONLY; } else { flags |= O_RDONLY; } @@ -766,19 +849,20 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } - f->fnum = fnum; - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; - f->pending_list = NULL; - f->lock_count = 0; + f->fnum = fnum; + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->share_access = io->generic.in.share_access; + f->access_mask = access_mask; + f->impersonation = io->generic.in.impersonation; f->handle->pvfs = pvfs; f->handle->fd = -1; f->handle->name = talloc_steal(f->handle, name); f->handle->create_options = io->generic.in.create_options; - f->handle->share_access = io->generic.in.share_access; - f->handle->access_mask = access_mask; f->handle->seek_offset = 0; f->handle->position = 0; f->handle->have_opendb_entry = False; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index fee3b19c9f..c8134939a3 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -283,7 +283,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, break; case RAW_FILEINFO_ACCESS_INFORMATION: - info->access_information.out.access_flags = h->access_mask; + info->access_information.out.access_flags = f->access_mask; break; case RAW_FILEINFO_MODE_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index b14a1e601c..5598ccfb08 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -54,7 +54,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, if (req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) { mask |= SA_RIGHT_FILE_EXECUTE; } - if (!(f->handle->access_mask & mask)) { + if (!(f->access_mask & mask)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index cad51c751c..a550fb03e4 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -202,7 +202,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - if (!(h->access_mask & STD_RIGHT_DELETE_ACCESS)) { + if (!(f->access_mask & STD_RIGHT_DELETE_ACCESS)) { return NT_STATUS_ACCESS_DENIED; } create_options = h->create_options; @@ -255,7 +255,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, if (h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (h->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + if (f->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { ret = ftruncate(h->fd, newstats.st.st_size); } else { ret = truncate(h->name->full_name, newstats.st.st_size); diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 7b38123971..6ebd9b70cf 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -48,7 +48,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (!(f->handle->access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { + if (!(f->access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { return NT_STATUS_ACCESS_VIOLATION; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 3f74de4b63..46cc38c1f8 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -100,8 +100,6 @@ struct pvfs_file_handle { DATA_BLOB locking_key; uint32_t create_options; - uint32_t share_access; - uint32_t access_mask; /* this is set by the mode_information level. What does it do? */ uint32_t mode; @@ -124,6 +122,10 @@ struct pvfs_file { struct pvfs_state *pvfs; + uint32_t impersonation; + uint32_t share_access; + uint32_t access_mask; + /* we need to remember the session it was opened on, as it is illegal to operate on someone elses fnum */ struct smbsrv_session *session; -- cgit From 47b91c97cd5ec323b9c3b73bfa7951f8105da732 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Nov 2004 02:12:57 +0000 Subject: r3631: a couple of tweaks to the talloc hierarchy for async requests in pvfs. This prevents a possible crash due to free ordering on unexpected disconnect. (This used to be commit bfca9eb7cb7a2caf3a232d538808ff2ade8e1ca9) --- source4/ntvfs/posix/pvfs_open.c | 2 ++ source4/ntvfs/posix/pvfs_wait.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index cfd2b0f159..cc4498eee1 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -669,6 +669,8 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } + talloc_steal(pvfs, r); + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 968f659421..479d339592 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -127,7 +127,7 @@ static int pvfs_wait_destructor(void *ptr) struct timed_event te; struct pvfs_wait *pwait; - pwait = talloc_p(req, struct pvfs_wait); + pwait = talloc_p(pvfs, struct pvfs_wait); if (pwait == NULL) { return NULL; } -- cgit From cc0e67015696ce625033e9b2d49142fabed19c7e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Nov 2004 10:50:13 +0000 Subject: r3635: fixed the crash from the BASE-DISCONNECT test (This used to be commit bdabb3f836d56ab0af9201321c00c8b385e053a5) --- source4/ntvfs/posix/pvfs_lock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index a2691cb550..485199e6f8 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -188,6 +188,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas if (pending->wait_handle == NULL) { pvfs_lock_async_failed(pvfs, req, f, locks, i, NT_STATUS_NO_MEMORY); } else { + talloc_steal(pending, pending->wait_handle); DLIST_ADD(f->pending_list, pending); } return; @@ -224,7 +225,6 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) for (p=f->pending_list;p;p=next) { next = p->next; DLIST_REMOVE(f->pending_list, p); - talloc_free(p->wait_handle); p->req->async_states->status = NT_STATUS_RANGE_NOT_LOCKED; p->req->async_states->send_fn(p->req); } @@ -374,6 +374,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, if (pending->wait_handle == NULL) { return NT_STATUS_NO_MEMORY; } + talloc_steal(pending, pending->wait_handle); DLIST_ADD(f->pending_list, pending); return NT_STATUS_OK; } -- cgit From e7810eeab787bb93b36c95f8783d0b8f4c7cf7c0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Nov 2004 12:40:33 +0000 Subject: r3658: use handle->fd == -1 as the primary indicator of a directory. This fixes a directory creation problem from WinXP (This used to be commit 4b3afc6c395b430e7e56d8ebe0ddf85c556a5df5) --- source4/ntvfs/posix/pvfs_flush.c | 2 +- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_resolve.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 66a0cc5edf..5c1132db19 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -28,7 +28,7 @@ */ static void pvfs_flush_file(struct pvfs_state *pvfs, struct pvfs_file *f) { - if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->fd == -1) { return; } if (pvfs->flags & PVFS_FLAG_STRICT_SYNC) { diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 485199e6f8..c0d0133f03 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -290,7 +290,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->fd == -1) { return NT_STATUS_FILE_IS_A_DIRECTORY; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 5598ccfb08..0f7d3b4b0c 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -46,7 +46,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->fd == -1) { return NT_STATUS_FILE_IS_A_DIRECTORY; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 30602b964a..5c650440c3 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -511,7 +511,7 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, inode = name->st.st_ino; } - if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + if (fd == -1) { if (stat(name->full_name, &name->st) == -1) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 6ebd9b70cf..989e8d7b1b 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -44,7 +44,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (f->handle->fd == -1) { return NT_STATUS_FILE_IS_A_DIRECTORY; } -- cgit From 94c6fde541f2f8c5b93f8c779f0a1714a446e490 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Nov 2004 02:45:52 +0000 Subject: r3694: added support for the RENAME_INFORMATION level of setfileinfo and setpathinfo. pvfs now passes the RAW-SFILEINFO test. (This used to be commit 31ac31398ba52dfc554e58edaa7ae257caf5fdc6) --- source4/ntvfs/posix/pvfs_resolve.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 58 ++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 5c650440c3..354cdd4bb4 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -527,7 +527,7 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, be someone trying to exploit a race condition. Certainly we don't want to continue operating on this file */ - DEBUG(0,("pvfs: WARNING: file '%s' changed during resole - failing\n", + DEBUG(0,("pvfs: WARNING: file '%s' changed during resolve - failing\n", name->full_name)); return NT_STATUS_UNEXPECTED_IO_ERROR; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index a550fb03e4..391a2e9d82 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -34,10 +34,9 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, struct pvfs_filename *name, struct smb_rename_information *r) { -#if 0 NTSTATUS status; struct pvfs_filename *name2; - char *base_dir, *p; + char *new_name, *p; /* renames are only allowed within a directory */ if (strchr_m(r->new_name, '\\')) { @@ -49,22 +48,61 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - /* work out the base directory that the source file is in */ - base_dir = talloc_strdup(name, name->full_name); - p = strrchr(base_dir, '/'); + /* w2k3 does not appear to allow relative rename */ + if (r->root_fid != 0) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* construct the fully qualified windows name for the new file name */ + new_name = talloc_strdup(req, name->original_name); + if (new_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + p = strrchr_m(new_name, '\\'); + if (p == NULL) { + return NT_STATUS_OBJECT_NAME_INVALID; + } *p = 0; + new_name = talloc_asprintf(req, "%s\\%s", new_name, r->new_name); + if (new_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + /* resolve the new name */ - status = pvfs_resolve_partial(pvfs, req, base_dir, r->new_name, &name2); + status = pvfs_resolve_name(pvfs, name, new_name, PVFS_RESOLVE_NO_WILDCARD, &name2); if (!NT_STATUS_IS_OK(status)) { return status; } - if (name2->exists && !r->overwrite) { - return NT_STATUS_OBJECT_NAME_COLLISION; + /* if the destination exists, then check the rename is allowed */ + if (name2->exists) { + if (strcmp(name2->full_name, name->full_name) == 0) { + /* rename to same name is null-op */ + return NT_STATUS_OK; + } + + if (!r->overwrite) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + status = pvfs_can_delete(pvfs, name2); + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { + return NT_STATUS_ACCESS_DENIED; + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + if (rename(name->full_name, name2->full_name) == -1) { + return map_nt_error_from_unix(errno); } -#endif - return NT_STATUS_UNSUCCESSFUL; + + name->full_name = talloc_steal(name, name2->full_name); + name->original_name = talloc_steal(name, name2->original_name); + + return NT_STATUS_OK; } /* -- cgit From 1c59d825afc3cdfe2ea42821123ece934ad7b5e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Nov 2004 05:47:27 +0000 Subject: r3717: - expanded the RAW-RENAME test a little - added support for wildcard rename in pvfs - made more consistent use of pvfs_map_errno() (This used to be commit e255d1c3a811c480a850452aaf636d9fa36f69fe) --- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/posix/pvfs_rename.c | 225 ++++++++++++++++++++++++++++++++- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 2 +- source4/ntvfs/posix/pvfs_xattr.c | 33 +++-- 5 files changed, 245 insertions(+), 19 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index cc4498eee1..af0f46ece3 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -937,7 +937,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, mode_t mode = pvfs_fileperms(pvfs, attrib); if (fchmod(fd, mode) == -1) { talloc_free(lck); - return map_nt_error_from_unix(errno); + return pvfs_map_errno(pvfs, errno); } name->dos.attrib = attrib; status = pvfs_dosattrib_save(pvfs, name, fd); diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index a621165ce4..d36af2b91d 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -23,6 +23,223 @@ #include "includes.h" #include "vfs_posix.h" + +/* + resolve a wildcard rename pattern. This works on one component of the name +*/ +static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, + const char *fname, + const char *pattern) +{ + const char *p1, *p2; + char *dest, *d; + + /* the length is bounded by the length of the two strings combined */ + dest = talloc(mem_ctx, strlen(fname) + strlen(pattern) + 1); + if (dest == NULL) { + return NULL; + } + + p1 = fname; + p2 = pattern; + d = dest; + + while (*p2) { + codepoint_t c1, c2; + size_t c_size1, c_size2; + c1 = next_codepoint(p1, &c_size1); + c2 = next_codepoint(p2, &c_size2); + if (c2 == '?') { + d += push_codepoint(d, c1); + } else if (c2 == '*') { + memcpy(d, p1, strlen(p1)); + d += strlen(p1); + break; + } else { + d += push_codepoint(d, c2); + } + + p1 += c_size1; + p2 += c_size2; + } + + *d = 0; + + return dest; +} + +/* + resolve a wildcard rename pattern. +*/ +static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, + const char *fname, + const char *pattern) +{ + const char *base1, *base2; + const char *ext1, *ext2; + char *p; + + /* break into base part plus extension */ + p = strrchr_m(fname, '.'); + if (p == NULL) { + ext1 = ""; + base1 = fname; + } else { + ext1 = talloc_strdup(mem_ctx, p+1); + base1 = talloc_strndup(mem_ctx, fname, p-fname); + } + if (ext1 == NULL || base1 == NULL) { + return NULL; + } + + p = strrchr_m(pattern, '.'); + if (p == NULL) { + ext2 = ""; + base2 = fname; + } else { + ext2 = talloc_strdup(mem_ctx, p+1); + base2 = talloc_strndup(mem_ctx, pattern, p-pattern); + } + if (ext2 == NULL || base2 == NULL) { + return NULL; + } + + base1 = pvfs_resolve_wildcard_component(mem_ctx, base1, base2); + ext1 = pvfs_resolve_wildcard_component(mem_ctx, ext1, ext2); + if (base1 == NULL || ext1 == NULL) { + return NULL; + } + + if (*ext1 == 0) { + return base1; + } + + return talloc_asprintf(mem_ctx, "%s.%s", base1, ext1); +} + +/* + rename one file from a wildcard set +*/ +static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, + struct smbsrv_request *req, + const char *dir_path, + const char *fname1, + const char *fname2, + uint16_t attrib) +{ + struct pvfs_filename *name1, *name2; + TALLOC_CTX *mem_ctx = talloc(req, 0); + NTSTATUS status; + + /* resolve the wildcard pattern for this name */ + fname2 = pvfs_resolve_wildcard(mem_ctx, fname1, fname2); + if (fname2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* get a pvfs_filename source object */ + status = pvfs_resolve_partial(pvfs, mem_ctx, + dir_path, fname1, &name1); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + /* make sure its matches the given attributes */ + status = pvfs_match_attrib(pvfs, name1, attrib, 0); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + status = pvfs_can_rename(pvfs, name1); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + /* get a pvfs_filename dest object */ + status = pvfs_resolve_partial(pvfs, mem_ctx, + dir_path, fname2, &name2); + if (NT_STATUS_IS_OK(status)) { + status = pvfs_can_delete(pvfs, name2); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + } + + fname2 = talloc_asprintf(mem_ctx, "%s/%s", dir_path, fname2); + if (fname2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* finally try the actual rename */ + if (rename(name1->full_name, fname2) == -1) { + talloc_free(mem_ctx); + return pvfs_map_errno(pvfs, errno); + } + + talloc_free(mem_ctx); + + return NT_STATUS_OK; +} + + +/* + rename a set of files with wildcards +*/ +static NTSTATUS pvfs_rename_wildcard(struct pvfs_state *pvfs, + struct smbsrv_request *req, + union smb_rename *ren, + struct pvfs_filename *name1, + struct pvfs_filename *name2) +{ + struct pvfs_dir *dir; + NTSTATUS status; + uint_t ofs = 0; + const char *fname, *fname2, *dir_path; + uint16_t attrib = ren->rename.in.attrib; + int total_renamed = 0; + + /* get list of matching files */ + status = pvfs_list_start(pvfs, name1, req, &dir); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = NT_STATUS_NO_SUCH_FILE; + + dir_path = pvfs_list_unix_path(dir); + + /* only allow wildcard renames within a directory */ + if (strncmp(dir_path, name2->full_name, strlen(dir_path)) != 0 || + name2->full_name[strlen(dir_path)] != '/' || + strchr(name2->full_name + strlen(dir_path) + 1, '/')) { + return NT_STATUS_INVALID_PARAMETER; + } + + fname2 = talloc_strdup(name2, name2->full_name + strlen(dir_path) + 1); + if (fname2 == NULL) { + return NT_STATUS_NO_MEMORY; + } + + while ((fname = pvfs_list_next(dir, &ofs))) { + status = pvfs_rename_one(pvfs, req, + dir_path, + fname, fname2, attrib); + if (NT_STATUS_IS_OK(status)) { + total_renamed++; + } + } + + if (total_renamed == 0) { + return status; + } + + return NT_STATUS_OK; +} + /* rename a set of files */ @@ -49,15 +266,17 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, } if (name1->has_wildcard || name2->has_wildcard) { - DEBUG(3,("Rejecting wildcard rename '%s' -> '%s'\n", - ren->rename.in.pattern1, ren->rename.in.pattern2)); - return NT_STATUS_NOT_SUPPORTED; + return pvfs_rename_wildcard(pvfs, req, ren, name1, name2); } if (!name1->exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + if (strcmp(name1->full_name, name2->full_name) == 0) { + return NT_STATUS_OK; + } + if (name2->exists) { return NT_STATUS_OBJECT_NAME_COLLISION; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 391a2e9d82..e54c37741c 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -96,7 +96,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } if (rename(name->full_name, name2->full_name) == -1) { - return map_nt_error_from_unix(errno); + return pvfs_map_errno(pvfs, errno); } name->full_name = talloc_steal(name, name2->full_name); diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 989e8d7b1b..c24de08a13 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -68,7 +68,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, if (errno == EFBIG) { return NT_STATUS_INVALID_PARAMETER; } - return map_nt_error_from_unix(errno); + return pvfs_map_errno(pvfs, errno); } f->handle->seek_offset = wr->writex.in.offset + ret; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index f4063b48b5..d5a7d17a31 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -28,7 +28,8 @@ /* pull a xattr as a blob, from either a file or a file descriptor */ -static NTSTATUS pull_xattr_blob(TALLOC_CTX *mem_ctx, +static NTSTATUS pull_xattr_blob(struct pvfs_state *pvfs, + TALLOC_CTX *mem_ctx, const char *attr_name, const char *fname, int fd, @@ -61,7 +62,7 @@ again: if (ret == -1) { data_blob_free(blob); - return map_nt_error_from_unix(errno); + return pvfs_map_errno(pvfs, errno); } blob->length = ret; @@ -75,7 +76,8 @@ again: /* push a xattr as a blob, from either a file or a file descriptor */ -static NTSTATUS push_xattr_blob(const char *attr_name, +static NTSTATUS push_xattr_blob(struct pvfs_state *pvfs, + const char *attr_name, const char *fname, int fd, const DATA_BLOB *blob) @@ -89,7 +91,7 @@ static NTSTATUS push_xattr_blob(const char *attr_name, ret = setxattr(fname, attr_name, blob->data, blob->length, 0); } if (ret == -1) { - return map_nt_error_from_unix(errno); + return pvfs_map_errno(pvfs, errno); } return NT_STATUS_OK; @@ -101,14 +103,15 @@ static NTSTATUS push_xattr_blob(const char *attr_name, /* load a NDR structure from a xattr */ -static NTSTATUS pvfs_xattr_ndr_load(TALLOC_CTX *mem_ctx, +static NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, + TALLOC_CTX *mem_ctx, const char *fname, int fd, const char *attr_name, void *p, ndr_pull_flags_fn_t pull_fn) { NTSTATUS status; DATA_BLOB blob; - status = pull_xattr_blob(mem_ctx, attr_name, fname, + status = pull_xattr_blob(pvfs, mem_ctx, attr_name, fname, fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob); if (!NT_STATUS_IS_OK(status)) { return status; @@ -125,7 +128,8 @@ static NTSTATUS pvfs_xattr_ndr_load(TALLOC_CTX *mem_ctx, /* save a NDR structure into a xattr */ -static NTSTATUS pvfs_xattr_ndr_save(const char *fname, int fd, const char *attr_name, +static NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, + const char *fname, int fd, const char *attr_name, void *p, ndr_push_flags_fn_t push_fn) { TALLOC_CTX *mem_ctx = talloc(NULL, 0); @@ -138,7 +142,7 @@ static NTSTATUS pvfs_xattr_ndr_save(const char *fname, int fd, const char *attr_ return status; } - status = push_xattr_blob(attr_name, fname, fd, &blob); + status = push_xattr_blob(pvfs, attr_name, fname, fd, &blob); talloc_free(mem_ctx); return status; @@ -159,8 +163,10 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name return NT_STATUS_OK; } - status = pvfs_xattr_ndr_load(mem_ctx, name->full_name, fd, XATTR_DOSATTRIB_NAME, - &attrib, (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); + status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, + fd, XATTR_DOSATTRIB_NAME, + &attrib, + (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); /* if the filesystem doesn't support them, then tell pvfs not to try again */ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { @@ -233,7 +239,8 @@ NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name info1->create_time = name->dos.create_time; info1->change_time = name->dos.change_time; - return pvfs_xattr_ndr_save(name->full_name, fd, XATTR_DOSATTRIB_NAME, &attrib, + return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, + XATTR_DOSATTRIB_NAME, &attrib, (ndr_push_flags_fn_t)ndr_push_xattr_DosAttrib); } @@ -249,7 +256,7 @@ NTSTATUS pvfs_doseas_load(struct pvfs_state *pvfs, struct pvfs_filename *name, i if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_OK; } - status = pvfs_xattr_ndr_load(eas, name->full_name, fd, XATTR_DOSEAS_NAME, + status = pvfs_xattr_ndr_load(pvfs, eas, name->full_name, fd, XATTR_DOSEAS_NAME, eas, (ndr_pull_flags_fn_t)ndr_pull_xattr_DosEAs); if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { return NT_STATUS_OK; @@ -266,6 +273,6 @@ NTSTATUS pvfs_doseas_save(struct pvfs_state *pvfs, struct pvfs_filename *name, i if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_OK; } - return pvfs_xattr_ndr_save(name->full_name, fd, XATTR_DOSEAS_NAME, eas, + return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSEAS_NAME, eas, (ndr_push_flags_fn_t)ndr_push_xattr_DosEAs); } -- cgit From 1b2b72ff61c6e81189fd0552bfce5d2c7d365554 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Nov 2004 06:46:51 +0000 Subject: r3718: added support for the ntrename level in pvfs_rename(). (This used to be commit 3d50982f5419b9a5c53f2b82a2313669cdeaaa21) --- source4/ntvfs/posix/pvfs_open.c | 3 +- source4/ntvfs/posix/pvfs_rename.c | 122 +++++++++++++++++++++++++++++++++++--- source4/ntvfs/posix/pvfs_util.c | 81 +++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index af0f46ece3..b07922dcbd 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1118,8 +1118,7 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, struct pvfs_filename *name) status = odb_can_open(pvfs->odb_context, &key, NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE | - NTCREATEX_SHARE_ACCESS_DELETE, + NTCREATEX_SHARE_ACCESS_WRITE, 0, STD_RIGHT_DELETE_ACCESS); diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index d36af2b91d..aae17f327c 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -174,7 +174,6 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - /* finally try the actual rename */ if (rename(name1->full_name, fname2) == -1) { talloc_free(mem_ctx); return pvfs_map_errno(pvfs, errno); @@ -241,19 +240,15 @@ static NTSTATUS pvfs_rename_wildcard(struct pvfs_state *pvfs, } /* - rename a set of files + rename a set of files - SMBmv interface */ -NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) +static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) { struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; - if (ren->generic.level != RAW_RENAME_RENAME) { - return NT_STATUS_INVALID_LEVEL; - } - /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, 0, &name1); if (!NT_STATUS_IS_OK(status)) { @@ -281,6 +276,11 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } + status = pvfs_match_attrib(pvfs, name1, ren->rename.in.attrib, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = pvfs_can_rename(pvfs, name1); if (!NT_STATUS_IS_OK(status)) { return status; @@ -292,3 +292,109 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } + + +/* + rename a set of files - ntrename interface +*/ +static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + NTSTATUS status; + struct pvfs_filename *name1, *name2; + + switch (ren->ntrename.in.flags) { + case RENAME_FLAG_RENAME: + case RENAME_FLAG_HARD_LINK: + case RENAME_FLAG_COPY: + case RENAME_FLAG_MOVE_CLUSTER_INFORMATION: + break; + default: + return NT_STATUS_ACCESS_DENIED; + } + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.old_name, 0, &name1); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.new_name, 0, &name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (name1->has_wildcard || name2->has_wildcard) { + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; + } + + if (!name1->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (strcmp(name1->full_name, name2->full_name) == 0) { + return NT_STATUS_OK; + } + + if (name2->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + status = pvfs_match_attrib(pvfs, name1, ren->ntrename.in.attrib, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_can_rename(pvfs, name1); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (ren->ntrename.in.flags) { + case RENAME_FLAG_RENAME: + if (rename(name1->full_name, name2->full_name) == -1) { + return pvfs_map_errno(pvfs, errno); + } + break; + + case RENAME_FLAG_HARD_LINK: + if (link(name1->full_name, name2->full_name) == -1) { + return pvfs_map_errno(pvfs, errno); + } + break; + + case RENAME_FLAG_COPY: + return pvfs_copy_file(pvfs, name1, name2); + + case RENAME_FLAG_MOVE_CLUSTER_INFORMATION: + return NT_STATUS_INVALID_PARAMETER; + + default: + return NT_STATUS_ACCESS_DENIED; + } + + + return NT_STATUS_OK; +} + +/* + rename a set of files - ntrename interface +*/ +NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) +{ + switch (ren->generic.level) { + case RAW_RENAME_RENAME: + return pvfs_rename_mv(ntvfs, req, ren); + + case RAW_RENAME_NTRENAME: + return pvfs_rename_nt(ntvfs, req, ren); + + default: + break; + } + + return NT_STATUS_INVALID_LEVEL; +} + diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 92d696970a..6503769013 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -79,3 +79,84 @@ uint32_t pvfs_attrib_normalise(uint32_t attrib) return attrib; } + +/* + copy a file. Caller is supposed to have already ensured that the + operation is allowed. The destination file must not exist. +*/ +NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs, + struct pvfs_filename *name1, + struct pvfs_filename *name2) +{ + int fd1, fd2; + mode_t mode; + NTSTATUS status; + size_t buf_size = 0x10000; + char *buf = talloc(name2, buf_size); + + if (buf == NULL) { + return NT_STATUS_NO_MEMORY; + } + + fd1 = open(name1->full_name, O_RDONLY); + if (fd1 == -1) { + talloc_free(buf); + return pvfs_map_errno(pvfs, errno); + } + + fd2 = open(name2->full_name, O_CREAT|O_EXCL|O_WRONLY, 0); + if (fd2 == -1) { + close(fd1); + talloc_free(buf); + return pvfs_map_errno(pvfs, errno); + } + + while (1) { + ssize_t ret2, ret = read(fd1, buf, buf_size); + if (ret == -1 && + (errno == EINTR || errno == EAGAIN)) { + continue; + } + if (ret <= 0) break; + + ret2 = write(fd2, buf, ret); + if (ret2 == -1 && + (errno == EINTR || errno == EAGAIN)) { + continue; + } + + if (ret2 != ret) { + close(fd1); + close(fd2); + talloc_free(buf); + unlink(name2->full_name); + if (ret2 == -1) { + return pvfs_map_errno(pvfs, errno); + } + return NT_STATUS_DISK_FULL; + } + } + + close(fd1); + + mode = pvfs_fileperms(pvfs, name1->dos.attrib); + if (fchmod(fd2, mode) == -1) { + status = pvfs_map_errno(pvfs, errno); + close(fd2); + unlink(name2->full_name); + return status; + } + + name2->dos = name1->dos; + + status = pvfs_dosattrib_save(pvfs, name2, fd2); + if (!NT_STATUS_IS_OK(status)) { + close(fd2); + unlink(name2->full_name); + return status; + } + + close(fd2); + + return NT_STATUS_OK; +} -- cgit From f0b954968c19722b7f42a4bcd367d5f815efdc47 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Nov 2004 09:16:03 +0000 Subject: r3729: permission changes on directories always include the FILE_ATTRIBUTE_DIRECTORY bit (This used to be commit 5af815ffc3531e4ae4a6844e9f754656d9acf76e) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index e54c37741c..b9ed592bf4 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -471,6 +471,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } /* possibly change the attribute */ + newstats.dos.attrib |= (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY); if (newstats.dos.attrib != name->dos.attrib) { mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib); if (chmod(name->full_name, mode) == -1) { -- cgit From 8e16d8a76f8a3b8ccc89eb317c8e5daa6cf43b71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 16:22:01 +0000 Subject: r3733: More build system fixes/features: - Use .mk files directly (no need for a SMB_*_MK() macro when adding a new SUBSYSTEM, MODULE or BINARY). This allows addition of new modules and subsystems without running configure - Add support for generating .dot files with the Samba4 dependency tree (as used by the graphviz and springgraph utilities) (This used to be commit 64826da834e26ee0488674e27a0eae36491ee179) --- source4/ntvfs/config.m4 | 19 ------------------- source4/ntvfs/config.mk | 5 +++++ source4/ntvfs/posix/config.m4 | 2 -- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/unixuid/config.m4 | 1 - source4/ntvfs/unixuid/config.mk | 1 + 6 files changed, 7 insertions(+), 22 deletions(-) delete mode 100644 source4/ntvfs/config.m4 (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.m4 b/source4/ntvfs/config.m4 deleted file mode 100644 index dd8e60adde..0000000000 --- a/source4/ntvfs/config.m4 +++ /dev/null @@ -1,19 +0,0 @@ -dnl # NTVFS Server subsystem - -SMB_INCLUDE_M4(ntvfs/posix/config.m4) -SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/posix/config.mk) - -SMB_INCLUDE_M4(ntvfs/unixuid/config.m4) -SMB_MODULE_MK(ntvfs_unixuid, NTVFS, STATIC, ntvfs/unixuid/config.mk) - -SMB_MODULE_MK(ntvfs_cifs, NTVFS, STATIC, ntvfs/config.mk) - -SMB_MODULE_MK(ntvfs_simple, NTVFS, STATIC, ntvfs/config.mk) - -SMB_MODULE_MK(ntvfs_print, NTVFS, STATIC, ntvfs/config.mk) - -SMB_MODULE_MK(ntvfs_ipc, NTVFS, STATIC, ntvfs/config.mk) - -SMB_MODULE_MK(ntvfs_nbench, NTVFS, STATIC, ntvfs/config.mk) - -SMB_SUBSYSTEM_MK(NTVFS,ntvfs/config.mk) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index c15470076f..14215004ea 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -4,6 +4,7 @@ # Start MODULE ntvfs_cifs [MODULE::ntvfs_cifs] INIT_FUNCTION = ntvfs_cifs_init +SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ ntvfs/cifs/vfs_cifs.o REQUIRED_SUBSYSTEMS = \ @@ -15,6 +16,7 @@ REQUIRED_SUBSYSTEMS = \ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init +SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ ntvfs/simple/vfs_simple.o ADD_OBJ_FILES = \ @@ -26,6 +28,7 @@ ADD_OBJ_FILES = \ # Start MODULE ntvfs_print [MODULE::ntvfs_print] INIT_FUNCTION = ntvfs_print_init +SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ ntvfs/print/vfs_print.o # End MODULE ntvfs_print @@ -34,6 +37,7 @@ INIT_OBJ_FILES = \ ################################################ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] +SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_ipc_init INIT_OBJ_FILES = \ ntvfs/ipc/vfs_ipc.o \ @@ -47,6 +51,7 @@ INIT_OBJ_FILES = \ ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] +SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_nbench_init INIT_OBJ_FILES = \ ntvfs/nbench/vfs_nbench.o diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 975da5f2a9..d39acbe85e 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -30,5 +30,3 @@ AC_SEARCH_LIBS(flistxattr, [attr]) if test x"$ac_cv_func_flistxattr" = x"yes"; then AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) fi - -SMB_MODULE_MK(ntvfs_posix, NTVFS, STATIC, ntvfs/config.mk) diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index f54d2e24fb..74e991d9bd 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,6 +1,7 @@ ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] +SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_posix_init INIT_OBJ_FILES = \ ntvfs/posix/vfs_posix.o diff --git a/source4/ntvfs/unixuid/config.m4 b/source4/ntvfs/unixuid/config.m4 index 61e7db3d91..2c6777f68e 100644 --- a/source4/ntvfs/unixuid/config.m4 +++ b/source4/ntvfs/unixuid/config.m4 @@ -1,4 +1,3 @@ -SMB_MODULE_MK(ntvfs_unixuid, NTVFS, STATIC, ntvfs/config.mk) ################################################ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 611be650d1..3df3194688 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -2,6 +2,7 @@ # Start MODULE ntvfs_unixuid [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init +SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ ntvfs/unixuid/vfs_unixuid.o # End MODULE ntvfs_unixuid -- cgit From 31ded4901b4529ad2e49871502cab5ecba71483a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 14 Nov 2004 22:23:23 +0000 Subject: r3737: - Get rid of the register_subsystem() and register_backend() functions. - Re-disable tdbtool (it was building fine on my Debian box but other machines were having problems) (This used to be commit 0d7bb2c40b7a9ed59df3f8944133ea562697e814) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/config.mk | 1 - source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/nbench/vfs_nbench.c | 2 +- source4/ntvfs/ntvfs_base.c | 21 +-------------------- source4/ntvfs/posix/vfs_posix.c | 4 ++-- source4/ntvfs/print/vfs_print.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 2 +- source4/ntvfs/unixuid/vfs_unixuid.c | 6 +++--- 9 files changed, 11 insertions(+), 31 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index ea169b7ee6..bfba31b46f 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -872,7 +872,7 @@ NTSTATUS ntvfs_cifs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register CIFS backend!\n")); diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 14215004ea..43157a8c66 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -61,7 +61,6 @@ INIT_OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::NTVFS] -INIT_FUNCTION = ntvfs_init INIT_OBJ_FILES = \ ntvfs/ntvfs_base.o ADD_OBJ_FILES = \ diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 271be09ac3..a53accd533 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -756,7 +756,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.cancel = ipc_cancel; /* register ourselves with the NTVFS subsystem. */ - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register IPC backend!\n")); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 1bcfda1371..560f4a646b 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -924,7 +924,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.trans2 = NULL; /* register ourselves with the NTVFS subsystem. */ - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register nbench backend!\n")); diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index c168467eae..136ef14e4c 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -45,7 +45,7 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -static NTSTATUS ntvfs_register(const void *_ops) +NTSTATUS ntvfs_register(const void *_ops) { const struct ntvfs_ops *ops = _ops; struct ntvfs_ops *new_ops; @@ -116,25 +116,6 @@ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) } -/* - initialise the NTVFS subsystem -*/ -NTSTATUS ntvfs_init(void) -{ - NTSTATUS status; - - status = register_subsystem("ntvfs", ntvfs_register); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - ntvfs_init_static_modules; - - DEBUG(3,("NTVFS subsystem version %d initialised\n", NTVFS_INTERFACE_VERSION)); - return status; -} - - /* initialise a connection structure to point at a NTVFS backend */ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 39f6717cae..e5712e3e7d 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -252,10 +252,10 @@ NTSTATUS ntvfs_posix_init(void) under the name 'default' as we wish to be the default backend, and also register as 'posix' */ ops.name = "default"; - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); ops.name = "posix"; - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend!\n")); diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 372f64e982..4e2dfad0ca 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -107,7 +107,7 @@ NTSTATUS ntvfs_print_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register PRINT backend!\n")); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 807f51a43d..57d626465a 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -1006,7 +1006,7 @@ NTSTATUS ntvfs_simple_init(void) ops.type = NTVFS_DISK; ops.name = "simple"; - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register simple backend with name: %s!\n", diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 7f8f8acf99..4520df59fc 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -803,15 +803,15 @@ NTSTATUS ntvfs_unixuid_init(void) /* we register under all 3 backend types, as we are not type specific */ ops.type = NTVFS_DISK; - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_PRINT; - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_IPC; - ret = register_backend("ntvfs", &ops); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) goto failed; failed: -- cgit From 24a40fb41280a9eb22be89699c76eeeb8aab7111 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Nov 2004 23:37:02 +0000 Subject: r3741: FILE_ATTRIBUTE_DIRECTORY is illegal in open of a file (This used to be commit ad7815fababe5783df5e8fb4a490921a5af693d6) --- source4/ntvfs/posix/pvfs_open.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index b07922dcbd..9bb3487679 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -809,6 +809,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, flags |= O_RDONLY; } + if (io->generic.in.file_attr & FILE_ATTRIBUTE_DIRECTORY) { + return NT_STATUS_INVALID_PARAMETER; + } + /* handle creating a new file separately */ if (!name->exists) { status = pvfs_create_file(pvfs, req, name, io); -- cgit From 187412f3da4fbc6feeca15bd0c2527534255964e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Nov 2004 06:57:26 +0000 Subject: r3747: - added some of the infrastructure needed for streams support in pvfs (the IDL, and the load/save meta-data logic) - changed pvfs_resolve_name() to default to non-wildcard, needing PVFS_RESOLVE_WILDCARD to enable wildcards. Most callers don't want wildcards, so defaulting this way makes more sense. - fixed deletion of EAs (This used to be commit e7afd4403cc1b7e0928776929f8988aa6f15640b) --- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_mkdir.c | 6 ++---- source4/ntvfs/posix/pvfs_open.c | 17 ++++++++-------- source4/ntvfs/posix/pvfs_qfileinfo.c | 3 +-- source4/ntvfs/posix/pvfs_rename.c | 10 ++++----- source4/ntvfs/posix/pvfs_resolve.c | 4 ++-- source4/ntvfs/posix/pvfs_search.c | 4 ++-- source4/ntvfs/posix/pvfs_setfileinfo.c | 16 ++++++++++++--- source4/ntvfs/posix/pvfs_streams.c | 27 +++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_unlink.c | 3 ++- source4/ntvfs/posix/pvfs_xattr.c | 37 ++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 3 +-- source4/ntvfs/posix/vfs_posix.h | 2 +- 13 files changed, 102 insertions(+), 31 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_streams.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 74e991d9bd..1d33d8b381 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -27,6 +27,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_seek.o \ ntvfs/posix/pvfs_ioctl.o \ ntvfs/posix/pvfs_xattr.o \ + ntvfs/posix/pvfs_streams.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 3b5204c934..1bc0fa569e 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -39,8 +39,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, } /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -69,8 +68,7 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, rd->in.path, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, rd->in.path, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 9bb3487679..4f089a8c07 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -103,6 +103,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, NTSTATUS status; uint32_t create_action; + if (name->stream_name) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + /* if the client says it must be a directory, and it isn't, then fail */ if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { @@ -180,8 +184,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, if (mkdir(name->full_name, mode) == -1) { return pvfs_map_errno(pvfs,errno); } - status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -684,8 +687,7 @@ static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; NTSTATUS status; - status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -735,8 +737,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, + PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -826,8 +828,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* try re-resolving the name */ - status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index c8134939a3..3eaa7865e8 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -219,8 +219,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index aae17f327c..efaf63ba9d 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -250,12 +250,14 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name1, *name2; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, 0, &name1); + status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, + PVFS_RESOLVE_WILDCARD, &name1); if (!NT_STATUS_IS_OK(status)) { return status; } - status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2, 0, &name2); + status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2, + PVFS_RESOLVE_WILDCARD, &name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -325,10 +327,6 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, return status; } - if (name1->has_wildcard || name2->has_wildcard) { - return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; - } - if (!name1->exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 354cdd4bb4..576b0d9db4 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -253,7 +253,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, case '<': case '?': case '"': - if (flags & PVFS_RESOLVE_NO_WILDCARD) { + if (!(flags & PVFS_RESOLVE_WILDCARD)) { return NT_STATUS_OBJECT_NAME_INVALID; } name->has_wildcard = True; @@ -341,7 +341,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t } } if (err_count) { - if (!(flags & PVFS_RESOLVE_NO_WILDCARD)) err_count--; + if (flags & PVFS_RESOLVE_WILDCARD) err_count--; if (err_count==1) { return NT_STATUS_OBJECT_NAME_INVALID; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 831b799716..f805f201f6 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -300,7 +300,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, pattern = io->search_first.in.pattern; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, pattern, 0, &name); + status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -436,7 +436,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, max_count = io->t2ffirst.in.max_count; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, pattern, 0, &name); + status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index b9ed592bf4..7ba64979c3 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -70,7 +70,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } /* resolve the new name */ - status = pvfs_resolve_name(pvfs, name, new_name, PVFS_RESOLVE_NO_WILDCARD, &name2); + status = pvfs_resolve_name(pvfs, name, new_name, 0, &name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -144,6 +144,17 @@ static NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, ealist->num_eas++; save: + /* pull out any null EAs */ + for (i=0;inum_eas;i++) { + if (ealist->eas[i].value.length == 0) { + memmove(&ealist->eas[i], + &ealist->eas[i+1], + (ealist->num_eas-(i+1)) * sizeof(ealist->eas[i])); + ealist->num_eas--; + i--; + } + } + status = pvfs_doseas_save(pvfs, name, fd, ealist); if (!NT_STATUS_IS_OK(status)) { return status; @@ -348,8 +359,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct utimbuf unix_times; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c new file mode 100644 index 0000000000..b71ff640e5 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - alternate data streams + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_xattr.h" + diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index ab8f1abf62..8dc9f60ad8 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -85,7 +85,8 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, uint_t ofs; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 0, &name); + status = pvfs_resolve_name(pvfs, req, unl->in.pattern, + PVFS_RESOLVE_WILDCARD, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index d5a7d17a31..269a2cc863 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -276,3 +276,40 @@ NTSTATUS pvfs_doseas_save(struct pvfs_state *pvfs, struct pvfs_filename *name, i return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSEAS_NAME, eas, (ndr_push_flags_fn_t)ndr_push_xattr_DosEAs); } + + +/* + load the set of streams from extended attributes +*/ +NTSTATUS pvfs_streams_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosStreams *streams) +{ + NTSTATUS status; + ZERO_STRUCTP(streams); + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + status = pvfs_xattr_ndr_load(pvfs, streams, name->full_name, fd, + XATTR_DOSSTREAMS_NAME, + streams, + (ndr_pull_flags_fn_t)ndr_pull_xattr_DosStreams); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + return NT_STATUS_OK; + } + return status; +} + +/* + save the set of streams into filesystem xattr +*/ +NTSTATUS pvfs_streams_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosStreams *streams) +{ + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, + XATTR_DOSSTREAMS_NAME, + streams, + (ndr_push_flags_fn_t)ndr_push_xattr_DosStreams); +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e5712e3e7d..2b4eef04ba 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -161,8 +161,7 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs, NTSTATUS status; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, cp->in.path, - PVFS_RESOLVE_NO_WILDCARD, &name); + status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 46cc38c1f8..645d293a6d 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -169,7 +169,7 @@ struct pvfs_mangle_context { /* flags to pvfs_resolve_name() */ -#define PVFS_RESOLVE_NO_WILDCARD (1<<0) +#define PVFS_RESOLVE_WILDCARD (1<<0) #define PVFS_RESOLVE_STREAMS (1<<1) /* flags in pvfs->flags */ -- cgit From ae7caf08c1f47f3ad08856cfea2a3e6e956b48ab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 05:58:04 +0000 Subject: r3798: added support for alternate data streams in xattrs into pvfs. The trickiest part about this was getting the sharing and locking rules right, as alternate streams are separate locking spaces from the main file for the purposes of byte range locking, and separate for most share violation rules. I suspect there are still problems with delete on close with alternate data streams. I'll look at that next. (This used to be commit b6452c4a2068cf7e837778559da002ae191b508a) --- source4/ntvfs/common/opendb.c | 15 +- source4/ntvfs/posix/pvfs_fileinfo.c | 1 + source4/ntvfs/posix/pvfs_lock.c | 18 +- source4/ntvfs/posix/pvfs_open.c | 126 ++++++++++--- source4/ntvfs/posix/pvfs_qfileinfo.c | 16 +- source4/ntvfs/posix/pvfs_read.c | 13 +- source4/ntvfs/posix/pvfs_rename.c | 10 +- source4/ntvfs/posix/pvfs_resolve.c | 45 ++++- source4/ntvfs/posix/pvfs_setfileinfo.c | 28 ++- source4/ntvfs/posix/pvfs_shortname.c | 23 +-- source4/ntvfs/posix/pvfs_streams.c | 322 +++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_unlink.c | 33 +++- source4/ntvfs/posix/pvfs_util.c | 27 +++ source4/ntvfs/posix/pvfs_write.c | 16 +- source4/ntvfs/posix/pvfs_xattr.c | 115 +++++++++++- source4/ntvfs/posix/vfs_posix.h | 13 +- 16 files changed, 718 insertions(+), 103 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index a07b657c33..64bed53c8b 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -54,6 +54,7 @@ struct odb_context { struct odb_entry { servid_t server; void *file_handle; + uint32_t stream_id; uint32_t share_access; uint32_t create_options; uint32_t access_mask; @@ -167,14 +168,20 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) return False; } - /* check the basic share access */ + /* data IO access masks. This is skipped if the two open handles + are on different streams (as in that case the masks don't + interact) */ + if (e1->stream_id != e2->stream_id) { + return False; + } + CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_WRITE_APPEND, NTCREATEX_SHARE_ACCESS_WRITE); CHECK_MASK(e2->access_mask, e1->share_access, SA_RIGHT_FILE_WRITE_APPEND, NTCREATEX_SHARE_ACCESS_WRITE); - + CHECK_MASK(e1->access_mask, e2->share_access, SA_RIGHT_FILE_READ_EXEC, NTCREATEX_SHARE_ACCESS_READ); @@ -203,6 +210,7 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) rules */ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, + uint32_t stream_id, uint32_t share_access, uint32_t create_options, uint32_t access_mask) { @@ -217,6 +225,7 @@ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, e.server = odb->server; e.file_handle = file_handle; + e.stream_id = stream_id; e.share_access = share_access; e.create_options = create_options; e.access_mask = access_mask; @@ -273,6 +282,7 @@ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) e.server = odb->server; e.file_handle = NULL; + e.stream_id = 0; e.share_access = 0; e.create_options = 0; e.access_mask = 0; @@ -496,6 +506,7 @@ NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key, e.server = odb->server; e.file_handle = NULL; + e.stream_id = 0; e.share_access = share_access; e.create_options = create_options; e.access_mask = access_mask; diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 2419893049..dbf18edcce 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -136,3 +136,4 @@ mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32 attrib) return mode; } + diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index c0d0133f03..74ee48ba15 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -41,7 +41,7 @@ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, } return brl_locktest(pvfs->brl_context, - &f->handle->locking_key, + &f->handle->brl_locking_key, f->fnum, smbpid, offset, count, rw); @@ -73,7 +73,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, /* undo the locks we just did */ for (i=i-1;i>=0;i--) { brl_unlock(pvfs->brl_context, - &f->handle->locking_key, + &f->handle->brl_locking_key, locks[i].pid, f->fnum, locks[i].offset, @@ -118,7 +118,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas DLIST_REMOVE(f->pending_list, pending); status = brl_lock(pvfs->brl_context, - &f->handle->locking_key, + &f->handle->brl_locking_key, req->smbpid, f->fnum, locks[pending->pending_lock].offset, @@ -134,7 +134,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas if (NT_STATUS_IS_OK(status) || timed_out) { NTSTATUS status2; status2 = brl_remove_pending(pvfs->brl_context, - &f->handle->locking_key, pending); + &f->handle->brl_locking_key, pending); if (!NT_STATUS_IS_OK(status2)) { DEBUG(0,("pvfs_lock: failed to remove pending lock - %s\n", nt_errstr(status2))); } @@ -171,7 +171,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas } status = brl_lock(pvfs->brl_context, - &f->handle->locking_key, + &f->handle->brl_locking_key, req->smbpid, f->fnum, locks[i].offset, @@ -216,7 +216,7 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) if (f->lock_count || f->pending_list) { DEBUG(5,("pvfs_lock: removing %.0f locks on close\n", (double)f->lock_count)); - brl_close(f->pvfs->brl_context, &f->handle->locking_key, f->fnum); + brl_close(f->pvfs->brl_context, &f->handle->brl_locking_key, f->fnum); f->lock_count = 0; } @@ -338,7 +338,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, for (i=0;ilockx.in.ulock_cnt;i++) { status = brl_unlock(pvfs->brl_context, - &f->handle->locking_key, + &f->handle->brl_locking_key, locks[i].pid, f->fnum, locks[i].offset, @@ -357,7 +357,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } status = brl_lock(pvfs->brl_context, - &f->handle->locking_key, + &f->handle->brl_locking_key, locks[i].pid, f->fnum, locks[i].offset, @@ -381,7 +381,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, /* undo the locks we just did */ for (i=i-1;i>=0;i--) { brl_unlock(pvfs->brl_context, - &f->handle->locking_key, + &f->handle->brl_locking_key, locks[i].pid, f->fnum, locks[i].offset, diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 4f089a8c07..a772feb623 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -104,7 +104,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, uint32_t create_action; if (name->stream_name) { - return NT_STATUS_OBJECT_NAME_INVALID; + return NT_STATUS_NOT_A_DIRECTORY; } /* if the client says it must be a directory, and it isn't, @@ -163,7 +163,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); f->handle->fd = -1; - f->handle->locking_key = data_blob(NULL, 0); + f->handle->odb_locking_key = data_blob(NULL, 0); + f->handle->brl_locking_key = data_blob(NULL, 0); f->handle->create_options = io->generic.in.create_options; f->handle->seek_offset = 0; f->handle->position = 0; @@ -243,7 +244,7 @@ static int pvfs_handle_destructor(void *p) struct odb_lock *lck; NTSTATUS status; - lck = odb_lock(h, h->pvfs->odb_context, &h->locking_key); + lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); if (lck == NULL) { DEBUG(0,("Unable to lock opendb for close\n")); return 0; @@ -278,9 +279,8 @@ static int pvfs_fnum_destructor(void *p) /* - form the lock context used for byte range locking and opendb - locking. Note that we must zero here to take account of - possible padding on some architectures + form the lock context used for opendb locking. Note that we must + zero here to take account of possible padding on some architectures */ static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, TALLOC_CTX *mem_ctx, DATA_BLOB *key) @@ -302,6 +302,37 @@ static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, return NT_STATUS_OK; } +/* + form the lock context used for byte range locking. This is separate + from the locking key used for opendb locking as it needs to take + account of file streams (each stream is a separate byte range + locking space) +*/ +static NTSTATUS pvfs_brl_locking_key(struct pvfs_filename *name, + TALLOC_CTX *mem_ctx, DATA_BLOB *key) +{ + DATA_BLOB odb_key; + NTSTATUS status; + status = pvfs_locking_key(name, mem_ctx, &odb_key); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (name->stream_name == NULL) { + *key = odb_key; + return NT_STATUS_OK; + } + *key = data_blob_talloc(mem_ctx, NULL, + odb_key.length + strlen(name->stream_name) + 1); + if (key->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + memcpy(key->data, odb_key.data, odb_key.length); + memcpy(key->data + odb_key.length, + name->stream_name, strlen(name->stream_name)+1); + data_blob_free(&odb_key); + return NT_STATUS_OK; +} + /* create a new file @@ -361,6 +392,16 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return pvfs_map_errno(pvfs, errno); } + /* if this was a stream create then create the stream as well */ + if (name->stream_name) { + status = pvfs_stream_create(pvfs, name, fd); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; + } + } + /* re-resolve the open fd */ status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { @@ -379,7 +420,14 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* form the lock context used for byte range locking and opendb locking */ - status = pvfs_locking_key(name, f->handle, &f->handle->locking_key); + status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; + } + + status = pvfs_brl_locking_key(name, f->handle, &f->handle->brl_locking_key); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, fnum); close(fd); @@ -387,7 +435,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } /* grab a lock on the open file record */ - lck = odb_lock(req, pvfs->odb_context, &f->handle->locking_key); + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); if (lck == NULL) { DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", name->full_name)); @@ -398,7 +446,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_open_file(lck, f->handle, + status = odb_open_file(lck, f->handle, name->stream_id, share_access, create_options, access_mask); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { @@ -463,7 +511,7 @@ struct pvfs_open_retry { struct smbsrv_request *req; union smb_open *io; void *wait_handle; - DATA_BLOB locking_key; + DATA_BLOB odb_locking_key; }; /* destroy a pending open request */ @@ -471,9 +519,9 @@ static int pvfs_retry_destructor(void *ptr) { struct pvfs_open_retry *r = ptr; struct pvfs_state *pvfs = r->ntvfs->private_data; - if (r->locking_key.data) { + if (r->odb_locking_key.data) { struct odb_lock *lck; - lck = odb_lock(r->req, pvfs->odb_context, &r->locking_key); + lck = odb_lock(r->req, pvfs->odb_context, &r->odb_locking_key); if (lck != NULL) { odb_remove_pending(lck, r); } @@ -512,7 +560,7 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) /* the pending odb entry is already removed. We use a null locking key to indicate this */ - data_blob_free(&r->locking_key); + data_blob_free(&r->odb_locking_key); talloc_free(r); /* try the open again, which could trigger another retry setup @@ -649,9 +697,9 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, r->ntvfs = ntvfs; r->req = req; r->io = io; - r->locking_key = data_blob_talloc(r, - f->handle->locking_key.data, - f->handle->locking_key.length); + r->odb_locking_key = data_blob_talloc(r, + f->handle->odb_locking_key.data, + f->handle->odb_locking_key.length); end_time = timeval_add(&req->request_time, 0, pvfs->sharing_violation_delay); @@ -693,14 +741,14 @@ static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs, } if (io->t2open.in.open_func & OPENX_OPEN_FUNC_CREATE) { - if (!name->exists) return NT_STATUS_ACCESS_DENIED; + if (!name->stream_exists) return NT_STATUS_ACCESS_DENIED; } if (io->t2open.in.open_func & OPENX_OPEN_FUNC_TRUNC) { - if (name->exists) return NT_STATUS_ACCESS_DENIED; + if (name->stream_exists) return NT_STATUS_ACCESS_DENIED; return NT_STATUS_OBJECT_NAME_NOT_FOUND; } if ((io->t2open.in.open_func & 0xF) == OPENX_OPEN_FUNC_FAIL) { - if (!name->exists) return NT_STATUS_ACCESS_DENIED; + if (!name->stream_exists) return NT_STATUS_ACCESS_DENIED; return NT_STATUS_OBJECT_NAME_COLLISION; } @@ -725,6 +773,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t create_options; uint32_t share_access; uint32_t access_mask; + BOOL stream_existed; if (io->generic.level == RAW_OPEN_T2OPEN) { return pvfs_open_t2open(ntvfs, req, io); @@ -777,21 +826,21 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, break; case NTCREATEX_DISP_OPEN: - if (!name->exists) { + if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } flags = 0; break; case NTCREATEX_DISP_OVERWRITE: - if (!name->exists) { + if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } flags = O_TRUNC; break; case NTCREATEX_DISP_CREATE: - if (name->exists) { + if (name->stream_exists) { return NT_STATUS_OBJECT_NAME_COLLISION; } flags = 0; @@ -876,14 +925,20 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* form the lock context used for byte range locking and opendb locking */ - status = pvfs_locking_key(name, f->handle, &f->handle->locking_key); + status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, f->fnum); + return status; + } + + status = pvfs_brl_locking_key(name, f->handle, &f->handle->brl_locking_key); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, f->fnum); return status; } /* get a lock on this file before the actual open */ - lck = odb_lock(req, pvfs->odb_context, &f->handle->locking_key); + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); if (lck == NULL) { DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", name->full_name)); @@ -902,7 +957,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, f->handle, + status = odb_open_file(lck, f->handle, f->handle->name->stream_id, share_access, create_options, access_mask); /* on a sharing violation we need to retry when the file is closed by @@ -928,6 +983,17 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->fd = fd; + stream_existed = name->stream_exists; + + /* if this was a stream create then create the stream as well */ + if (!name->stream_exists) { + status = pvfs_stream_create(pvfs, f->handle->name, fd); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } + } + /* re-resolve the open fd */ status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name); if (!NT_STATUS_IS_OK(status)) { @@ -935,8 +1001,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } - if (io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE || - io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE_IF) { + if (f->handle->name->stream_id == 0 && + (io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE || + io->generic.in.open_disposition == NTCREATEX_DISP_OVERWRITE_IF)) { /* for overwrite we need to replace file permissions */ uint32_t attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE; mode_t mode = pvfs_fileperms(pvfs, attrib); @@ -956,7 +1023,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, io->generic.out.oplock_level = NO_OPLOCK; io->generic.out.fnum = f->fnum; - io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; + io->generic.out.create_action = stream_existed? + NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; io->generic.out.write_time = name->dos.write_time; @@ -1069,7 +1137,7 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, return NT_STATUS_CANNOT_DELETE; } - lck = odb_lock(req, pvfs->odb_context, &f->handle->locking_key); + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); if (lck == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 3eaa7865e8..3959fbfc16 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -148,17 +148,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, case RAW_FILEINFO_STREAM_INFO: case RAW_FILEINFO_STREAM_INFORMATION: - info->stream_info.out.num_streams = 1; - info->stream_info.out.streams = talloc_array_p(mem_ctx, - struct stream_struct, 1); - if (!info->stream_info.out.streams) { - return NT_STATUS_NO_MEMORY; - } - info->stream_info.out.streams[0].size = name->st.st_size; - info->stream_info.out.streams[0].alloc_size = name->dos.alloc_size; - info->stream_info.out.streams[0].stream_name.s = - talloc_strdup(info->stream_info.out.streams, "::$DATA"); - return NT_STATUS_OK; + return pvfs_stream_information(pvfs, mem_ctx, name, fd, &info->stream_info.out); case RAW_FILEINFO_COMPRESSION_INFO: case RAW_FILEINFO_COMPRESSION_INFORMATION: @@ -219,12 +209,12 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, 0, &name); + status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; } - if (!name->exists) { + if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 0f7d3b4b0c..793a97ba62 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -71,10 +71,15 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return status; } - ret = pread(f->handle->fd, - rd->readx.out.data, - maxcnt, - rd->readx.in.offset); + if (f->handle->name->stream_name) { + ret = pvfs_stream_read(pvfs, f->handle, + rd->readx.out.data, maxcnt, rd->readx.in.offset); + } else { + ret = pread(f->handle->fd, + rd->readx.out.data, + maxcnt, + rd->readx.in.offset); + } if (ret == -1) { return pvfs_map_errno(pvfs, errno); } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index efaf63ba9d..cba9cace59 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -317,16 +317,22 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, } /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.old_name, 0, &name1); + status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.old_name, + PVFS_RESOLVE_WILDCARD, &name1); if (!NT_STATUS_IS_OK(status)) { return status; } - status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.new_name, 0, &name2); + status = pvfs_resolve_name(pvfs, req, ren->ntrename.in.new_name, + PVFS_RESOLVE_WILDCARD, &name2); if (!NT_STATUS_IS_OK(status)) { return status; } + if (name1->has_wildcard || name2->has_wildcard) { + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; + } + if (!name1->exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 576b0d9db4..302ccdae60 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -181,6 +181,37 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * return NT_STATUS_OK; } +/* + parse a alternate data stream name +*/ +static NTSTATUS parse_stream_name(struct pvfs_filename *name, const char *s) +{ + char *p; + name->stream_name = talloc_strdup(name, s+1); + if (name->stream_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + p = strchr_m(name->stream_name, ':'); + if (p == NULL) { + name->stream_id = pvfs_name_hash(name->stream_name, + strlen(name->stream_name)); + return NT_STATUS_OK; + } + if (StrCaseCmp(p, ":$DATA") != 0) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + *p = 0; + if (strcmp(name->stream_name, "") == 0) { + name->stream_name = NULL; + name->stream_id = 0; + } else { + name->stream_id = pvfs_name_hash(name->stream_name, + strlen(name->stream_name)); + } + + return NT_STATUS_OK; +} + /* convert a CIFS pathname to a unix pathname. Note that this does NOT @@ -194,9 +225,11 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, uint_t flags, struct pvfs_filename *name) { char *ret, *p, *p_start; + NTSTATUS status; name->original_name = talloc_strdup(name, cifs_name); name->stream_name = NULL; + name->stream_id = 0; name->has_wildcard = False; while (*cifs_name == '\\') { @@ -242,9 +275,12 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, if (!(flags & PVFS_RESOLVE_STREAMS)) { return NT_STATUS_ILLEGAL_CHARACTER; } - name->stream_name = talloc_strdup(name, p+1); - if (name->stream_name == NULL) { - return NT_STATUS_NO_MEMORY; + if (name->has_wildcard) { + return NT_STATUS_ILLEGAL_CHARACTER; + } + status = parse_stream_name(name, p); + if (!NT_STATUS_IS_OK(status)) { + return status; } *p-- = 0; break; @@ -420,6 +456,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, } (*name)->exists = False; + (*name)->stream_exists = False; /* do the basic conversion to a unix formatted path, also checking for allowable characters */ @@ -485,9 +522,11 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, } (*name)->exists = True; + (*name)->stream_exists = True; (*name)->has_wildcard = False; (*name)->original_name = talloc_strdup(*name, fname); (*name)->stream_name = NULL; + (*name)->stream_id = 0; status = pvfs_fill_dos_info(pvfs, *name, -1); diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 7ba64979c3..ede07983b3 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -300,17 +300,24 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file size */ if (newstats.st.st_size != h->name->st.st_size) { - int ret; if (h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (f->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { - ret = ftruncate(h->fd, newstats.st.st_size); + if (h->name->stream_name) { + status = pvfs_stream_truncate(pvfs, h->name, h->fd, newstats.st.st_size); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } else { - ret = truncate(h->name->full_name, newstats.st.st_size); - } - if (ret == -1) { - return pvfs_map_errno(pvfs, errno); + int ret; + if (f->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + ret = ftruncate(h->fd, newstats.st.st_size); + } else { + ret = truncate(h->name->full_name, newstats.st.st_size); + } + if (ret == -1) { + return pvfs_map_errno(pvfs, errno); + } } } @@ -461,7 +468,12 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file size */ if (newstats.st.st_size != name->st.st_size) { - if (truncate(name->full_name, newstats.st.st_size) == -1) { + if (name->stream_name) { + status = pvfs_stream_truncate(pvfs, name, -1, newstats.st.st_size); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } else if (truncate(name->full_name, newstats.st.st_size) == -1) { return pvfs_map_errno(pvfs, errno); } } diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 3627820bb0..c0fc2fb136 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -36,11 +36,6 @@ for simplicity, we only allow ascii characters in 8.3 names */ - /* hash alghorithm changed to FNV1 by idra@samba.org (Simo Sorce). - * see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a - * discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors - */ - /* =============================================================================== NOTE NOTE NOTE!!! @@ -83,10 +78,6 @@ #define DEFAULT_MANGLE_PREFIX 4 -#define FNV1_PRIME 0x01000193 -/*the following number is a fnv1 of the string: idra@samba.org 2002 */ -#define FNV1_INIT 0xa6b93095 - #define MANGLE_BASECHARS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" #define FLAG_CHECK(c, flag) (ctx->char_flags[(uint8_t)(c)] & (flag)) @@ -105,19 +96,7 @@ static const char *reserved_names[] = static uint32_t mangle_hash(struct pvfs_mangle_context *ctx, const char *key, size_t length) { - uint32_t value = FNV1_INIT; - codepoint_t c; - size_t c_size; - - while (*key && length--) { - c = next_codepoint(key, &c_size); - c = toupper_w(c); - value *= (uint32_t)FNV1_PRIME; - value ^= (uint32_t)c; - key += c_size; - } - - return (value % ctx->mangle_modulus); + return pvfs_name_hash(key, length) % ctx->mangle_modulus; } /* diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index b71ff640e5..7edf111fc9 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -25,3 +25,325 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" + +/* + return the list of file streams for RAW_FILEINFO_STREAM_INFORMATION +*/ +NTSTATUS pvfs_stream_information(struct pvfs_state *pvfs, + TALLOC_CTX *mem_ctx, + struct pvfs_filename *name, int fd, + struct stream_information *info) +{ + struct xattr_DosStreams *streams; + int i; + NTSTATUS status; + + streams = talloc_p(mem_ctx, struct xattr_DosStreams); + if (streams == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_streams_load(pvfs, name, fd, streams); + if (!NT_STATUS_IS_OK(status)) { + ZERO_STRUCTP(streams); + } + + info->num_streams = streams->num_streams+1; + info->streams = talloc_array_p(mem_ctx, struct stream_struct, info->num_streams); + if (!info->streams) { + return NT_STATUS_NO_MEMORY; + } + + info->streams[0].size = name->st.st_size; + info->streams[0].alloc_size = name->dos.alloc_size; + info->streams[0].stream_name.s = talloc_strdup(info->streams, "::$DATA"); + + for (i=0;inum_streams;i++) { + info->streams[i+1].size = streams->streams[i].size; + info->streams[i+1].alloc_size = streams->streams[i].alloc_size; + info->streams[i+1].stream_name.s = talloc_asprintf(streams->streams, + ":%s:$DATA", + streams->streams[i].name); + } + + return NT_STATUS_OK; +} + + +/* + fill in the stream information for a name +*/ +NTSTATUS pvfs_stream_info(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +{ + struct xattr_DosStreams *streams; + int i; + NTSTATUS status; + + /* the NULL stream always exists */ + if (name->stream_name == NULL) { + name->stream_exists = True; + return NT_STATUS_OK; + } + + streams = talloc_p(name, struct xattr_DosStreams); + if (streams == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_streams_load(pvfs, name, fd, streams); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(streams); + return status; + } + + for (i=0;inum_streams;i++) { + struct xattr_DosStream *s = &streams->streams[i]; + if (StrCaseCmp(s->name, name->stream_name) == 0) { + name->dos.alloc_size = s->alloc_size; + name->st.st_size = s->size; + name->stream_exists = True; + talloc_free(streams); + return NT_STATUS_OK; + } + } + + talloc_free(streams); + + name->dos.alloc_size = 0; + name->st.st_size = 0; + name->stream_exists = False; + + return NT_STATUS_OK; +} + + +/* + update size information for a stream +*/ +static NTSTATUS pvfs_stream_update_size(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + off_t size) +{ + struct xattr_DosStreams *streams; + int i; + NTSTATUS status; + + streams = talloc_p(name, struct xattr_DosStreams); + if (streams == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_streams_load(pvfs, name, fd, streams); + if (!NT_STATUS_IS_OK(status)) { + ZERO_STRUCTP(streams); + } + + for (i=0;inum_streams;i++) { + struct xattr_DosStream *s = &streams->streams[i]; + if (StrCaseCmp(s->name, name->stream_name) == 0) { + s->size = size; + s->alloc_size = size; + break; + } + } + + if (i == streams->num_streams) { + struct xattr_DosStream *s; + streams->streams = talloc_realloc_p(streams, streams->streams, + struct xattr_DosStream, + streams->num_streams+1); + if (streams->streams == NULL) { + talloc_free(streams); + return NT_STATUS_NO_MEMORY; + } + streams->num_streams++; + s = &streams->streams[i]; + + s->flags = XATTR_STREAM_FLAG_INTERNAL; + s->size = size; + s->alloc_size = size; + s->name = name->stream_name; + } + + status = pvfs_streams_save(pvfs, name, fd, streams); + talloc_free(streams); + + return status; +} + + +/* + create the xattr for a alternate data stream +*/ +NTSTATUS pvfs_stream_create(struct pvfs_state *pvfs, + struct pvfs_filename *name, + int fd) +{ + NTSTATUS status; + status = pvfs_xattr_create(pvfs, name->full_name, fd, + XATTR_DOSSTREAM_PREFIX, name->stream_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + return pvfs_stream_update_size(pvfs, name, fd, 0); +} + +/* + delete the xattr for a alternate data stream +*/ +NTSTATUS pvfs_stream_delete(struct pvfs_state *pvfs, + struct pvfs_filename *name, + int fd) +{ + NTSTATUS status; + struct xattr_DosStreams *streams; + int i; + + status = pvfs_xattr_delete(pvfs, name->full_name, fd, + XATTR_DOSSTREAM_PREFIX, name->stream_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + streams = talloc_p(name, struct xattr_DosStreams); + if (streams == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_streams_load(pvfs, name, fd, streams); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(streams); + return status; + } + + for (i=0;inum_streams;i++) { + struct xattr_DosStream *s = &streams->streams[i]; + if (StrCaseCmp(s->name, name->stream_name) == 0) { + memmove(s, s+1, (streams->num_streams - (i+1)) * sizeof(*s)); + streams->num_streams--; + break; + } + } + + status = pvfs_streams_save(pvfs, name, fd, streams); + talloc_free(streams); + + return status; +} + +/* + the equvalent of pread() on a stream +*/ +ssize_t pvfs_stream_read(struct pvfs_state *pvfs, + struct pvfs_file_handle *h, void *data, size_t count, off_t offset) +{ + NTSTATUS status; + DATA_BLOB blob; + if (count == 0) { + return 0; + } + status = pvfs_xattr_load(pvfs, h, h->name->full_name, h->fd, XATTR_DOSSTREAM_PREFIX, + h->name->stream_name, offset+count, &blob); + if (!NT_STATUS_IS_OK(status)) { + errno = EIO; + return -1; + } + if (offset >= blob.length) { + data_blob_free(&blob); + return 0; + } + if (count > blob.length - offset) { + count = blob.length - offset; + } + memcpy(data, blob.data + offset, count); + data_blob_free(&blob); + return count; +} + + +/* + the equvalent of pwrite() on a stream +*/ +ssize_t pvfs_stream_write(struct pvfs_state *pvfs, + struct pvfs_file_handle *h, const void *data, size_t count, off_t offset) +{ + NTSTATUS status; + DATA_BLOB blob; + if (count == 0) { + return 0; + } + /* we have to load the existing stream, then modify, then save */ + status = pvfs_xattr_load(pvfs, h, h->name->full_name, h->fd, XATTR_DOSSTREAM_PREFIX, + h->name->stream_name, offset+count, &blob); + if (!NT_STATUS_IS_OK(status)) { + blob = data_blob(NULL, 0); + } + if (count+offset > blob.length) { + blob.data = talloc_realloc(blob.data, blob.data, count+offset); + if (blob.data == NULL) { + errno = ENOMEM; + return -1; + } + if (offset > blob.length) { + memset(blob.data+blob.length, 0, offset - blob.length); + } + blob.length = count+offset; + } + memcpy(blob.data + offset, data, count); + + status = pvfs_xattr_save(pvfs, h->name->full_name, h->fd, XATTR_DOSSTREAM_PREFIX, + h->name->stream_name, &blob); + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&blob); + /* getting this error mapping right is probably + not worth it */ + errno = ENOSPC; + return -1; + } + + status = pvfs_stream_update_size(pvfs, h->name, h->fd, blob.length); + + data_blob_free(&blob); + + if (!NT_STATUS_IS_OK(status)) { + errno = EIO; + return -1; + } + + return count; +} + +/* + the equvalent of truncate() on a stream +*/ +NTSTATUS pvfs_stream_truncate(struct pvfs_state *pvfs, + struct pvfs_filename *name, int fd, off_t length) +{ + NTSTATUS status; + DATA_BLOB blob; + /* we have to load the existing stream, then modify, then save */ + status = pvfs_xattr_load(pvfs, name, name->full_name, fd, XATTR_DOSSTREAM_PREFIX, + name->stream_name, length, &blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (length <= blob.length) { + blob.length = length; + } else if (length > blob.length) { + blob.data = talloc_realloc(blob.data, blob.data, length); + if (blob.data == NULL) { + return NT_STATUS_NO_MEMORY; + } + memset(blob.data+blob.length, 0, length - blob.length); + blob.length = length; + } + + status = pvfs_xattr_save(pvfs, name->full_name, fd, XATTR_DOSSTREAM_PREFIX, + name->stream_name, &blob); + data_blob_free(&blob); + + if (NT_STATUS_IS_OK(status)) { + status = pvfs_stream_update_size(pvfs, name, fd, blob.length); + } + + return status; +} diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 8dc9f60ad8..434577a862 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -24,6 +24,33 @@ #include "vfs_posix.h" +/* + unlink a stream + */ +static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct pvfs_filename *name, + uint16_t attrib) +{ + NTSTATUS status; + + if (!name->stream_exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* make sure its matches the given attributes */ + status = pvfs_match_attrib(pvfs, name, attrib, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_can_delete(pvfs, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return pvfs_stream_delete(pvfs, name, -1); +} + + /* unlink one file */ @@ -86,7 +113,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, unl->in.pattern, - PVFS_RESOLVE_WILDCARD, &name); + PVFS_RESOLVE_WILDCARD | PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -100,6 +127,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } + if (name->stream_name) { + return pvfs_unlink_stream(pvfs, name, unl->in.attrib); + } + /* get list of matching files */ status = pvfs_list_start(pvfs, name, req, &dir); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 6503769013..9f617d39d4 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -160,3 +160,30 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs, return NT_STATUS_OK; } + + +/* + hash a string of the specified length. The string does not need to be + null terminated + + hash alghorithm changed to FNV1 by idra@samba.org (Simo Sorce). + see http://www.isthe.com/chongo/tech/comp/fnv/index.html for a + discussion on Fowler / Noll / Vo (FNV) Hash by one of it's authors +*/ +uint32_t pvfs_name_hash(const char *key, size_t length) +{ + const uint32_t fnv1_prime = 0x01000193; + const uint32_t fnv1_init = 0xa6b93095; + uint32_t value = fnv1_init; + + while (*key && length--) { + size_t c_size; + codepoint_t c = next_codepoint(key, &c_size); + c = toupper_w(c); + value *= fnv1_prime; + value ^= (uint32_t)c; + key += c_size; + } + + return value; +} diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index c24de08a13..3f6e8d908a 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -60,10 +60,18 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return status; } - ret = pwrite(f->handle->fd, - wr->writex.in.data, - wr->writex.in.count, - wr->writex.in.offset); + if (f->handle->name->stream_name) { + ret = pvfs_stream_write(pvfs, + f->handle, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + } else { + ret = pwrite(f->handle->fd, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + } if (ret == -1) { if (errno == EFBIG) { return NT_STATUS_INVALID_PARAMETER; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 269a2cc863..ff0c0f5116 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -100,6 +100,31 @@ static NTSTATUS push_xattr_blob(struct pvfs_state *pvfs, #endif } + +/* + delete a xattr +*/ +static NTSTATUS delete_xattr(struct pvfs_state *pvfs, const char *attr_name, + const char *fname, int fd) +{ +#if HAVE_XATTR_SUPPORT + int ret; + + if (fd != -1) { + ret = fremovexattr(fd, attr_name); + } else { + ret = removexattr(fname, attr_name); + } + if (ret == -1) { + return pvfs_map_errno(pvfs, errno); + } + + return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif +} + /* load a NDR structure from a xattr */ @@ -159,6 +184,12 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name TALLOC_CTX *mem_ctx = talloc(name, 0); struct xattr_DosInfo1 *info1; + if (name->stream_name != NULL) { + name->stream_exists = False; + } else { + name->stream_exists = True; + } + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_OK; } @@ -209,9 +240,11 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name talloc_free(mem_ctx); return NT_STATUS_INVALID_LEVEL; } - talloc_free(mem_ctx); - return NT_STATUS_OK; + + status = pvfs_stream_info(pvfs, name, fd); + + return status; } @@ -313,3 +346,81 @@ NTSTATUS pvfs_streams_save(struct pvfs_state *pvfs, struct pvfs_filename *name, streams, (ndr_push_flags_fn_t)ndr_push_xattr_DosStreams); } + +/* + create a zero length xattr with the given name +*/ +NTSTATUS pvfs_xattr_create(struct pvfs_state *pvfs, + const char *fname, int fd, + const char *attr_prefix, + const char *attr_name) +{ + NTSTATUS status; + DATA_BLOB blob = data_blob(NULL, 0); + char *aname = talloc_asprintf(NULL, "%s%s", attr_prefix, attr_name); + if (aname == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = push_xattr_blob(pvfs, aname, fname, fd, &blob); + talloc_free(aname); + return status; +} + + +/* + delete a xattr with the given name +*/ +NTSTATUS pvfs_xattr_delete(struct pvfs_state *pvfs, + const char *fname, int fd, + const char *attr_prefix, + const char *attr_name) +{ + NTSTATUS status; + char *aname = talloc_asprintf(NULL, "%s%s", attr_prefix, attr_name); + if (aname == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = delete_xattr(pvfs, aname, fname, fd); + talloc_free(aname); + return status; +} + +/* + load a xattr with the given name +*/ +NTSTATUS pvfs_xattr_load(struct pvfs_state *pvfs, + TALLOC_CTX *mem_ctx, + const char *fname, int fd, + const char *attr_prefix, + const char *attr_name, + size_t estimated_size, + DATA_BLOB *blob) +{ + NTSTATUS status; + char *aname = talloc_asprintf(mem_ctx, "%s%s", attr_prefix, attr_name); + if (aname == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = pull_xattr_blob(pvfs, mem_ctx, aname, fname, fd, estimated_size, blob); + talloc_free(aname); + return status; +} + +/* + save a xattr with the given name +*/ +NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, + const char *fname, int fd, + const char *attr_prefix, + const char *attr_name, + const DATA_BLOB *blob) +{ + NTSTATUS status; + char *aname = talloc_asprintf(NULL, "%s%s", attr_prefix, attr_name); + if (aname == NULL) { + return NT_STATUS_NO_MEMORY; + } + status = push_xattr_blob(pvfs, aname, fname, fd, blob); + talloc_free(aname); + return status; +} diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 645d293a6d..09d4bce085 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -76,9 +76,11 @@ struct pvfs_dos_fileinfo { struct pvfs_filename { const char *original_name; char *full_name; - const char *stream_name; + const char *stream_name; /* does not include :$DATA suffix */ + uint32_t stream_id; /* this uses a hash, so is probabilistic */ BOOL has_wildcard; - BOOL exists; + BOOL exists; /* true if the base filename exists */ + BOOL stream_exists; /* true if the stream exists */ struct stat st; struct pvfs_dos_fileinfo dos; }; @@ -96,8 +98,11 @@ struct pvfs_file_handle { struct pvfs_filename *name; - /* a unique file key to be used for file locking */ - DATA_BLOB locking_key; + /* a unique file key to be used for open file locking */ + DATA_BLOB odb_locking_key; + + /* a unique file key to be used for byte range locking */ + DATA_BLOB brl_locking_key; uint32_t create_options; -- cgit From 5a34ef4df6152f5e970afbfb463d4665a823deb7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 06:30:06 +0000 Subject: r3799: - added the bit for FS_ATTR_NAMED_STREAMS support into qfsinfo filesystem attribute reply - pvfs passes the RAW-STREAMS test (This used to be commit c1a48a7542a52df734b54031f405d574e4c891e3) --- source4/ntvfs/posix/pvfs_fsinfo.c | 4 ++-- source4/ntvfs/posix/pvfs_resolve.c | 4 ++++ source4/ntvfs/posix/vfs_posix.c | 10 ++++++++++ source4/ntvfs/posix/vfs_posix.h | 3 +++ 4 files changed, 19 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 7b2226579a..6d92713ac7 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -115,9 +115,9 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, case RAW_QFS_ATTRIBUTE_INFO: case RAW_QFS_ATTRIBUTE_INFORMATION: - fs->attribute_info.out.fs_attr = 0; + fs->attribute_info.out.fs_attr = pvfs->fs_attribs; fs->attribute_info.out.max_file_component_length = 255; - fs->attribute_info.out.fs_type.s = req->tcon->fs_type; + fs->attribute_info.out.fs_type.s = req->tcon->fs_type; return NT_STATUS_OK; case RAW_QFS_QUOTA_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 302ccdae60..7329968d6c 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -458,6 +458,10 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, (*name)->exists = False; (*name)->stream_exists = False; + if (!(pvfs->fs_attribs & FS_ATTR_NAMED_STREAMS)) { + flags &= ~PVFS_RESOLVE_STREAMS; + } + /* do the basic conversion to a unix formatted path, also checking for allowable characters */ status = pvfs_unix_path(pvfs, cifs_name, flags, *name); diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 2b4eef04ba..e02bd7aa32 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -55,6 +55,16 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) } pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); + + pvfs->fs_attribs = + FS_ATTR_CASE_SENSITIVE_SEARCH | + FS_ATTR_CASE_PRESERVED_NAMES | + FS_ATTR_UNICODE_ON_DISK | + FS_ATTR_SPARSE_FILES; + + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + pvfs->fs_attribs |= FS_ATTR_NAMED_STREAMS; + } } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 09d4bce085..a79c53ca2e 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -53,6 +53,9 @@ struct pvfs_state { /* the sharing violation timeout */ uint_t sharing_violation_delay; + + /* filesystem attributes (see FS_ATTR_*) */ + uint32_t fs_attribs; }; -- cgit From 856f663adc2459044f7a20c2974bcb41ed561f77 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 06:44:50 +0000 Subject: r3800: - fixed delete-on-close behaviour for streams - added a delete-on-close test to RAW-STREAMS - don't allow rename of streams at the moment (I need to work out if its supposed to be allowed first) (This used to be commit f4b2b1311da6e37ac0947a3419d89c77ebbd6b63) --- source4/ntvfs/posix/pvfs_open.c | 13 ++++++++++++- source4/ntvfs/posix/pvfs_setfileinfo.c | 8 +++++++- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a772feb623..d8f3342f0d 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -225,6 +225,16 @@ static int pvfs_handle_destructor(void *p) { struct pvfs_file_handle *h = p; + if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + h->name->stream_name) { + NTSTATUS status; + status = pvfs_stream_delete(h->pvfs, h->name, h->fd); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to delete stream '%s' on close of '%s'\n", + h->name->stream_name, h->name->full_name)); + } + } + if (h->fd != -1) { if (close(h->fd) != 0) { DEBUG(0,("pvfs_handle_destructor: close(%d) failed for %s - %s\n", @@ -233,7 +243,8 @@ static int pvfs_handle_destructor(void *p) h->fd = -1; } - if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + h->name->stream_name == NULL) { if (unlink(h->name->full_name) != 0) { DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", h->name->full_name, strerror(errno))); diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index ede07983b3..58a3372f82 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -48,6 +48,11 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } + /* don't allow stream renames for now */ + if (name->stream_name) { + return NT_STATUS_INVALID_PARAMETER; + } + /* w2k3 does not appear to allow relative rename */ if (r->root_fid != 0) { return NT_STATUS_INVALID_PARAMETER; @@ -366,7 +371,8 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct utimbuf unix_times; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, 0, &name); + status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, + PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From f4e5f3a498bce04312898dfe92104fafc1fc2aa2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 07:17:55 +0000 Subject: r3801: added allocation size rounding. This is needed for ifstest. (This used to be commit 8a6fa43156667f75e058c7d44b1c15a6cf7067b2) --- source4/ntvfs/posix/pvfs_fileinfo.c | 5 +++-- source4/ntvfs/posix/pvfs_setfileinfo.c | 4 ++++ source4/ntvfs/posix/pvfs_streams.c | 6 +++--- source4/ntvfs/posix/pvfs_util.c | 11 +++++++++++ source4/ntvfs/posix/pvfs_xattr.c | 3 ++- 5 files changed, 23 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index dbf18edcce..32c7ae34fa 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -93,7 +93,7 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.change_time += name->st.st_ctim.tv_nsec / 100; #endif name->dos.attrib = dos_mode_from_stat(pvfs, &name->st); - name->dos.alloc_size = name->st.st_size; + name->dos.alloc_size = pvfs_round_alloc_size(pvfs, name->st.st_size); name->dos.nlink = name->st.st_nlink; name->dos.ea_size = 0; name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; @@ -113,7 +113,8 @@ mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32 attrib) mode |= S_IXUSR | S_IXGRP | S_IXOTH; } - if (!(attrib & FILE_ATTRIBUTE_READONLY)) { + if (!(attrib & FILE_ATTRIBUTE_READONLY) || + (pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { mode |= S_IWUSR; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 58a3372f82..37d8a290b8 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -273,6 +273,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, if (newstats.dos.alloc_size < newstats.st.st_size) { newstats.st.st_size = newstats.dos.alloc_size; } + newstats.dos.alloc_size = pvfs_round_alloc_size(pvfs, + newstats.dos.alloc_size); break; case RAW_SFILEINFO_END_OF_FILE_INFO: @@ -443,6 +445,8 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, if (newstats.dos.alloc_size < newstats.st.st_size) { newstats.st.st_size = newstats.dos.alloc_size; } + newstats.dos.alloc_size = pvfs_round_alloc_size(pvfs, + newstats.dos.alloc_size); break; case RAW_SFILEINFO_END_OF_FILE_INFO: diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 7edf111fc9..13a4ca1265 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -99,7 +99,7 @@ NTSTATUS pvfs_stream_info(struct pvfs_state *pvfs, struct pvfs_filename *name, i for (i=0;inum_streams;i++) { struct xattr_DosStream *s = &streams->streams[i]; if (StrCaseCmp(s->name, name->stream_name) == 0) { - name->dos.alloc_size = s->alloc_size; + name->dos.alloc_size = pvfs_round_alloc_size(pvfs, s->alloc_size); name->st.st_size = s->size; name->stream_exists = True; talloc_free(streams); @@ -141,7 +141,7 @@ static NTSTATUS pvfs_stream_update_size(struct pvfs_state *pvfs, struct pvfs_fil struct xattr_DosStream *s = &streams->streams[i]; if (StrCaseCmp(s->name, name->stream_name) == 0) { s->size = size; - s->alloc_size = size; + s->alloc_size = pvfs_round_alloc_size(pvfs, size); break; } } @@ -160,7 +160,7 @@ static NTSTATUS pvfs_stream_update_size(struct pvfs_state *pvfs, struct pvfs_fil s->flags = XATTR_STREAM_FLAG_INTERNAL; s->size = size; - s->alloc_size = size; + s->alloc_size = pvfs_round_alloc_size(pvfs, size); s->name = name->stream_name; } diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 9f617d39d4..67dd9d22b3 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -187,3 +187,14 @@ uint32_t pvfs_name_hash(const char *key, size_t length) return value; } + + +/* + file allocation size rounding. This is required to pass ifstest +*/ +uint64_t pvfs_round_alloc_size(struct pvfs_state *pvfs, uint64_t size) +{ + const uint64_t round_value = 511; + if (size == 0) return 0; + return (size + round_value) & ~round_value; +} diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index ff0c0f5116..6984c2d284 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -224,7 +224,8 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name name->dos.attrib = pvfs_attrib_normalise(info1->attrib); name->dos.ea_size = info1->ea_size; if (name->st.st_size == info1->size) { - name->dos.alloc_size = info1->alloc_size; + name->dos.alloc_size = + pvfs_round_alloc_size(pvfs, info1->alloc_size); } if (info1->create_time != 0) { name->dos.create_time = info1->create_time; -- cgit From db95baf55ece57a884b9fdf5342348cc4948e26e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 10:02:55 +0000 Subject: r3803: fixed detection of xattr support (This used to be commit b7e4ec4550dd2d15714784e5fb29789be9ca8623) --- source4/ntvfs/posix/config.m4 | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index d39acbe85e..0fcc948a5b 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -26,6 +26,7 @@ dnl use flistxattr as the key function for having dnl sufficient xattr support for posix xattr backend AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) AC_SEARCH_LIBS(flistxattr, [attr]) +AC_CHECK_FUNCS(flistxattr) if test x"$ac_cv_func_flistxattr" = x"yes"; then AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) -- cgit From 696fdc8cf91cc1660725fd93c2b91ec6b65d06b5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Nov 2004 12:36:14 +0000 Subject: r3806: added support to smb_server and pvfs for the NTTRANS Create call. This call has an optional sec_desc and ea_list. (This used to be commit 8379ad14e3d51a848a99865d9ce8d56a301e8a3c) --- source4/ntvfs/posix/pvfs_open.c | 17 ++++++++++++++++- source4/ntvfs/posix/pvfs_qfileinfo.c | 3 ++- source4/ntvfs/posix/pvfs_setfileinfo.c | 6 +++--- source4/ntvfs/posix/pvfs_streams.c | 10 ++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index d8f3342f0d..1b9538d7e2 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -429,6 +429,20 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } + /* setup any EAs that were asked for */ + if (io->ntcreatex.in.ea_list) { + int i; + for (i=0;intcreatex.in.ea_list->num_eas;i++) { + status = pvfs_setfileinfo_ea_set(pvfs, name, fd, + &io->ntcreatex.in.ea_list->eas[i]); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; + } + } + } + /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); @@ -792,7 +806,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* use the generic mapping code to avoid implementing all the different open calls. */ - if (io->generic.level != RAW_OPEN_GENERIC) { + if (io->generic.level != RAW_OPEN_GENERIC && + io->generic.level != RAW_OPEN_NTTRANS_CREATE) { return ntvfs_map_open(req, io, ntvfs); } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 3959fbfc16..f6e1288b1d 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -28,7 +28,8 @@ reply to a RAW_FILEINFO_ALL_EAS call */ static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, - struct pvfs_filename *name, int fd, struct smb_all_eas *eas) + struct pvfs_filename *name, int fd, + struct smb_ea_list *eas) { NTSTATUS status; int i; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 37d8a290b8..d31bcac337 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -113,9 +113,9 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, /* add a single DOS EA */ -static NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, - struct pvfs_filename *name, - int fd, struct ea_struct *ea) +NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, + struct pvfs_filename *name, + int fd, struct ea_struct *ea) { struct xattr_DosEAs *ealist = talloc_p(pvfs, struct xattr_DosEAs); int i; diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 13a4ca1265..12f783e172 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -271,6 +271,11 @@ ssize_t pvfs_stream_write(struct pvfs_state *pvfs, if (count == 0) { return 0; } + if (offset > XATTR_MAX_STREAM_SIZE) { + errno = ENOSPC; + return -1; + } + /* we have to load the existing stream, then modify, then save */ status = pvfs_xattr_load(pvfs, h, h->name->full_name, h->fd, XATTR_DOSSTREAM_PREFIX, h->name->stream_name, offset+count, &blob); @@ -320,6 +325,11 @@ NTSTATUS pvfs_stream_truncate(struct pvfs_state *pvfs, { NTSTATUS status; DATA_BLOB blob; + + if (length > XATTR_MAX_STREAM_SIZE) { + return NT_STATUS_DISK_FULL; + } + /* we have to load the existing stream, then modify, then save */ status = pvfs_xattr_load(pvfs, name, name->full_name, fd, XATTR_DOSSTREAM_PREFIX, name->stream_name, length, &blob); -- cgit From bc7b4abc3a85e78a73d401345265b2c022f0f04d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 03:31:35 +0000 Subject: r3832: added NT ACL query/set to the posix NTVFS backend. The default ACL is based on the current nttoken, which is completely wrong, but works as a start. The ACL is stored in the xattr system.DosAcl, using a NDR encoded IDL union with a version number to allow for future expansion. pvfs does not yet check the ACL for file access. At the moment the ACL is just query/set. We also need to do some RPC work to allow the windows ACL editor to be used. At the moment is queries the ACL fine, but displays an error when it fails to map the SIDs via rpc. (This used to be commit 3a1f20d874ab2d8b2a2f2485b7a705847abf1263) --- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_acl.c | 193 +++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_qfileinfo.c | 10 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 3 + source4/ntvfs/posix/pvfs_xattr.c | 43 ++++++++ source4/ntvfs/posix/vfs_posix.c | 3 + source4/ntvfs/unixuid/vfs_unixuid.c | 4 + 7 files changed, 254 insertions(+), 3 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_acl.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 1d33d8b381..7999a32741 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -28,6 +28,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_ioctl.o \ ntvfs/posix/pvfs_xattr.o \ ntvfs/posix/pvfs_streams.o \ + ntvfs/posix/pvfs_acl.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o # End MODULE ntvfs_posix diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c new file mode 100644 index 0000000000..2885604311 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -0,0 +1,193 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - ACL support + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "auth/auth.h" +#include "system/filesys.h" +#include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_xattr.h" + + +/* + setup a default ACL for a file +*/ +static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, int fd, + struct xattr_DosAcl *acl) +{ + struct security_descriptor *sd; + struct nt_user_token *token = req->session->session_info->nt_user_token; + int i; + + sd = security_descriptor_initialise(req); + if (sd == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* nasty hack to get a reasonable sec desc - should be based on posix uid/gid + and perms */ + if (token->num_sids > 0) { + sd->owner_sid = token->user_sids[0]; + } + if (token->num_sids > 1) { + sd->group_sid = token->user_sids[1]; + } + + for (i=0;inum_sids;i++) { + struct security_ace ace; + NTSTATUS status; + + ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED; + ace.flags = 0; + ace.access_mask = SEC_RIGHTS_FULL_CTRL | STD_RIGHT_ALL_ACCESS; + ace.trustee = *token->user_sids[i]; + + status = security_descriptor_dacl_add(sd, &ace); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + acl->version = 1; + acl->info.sd = sd; + + return NT_STATUS_OK; +} + + +/* + omit any security_descriptor elements not specified in the given + secinfo flags +*/ +static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags) +{ + if (!(secinfo_flags & OWNER_SECURITY_INFORMATION)) { + sd->owner_sid = NULL; + } + if (!(secinfo_flags & GROUP_SECURITY_INFORMATION)) { + sd->group_sid = NULL; + } + if (!(secinfo_flags & DACL_SECURITY_INFORMATION)) { + sd->dacl = NULL; + } + if (!(secinfo_flags & SACL_SECURITY_INFORMATION)) { + sd->sacl = NULL; + } +} + +/* + answer a setfileinfo for an ACL +*/ +NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, int fd, + union smb_setfileinfo *info) +{ + struct xattr_DosAcl *acl; + uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags; + struct security_descriptor *new_sd, *sd; + NTSTATUS status; + + acl = talloc_p(req, struct xattr_DosAcl); + if (acl == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_acl_load(pvfs, name, fd, acl); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + status = pvfs_default_acl(pvfs, req, name, fd, acl); + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (acl->version) { + case 1: + sd = acl->info.sd; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + new_sd = info->set_secdesc.in.sd; + + /* only set the elements that have been specified */ + if (secinfo_flags & OWNER_SECURITY_INFORMATION) { + sd->owner_sid = new_sd->owner_sid; + } + if (secinfo_flags & GROUP_SECURITY_INFORMATION) { + sd->group_sid = new_sd->group_sid; + } + if (secinfo_flags & DACL_SECURITY_INFORMATION) { + sd->dacl = new_sd->dacl; + } + if (secinfo_flags & SACL_SECURITY_INFORMATION) { + sd->sacl = new_sd->sacl; + } + + status = pvfs_acl_save(pvfs, name, fd, acl); + + return status; +} + + +/* + answer a fileinfo query for the ACL +*/ +NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, int fd, + union smb_fileinfo *info) +{ + struct xattr_DosAcl *acl; + NTSTATUS status; + struct security_descriptor *sd; + + acl = talloc_p(req, struct xattr_DosAcl); + if (acl == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_acl_load(pvfs, name, fd, acl); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + status = pvfs_default_acl(pvfs, req, name, fd, acl); + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (acl->version) { + case 1: + sd = acl->info.sd; + break; + default: + return NT_STATUS_INVALID_LEVEL; + } + + normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags); + + info->query_secdesc.out.sd = sd; + + return NT_STATUS_OK; +} + diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index f6e1288b1d..fe53b0a415 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -56,7 +56,8 @@ static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* approximately map a struct pvfs_filename to a generic fileinfo struct */ -static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, +static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, + struct smbsrv_request *req, struct pvfs_filename *name, union smb_fileinfo *info, int fd) { @@ -91,7 +92,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; case RAW_FILEINFO_ALL_EAS: - return pvfs_query_all_eas(pvfs, mem_ctx, name, fd, &info->all_eas.out); + return pvfs_query_all_eas(pvfs, req, name, fd, &info->all_eas.out); case RAW_FILEINFO_IS_NAME_VALID: return NT_STATUS_OK; @@ -149,7 +150,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, case RAW_FILEINFO_STREAM_INFO: case RAW_FILEINFO_STREAM_INFORMATION: - return pvfs_stream_information(pvfs, mem_ctx, name, fd, &info->stream_info.out); + return pvfs_stream_information(pvfs, req, name, fd, &info->stream_info.out); case RAW_FILEINFO_COMPRESSION_INFO: case RAW_FILEINFO_COMPRESSION_INFORMATION: @@ -194,6 +195,9 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, info->attribute_tag_information.out.attrib = name->dos.attrib; info->attribute_tag_information.out.reparse_tag = 0; return NT_STATUS_OK; + + case RAW_FILEINFO_SEC_DESC: + return pvfs_acl_query(pvfs, req, name, fd, info); } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index d31bcac337..cc1b69b8ea 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -301,6 +301,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return pvfs_setfileinfo_rename(pvfs, req, h->name, &info->rename_information.in); + case RAW_SFILEINFO_SEC_DESC: + return pvfs_acl_set(pvfs, req, h->name, h->fd, info); + default: return NT_STATUS_INVALID_LEVEL; } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 6984c2d284..a50348ef04 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -348,6 +348,49 @@ NTSTATUS pvfs_streams_save(struct pvfs_state *pvfs, struct pvfs_filename *name, (ndr_push_flags_fn_t)ndr_push_xattr_DosStreams); } + +/* + load the current ACL from extended attributes +*/ +NTSTATUS pvfs_acl_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosAcl *acl) +{ + NTSTATUS status; + ZERO_STRUCTP(acl); + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + status = pvfs_xattr_ndr_load(pvfs, acl, name->full_name, fd, + XATTR_DOSACL_NAME, + acl, + (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAcl); + return status; +} + +/* + save the acl for a file into filesystem xattr +*/ +NTSTATUS pvfs_acl_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct xattr_DosAcl *acl) +{ + NTSTATUS status; + void *privs; + + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + + /* this xattr is in the "system" namespace, so we need + admin privileges to set it */ + privs = root_privileges(); + status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, + XATTR_DOSACL_NAME, + acl, + (ndr_push_flags_fn_t)ndr_push_xattr_DosAcl); + talloc_free(privs); + return status; +} + /* create a zero length xattr with the given name */ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e02bd7aa32..e19b0739c7 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -65,6 +65,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_NAMED_STREAMS; } + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + pvfs->fs_attribs |= FS_ATTR_PERSISTANT_ACLS; + } } diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 4520df59fc..674ce3e5cf 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -294,6 +294,10 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, struct unix_sec_ctx *newsec; NTSTATUS status; + if (req->session == NULL) { + return NT_STATUS_ACCESS_DENIED; + } + *sec = save_unix_security(req); if (*sec == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From 82da254ece1e09218d12b478e2164461306499a3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 03:41:50 +0000 Subject: r3833: NTACL is a better xattr name than DosAcl (tpot suggested this) (This used to be commit 17911eea5995c12a2300dd3928612c77f8f0883e) --- source4/ntvfs/posix/pvfs_acl.c | 10 +++++----- source4/ntvfs/posix/pvfs_xattr.c | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 2885604311..ba92cdc31c 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -33,7 +33,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, struct smbsrv_request *req, struct pvfs_filename *name, int fd, - struct xattr_DosAcl *acl) + struct xattr_NTACL *acl) { struct security_descriptor *sd; struct nt_user_token *token = req->session->session_info->nt_user_token; @@ -103,12 +103,12 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, union smb_setfileinfo *info) { - struct xattr_DosAcl *acl; + struct xattr_NTACL *acl; uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags; struct security_descriptor *new_sd, *sd; NTSTATUS status; - acl = talloc_p(req, struct xattr_DosAcl); + acl = talloc_p(req, struct xattr_NTACL); if (acl == NULL) { return NT_STATUS_NO_MEMORY; } @@ -159,11 +159,11 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, union smb_fileinfo *info) { - struct xattr_DosAcl *acl; + struct xattr_NTACL *acl; NTSTATUS status; struct security_descriptor *sd; - acl = talloc_p(req, struct xattr_DosAcl); + acl = talloc_p(req, struct xattr_NTACL); if (acl == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index a50348ef04..35d06e3fb6 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -353,7 +353,7 @@ NTSTATUS pvfs_streams_save(struct pvfs_state *pvfs, struct pvfs_filename *name, load the current ACL from extended attributes */ NTSTATUS pvfs_acl_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, - struct xattr_DosAcl *acl) + struct xattr_NTACL *acl) { NTSTATUS status; ZERO_STRUCTP(acl); @@ -363,7 +363,7 @@ NTSTATUS pvfs_acl_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int status = pvfs_xattr_ndr_load(pvfs, acl, name->full_name, fd, XATTR_DOSACL_NAME, acl, - (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAcl); + (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL); return status; } @@ -371,7 +371,7 @@ NTSTATUS pvfs_acl_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int save the acl for a file into filesystem xattr */ NTSTATUS pvfs_acl_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, - struct xattr_DosAcl *acl) + struct xattr_NTACL *acl) { NTSTATUS status; void *privs; @@ -386,7 +386,7 @@ NTSTATUS pvfs_acl_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSACL_NAME, acl, - (ndr_push_flags_fn_t)ndr_push_xattr_DosAcl); + (ndr_push_flags_fn_t)ndr_push_xattr_NTACL); talloc_free(privs); return status; } -- cgit From 837909e3abfe6988d1e685c291c2871c0d89f4ed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 03:45:06 +0000 Subject: r3834: - fixed XATTR_NTACL_NAME - pvfs now passes RAW-ACLS (This used to be commit 2e19edaa4ebc96b3e95e0b55c4fae8eaefd642b2) --- source4/ntvfs/posix/pvfs_xattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 35d06e3fb6..fda15a2e92 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -361,7 +361,7 @@ NTSTATUS pvfs_acl_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int return NT_STATUS_OK; } status = pvfs_xattr_ndr_load(pvfs, acl, name->full_name, fd, - XATTR_DOSACL_NAME, + XATTR_NTACL_NAME, acl, (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL); return status; @@ -384,7 +384,7 @@ NTSTATUS pvfs_acl_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int admin privileges to set it */ privs = root_privileges(); status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, - XATTR_DOSACL_NAME, + XATTR_NTACL_NAME, acl, (ndr_push_flags_fn_t)ndr_push_xattr_NTACL); talloc_free(privs); -- cgit From 85215a9a265b006497ec365d421be1f2b54cdca1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 03:59:24 +0000 Subject: r3835: - added testing of setting an initial ACL on a file using NTTRANS create - added support for initial ACLs in pvfs backend (This used to be commit 05ee9179f74d243aa22fa00be7873c5db76a8ad1) --- source4/ntvfs/posix/pvfs_open.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1b9538d7e2..5a23ffaa67 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -443,6 +443,22 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } } + /* setup an initial sec_desc is required */ + if (io->ntcreatex.in.sec_desc) { + union smb_setfileinfo set; + + set.set_secdesc.file.fnum = fnum; + set.set_secdesc.in.secinfo_flags = DACL_SECURITY_INFORMATION; + set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; + + status = pvfs_acl_set(pvfs, req, name, fd, &set); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; + } + } + /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); -- cgit From 0b691afe81c2778de30f20c03ab2a5f29473f799 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Nov 2004 04:19:26 +0000 Subject: r3836: - fixed the handling of NT_STATUS_BUFFER_TOO_SMALL in nttrans server - fixed revision number on default DACL - fixed DACL_PRESENT bit in acl query with these fixes cacls.exe and the GUI ACL editor in w2k both work against pvfs. The GUI editor is slow as it times out looking up the SID -> name mappings. (This used to be commit 4468018cb63fd884920c2b0f5235bded50c6b5db) --- source4/ntvfs/posix/pvfs_acl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index ba92cdc31c..216c9b4a71 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -52,6 +52,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, if (token->num_sids > 1) { sd->group_sid = token->user_sids[1]; } + sd->type |= SEC_DESC_DACL_PRESENT; for (i=0;inum_sids;i++) { struct security_ace ace; -- cgit From d95a256d1b7f579666c852740d32ba0f446a4c66 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 19 Nov 2004 20:21:13 +0000 Subject: r3881: Split up the LIBNDR_GEN subsystem into NDR_* and RPC_NDR_* subsystems. This reduces the total size of the samba binaries from 119 Mb to 73 Mb. Next step will be to have the build system obtain some of this information by itself, so that we don't have to write ~10 lines per interface manually. (This used to be commit 16d905f6b0cbec591eebc44ee2ac9516a5730378) --- source4/ntvfs/posix/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 7999a32741..44857feda3 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -31,5 +31,6 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_acl.o \ ntvfs/common/opendb.o \ ntvfs/common/brlock.o +REQUIRED_SUBSYSTEMS = NDR_XATTR # End MODULE ntvfs_posix ################################################ -- cgit From f2a605eeab5752e4884987496f2661368f85b271 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 Nov 2004 06:09:14 +0000 Subject: r3939: - added "posix:fakeoplocks" option for testing with oplocks forced on - added support for sticky write times after a setfileinfo, by using a write_time field in the DosAttrib xattr structure. (This used to be commit 4a52fae82d8305e999f94f1947daa21dab54cdfd) --- source4/ntvfs/posix/pvfs_fileinfo.c | 1 + source4/ntvfs/posix/pvfs_open.c | 56 +++++++++++++++++++++++++--------- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 ++ source4/ntvfs/posix/pvfs_xattr.c | 43 ++++++++++++++++++++------ source4/ntvfs/posix/vfs_posix.c | 4 +++ source4/ntvfs/posix/vfs_posix.h | 6 +++- 6 files changed, 88 insertions(+), 24 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 32c7ae34fa..fa45444159 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -97,6 +97,7 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.nlink = name->st.st_nlink; name->dos.ea_size = 0; name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; + name->dos.flags = 0; return pvfs_dosattrib_load(pvfs, name, fd); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5a23ffaa67..3d0e444d29 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -26,6 +26,7 @@ #include "system/filesys.h" #include "dlinklist.h" #include "messages.h" +#include "librpc/gen_ndr/ndr_xattr.h" /* create file handles with convenient numbers for sniffers @@ -160,15 +161,16 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->share_access = io->generic.in.share_access; f->impersonation = io->generic.in.impersonation; - f->handle->pvfs = pvfs; - f->handle->name = talloc_steal(f->handle, name); - f->handle->fd = -1; - f->handle->odb_locking_key = data_blob(NULL, 0); - f->handle->brl_locking_key = data_blob(NULL, 0); - f->handle->create_options = io->generic.in.create_options; - f->handle->seek_offset = 0; - f->handle->position = 0; - f->handle->mode = 0; + f->handle->pvfs = pvfs; + f->handle->name = talloc_steal(f->handle, name); + f->handle->fd = -1; + f->handle->odb_locking_key = data_blob(NULL, 0); + f->handle->brl_locking_key = data_blob(NULL, 0); + f->handle->create_options = io->generic.in.create_options; + f->handle->seek_offset = 0; + f->handle->position = 0; + f->handle->mode = 0; + f->handle->sticky_write_time = False; DLIST_ADD(pvfs->open_files, f); @@ -201,7 +203,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* the open succeeded, keep this handle permanently */ talloc_steal(pvfs, f); - io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.oplock_level = OPLOCK_NONE; io->generic.out.fnum = f->fnum; io->generic.out.create_action = create_action; io->generic.out.create_time = name->dos.create_time; @@ -225,6 +227,16 @@ static int pvfs_handle_destructor(void *p) { struct pvfs_file_handle *h = p; + /* the write time is no longer sticky */ + if (h->sticky_write_time) { + NTSTATUS status; + status = pvfs_dosattrib_load(h->pvfs, h->name, h->fd); + if (NT_STATUS_IS_OK(status)) { + h->name->dos.flags &= ~XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; + pvfs_dosattrib_save(h->pvfs, h->name, h->fd); + } + } + if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && h->name->stream_name) { NTSTATUS status; @@ -515,6 +527,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->position = 0; f->handle->mode = 0; f->handle->have_opendb_entry = True; + f->handle->sticky_write_time = False; DLIST_ADD(pvfs->open_files, f); @@ -523,7 +536,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, talloc_set_destructor(f, pvfs_fnum_destructor); talloc_set_destructor(f->handle, pvfs_handle_destructor); - io->generic.out.oplock_level = NO_OPLOCK; + + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { + io->generic.out.oplock_level = OPLOCK_EXCLUSIVE; + } else { + io->generic.out.oplock_level = OPLOCK_NONE; + } io->generic.out.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; @@ -685,7 +703,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, name = f->handle->name; - io->generic.out.oplock_level = NO_OPLOCK; + io->generic.out.oplock_level = OPLOCK_NONE; io->generic.out.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; io->generic.out.create_time = name->dos.create_time; @@ -963,7 +981,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->create_options = io->generic.in.create_options; f->handle->seek_offset = 0; f->handle->position = 0; + f->handle->mode = 0; f->handle->have_opendb_entry = False; + f->handle->sticky_write_time = False; /* form the lock context used for byte range locking and opendb locking */ @@ -1063,7 +1083,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_free(lck); - io->generic.out.oplock_level = NO_OPLOCK; + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { + io->generic.out.oplock_level = OPLOCK_EXCLUSIVE; + } else { + io->generic.out.oplock_level = OPLOCK_NONE; + } io->generic.out.fnum = f->fnum; io->generic.out.create_action = stream_existed? NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED; @@ -1112,8 +1136,12 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, unix_times.actime = 0; unix_times.modtime = io->close.in.write_time; utime(f->handle->name->full_name, &unix_times); + } else if (f->handle->sticky_write_time) { + unix_times.actime = 0; + unix_times.modtime = nt_time_to_unix(f->handle->name->dos.write_time); + utime(f->handle->name->full_name, &unix_times); } - + talloc_free(f); return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index cc1b69b8ea..5a758a6b70 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -245,6 +245,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } if (info->basic_info.in.write_time) { newstats.dos.write_time = info->basic_info.in.write_time; + newstats.dos.flags |= XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; + h->sticky_write_time = True; } if (info->basic_info.in.change_time) { newstats.dos.change_time = info->basic_info.in.change_time; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index fda15a2e92..47549499e6 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -183,6 +183,7 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name struct xattr_DosAttrib attrib; TALLOC_CTX *mem_ctx = talloc(name, 0); struct xattr_DosInfo1 *info1; + struct xattr_DosInfo2 *info2; if (name->stream_name != NULL) { name->stream_exists = False; @@ -233,6 +234,27 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name if (info1->change_time != 0) { name->dos.change_time = info1->change_time; } + name->dos.flags = 0; + break; + + case 2: + info2 = &attrib.info.info2; + name->dos.attrib = pvfs_attrib_normalise(info2->attrib); + name->dos.ea_size = info2->ea_size; + if (name->st.st_size == info2->size) { + name->dos.alloc_size = + pvfs_round_alloc_size(pvfs, info2->alloc_size); + } + if (info2->create_time != 0) { + name->dos.create_time = info2->create_time; + } + if (info2->change_time != 0) { + name->dos.change_time = info2->change_time; + } + name->dos.flags = info2->flags; + if (name->dos.flags & XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME) { + name->dos.write_time = info2->write_time; + } break; default: @@ -255,23 +277,26 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) { struct xattr_DosAttrib attrib; - struct xattr_DosInfo1 *info1; + struct xattr_DosInfo2 *info2; if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_OK; } - attrib.version = 1; - info1 = &attrib.info.info1; + attrib.version = 2; + info2 = &attrib.info.info2; name->dos.attrib = pvfs_attrib_normalise(name->dos.attrib); - info1->attrib = name->dos.attrib; - info1->ea_size = name->dos.ea_size; - info1->size = name->st.st_size; - info1->alloc_size = name->dos.alloc_size; - info1->create_time = name->dos.create_time; - info1->change_time = name->dos.change_time; + info2->attrib = name->dos.attrib; + info2->ea_size = name->dos.ea_size; + info2->size = name->st.st_size; + info2->alloc_size = name->dos.alloc_size; + info2->create_time = name->dos.create_time; + info2->change_time = name->dos.change_time; + info2->write_time = name->dos.write_time; + info2->flags = name->dos.flags; + info2->name = ""; return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSATTRIB_NAME, &attrib, diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e19b0739c7..95b4c20551 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -44,6 +44,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; + if (lp_parm_bool(snum, "posix", "fakeoplocks", True)) { + pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; + } + #if HAVE_XATTR_SUPPORT if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index a79c53ca2e..1ae552b116 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -58,7 +58,6 @@ struct pvfs_state { uint32_t fs_attribs; }; - /* this is the basic information needed about a file from the filesystem */ struct pvfs_dos_fileinfo { NTTIME create_time; @@ -70,6 +69,7 @@ struct pvfs_dos_fileinfo { uint32_t nlink; uint32_t ea_size; uint64_t file_id; + uint32_t flags; }; /* @@ -120,6 +120,9 @@ struct pvfs_file_handle { /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; + + /* have we set a sticky write time that we should remove on close */ + BOOL sticky_write_time; }; /* open file state */ @@ -189,6 +192,7 @@ struct pvfs_mangle_context { #define PVFS_FLAG_STRICT_SYNC (1<<5) #define PVFS_FLAG_STRICT_LOCKING (1<<6) #define PVFS_FLAG_XATTR_ENABLE (1<<7) +#define PVFS_FLAG_FAKE_OPLOCKS (1<<8) /* forward declare some anonymous structures */ struct pvfs_dir; -- cgit From 1814aad5617c5fcafb75cc4566618e98f5323554 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 18:25:22 +0000 Subject: r3962: fix compiler warnings metze (This used to be commit 3bfb732187211d450db842a7533e4c7e915b6ce4) --- source4/ntvfs/ipc/ipc_rap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 4fc5e182ca..eeea7e24f7 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -241,12 +241,12 @@ static NTSTATUS _rap_netshareenum(struct smbsrv_request *req, switch(r.in.level) { case 0: NDR_OK(ndr_push_bytes(call->ndr_push_data, - r.out.info[i].info0.name, + (const uint8_t *)r.out.info[i].info0.name, sizeof(r.out.info[i].info0.name))); break; case 1: NDR_OK(ndr_push_bytes(call->ndr_push_data, - r.out.info[i].info1.name, + (const uint8_t *)r.out.info[i].info1.name, sizeof(r.out.info[i].info1.name))); NDR_OK(ndr_push_uint8(call->ndr_push_data, r.out.info[i].info1.pad)); @@ -324,12 +324,12 @@ static NTSTATUS _rap_netserverenum2(struct smbsrv_request *req, switch(r.in.level) { case 0: NDR_OK(ndr_push_bytes(call->ndr_push_data, - r.out.info[i].info0.name, + (const uint8_t *)r.out.info[i].info0.name, sizeof(r.out.info[i].info0.name))); break; case 1: NDR_OK(ndr_push_bytes(call->ndr_push_data, - r.out.info[i].info1.name, + (const uint8_t *)r.out.info[i].info1.name, sizeof(r.out.info[i].info1.name))); NDR_OK(ndr_push_uint8(call->ndr_push_data, r.out.info[i].info1.version_major)); -- cgit From daea5e8c8c6cf83af0a41e858be571886fae7218 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 19:31:53 +0000 Subject: r3969: fix compiler warnings metze (This used to be commit 7d24b98f3ff55049a7c0d430c15e0a060b4aa2d3) --- source4/ntvfs/common/brlock.c | 10 +++++----- source4/ntvfs/common/opendb.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 2b30270eff..e01f458e74 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -234,7 +234,7 @@ NTSTATUS brl_lock(struct brl_context *brl, char *tp; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -379,7 +379,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -463,7 +463,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -534,7 +534,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, int count, i; struct lock_struct lock, *locks; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; dbuf = tdb_fetch(brl->w->tdb, kbuf); @@ -577,7 +577,7 @@ NTSTATUS brl_close(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; + kbuf.dptr = (char *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 64bed53c8b..99c013fc84 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -488,7 +488,7 @@ NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key, int i, count; struct odb_entry e; - kbuf.dptr = key->data; + kbuf.dptr = (char *)key->data; kbuf.dsize = key->length; dbuf = tdb_fetch(odb->w->tdb, kbuf); -- cgit From 3308087bae76a99c02687bd11f4237d803f9f605 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 25 Nov 2004 20:01:47 +0000 Subject: r3971: fix compiler warnings metze (This used to be commit 234166606dc86b9e98226cff94b3869ec173671e) --- source4/ntvfs/print/vfs_print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 4e2dfad0ca..c62357c949 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -74,7 +74,7 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, data_blob_clear(&io->ioctl.out.blob); - p = io->ioctl.out.blob.data; + p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); push_string(p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); push_string(p+18, lp_servicename(req->tcon->service), 13, STR_TERMINATE|STR_ASCII); -- cgit From 6895228b5c911a0859274dc7e3d427dd9cadeeca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 27 Nov 2004 00:24:36 +0000 Subject: r3982: split out the sid -> uid/gid mapping routines into a ntvfs_sidmap subsystem. This is in preparation for adding better default ACL generation in pvfs, which will require uid/gid -> sid mapping. (This used to be commit b31108e49247495d98cf7c12ee303b12a9e44e92) --- source4/ntvfs/common/sidmap.c | 212 ++++++++++++++++++++++++++++++++++++ source4/ntvfs/config.mk | 11 ++ source4/ntvfs/posix/config.mk | 6 +- source4/ntvfs/unixuid/config.mk | 2 + source4/ntvfs/unixuid/vfs_unixuid.c | 166 ++-------------------------- 5 files changed, 237 insertions(+), 160 deletions(-) create mode 100644 source4/ntvfs/common/sidmap.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c new file mode 100644 index 0000000000..ac3aaaecaf --- /dev/null +++ b/source4/ntvfs/common/sidmap.c @@ -0,0 +1,212 @@ +/* + Unix SMB/CIFS implementation. + + mapping routines for SID <-> unix uid/gid + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + private context for sid mapping routines +*/ +struct sidmap_context { + void *samctx; +}; + +/* + open a sidmap context - use talloc_free to close +*/ +struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx) +{ + struct sidmap_context *sidmap; + sidmap = talloc_p(mem_ctx, struct sidmap_context); + if (sidmap == NULL) { + return NULL; + } + sidmap->samctx = samdb_connect(sidmap); + if (sidmap->samctx == NULL) { + talloc_free(sidmap); + return NULL; + } + + return sidmap; +} + +/* + map a sid to a unix uid +*/ +NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, + struct dom_sid *sid, uid_t *uid) +{ + const char *attrs[] = { "sAMAccountName", "unixID", + "unixName", "sAMAccountType", NULL }; + int ret; + const char *s; + void *ctx; + struct ldb_message **res; + const char *sidstr; + uint_t atype; + + ctx = talloc(sidmap, 0); + sidstr = dom_sid_string(ctx, sid); + if (sidstr == NULL) { + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + + ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + "objectSid=%s", sidstr); + if (ret != 1) { + DEBUG(0,("sid_to_unixuid: unable to find sam record for sid %s\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* make sure its a user, not a group */ + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype && (!(atype & ATYPE_ACCOUNT))) { + DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* first try to get the uid directly */ + s = samdb_result_string(res[0], "unixID", NULL); + if (s != NULL) { + *uid = strtoul(s, NULL, 0); + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* next try via the UnixName attribute */ + s = samdb_result_string(res[0], "unixName", NULL); + if (s != NULL) { + struct passwd *pwd = getpwnam(s); + if (!pwd) { + DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *uid = pwd->pw_uid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* finally try via the sAMAccountName attribute */ + s = samdb_result_string(res[0], "sAMAccountName", NULL); + if (s != NULL) { + struct passwd *pwd = getpwnam(s); + if (!pwd) { + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *uid = pwd->pw_uid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); + + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; +} + + +/* + map a sid to a unix gid +*/ +NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, + struct dom_sid *sid, gid_t *gid) +{ + const char *attrs[] = { "sAMAccountName", "unixID", + "unixName", "sAMAccountType", NULL }; + int ret; + const char *s; + void *ctx; + struct ldb_message **res; + const char *sidstr; + uint_t atype; + + ctx = talloc(sidmap, 0); + sidstr = dom_sid_string(ctx, sid); + if (sidstr == NULL) { + talloc_free(ctx); + return NT_STATUS_NO_MEMORY; + } + + ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + "objectSid=%s", sidstr); + if (ret != 1) { + DEBUG(0,("sid_to_unixgid: unable to find sam record for sid %s\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* make sure its not a user */ + atype = samdb_result_uint(res[0], "sAMAccountType", 0); + if (atype && atype == ATYPE_NORMAL_ACCOUNT) { + DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + + /* first try to get the gid directly */ + s = samdb_result_string(res[0], "unixID", NULL); + if (s != NULL) { + *gid = strtoul(s, NULL, 0); + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* next try via the UnixName attribute */ + s = samdb_result_string(res[0], "unixName", NULL); + if (s != NULL) { + struct group *grp = getgrnam(s); + if (!grp) { + DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", + s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *gid = grp->gr_gid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + /* finally try via the sAMAccountName attribute */ + s = samdb_result_string(res[0], "sAMAccountName", NULL); + if (s != NULL) { + struct group *grp = getgrnam(s); + if (!grp) { + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, sidstr)); + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; + } + *gid = grp->gr_gid; + talloc_free(ctx); + return NT_STATUS_OK; + } + + DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", + sidstr)); + + talloc_free(ctx); + return NT_STATUS_ACCESS_DENIED; +} diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 43157a8c66..55f8270de2 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -58,6 +58,17 @@ INIT_OBJ_FILES = \ # End MODULE ntvfs_nbench ################################################ +################################################ +# Start SUBSYSTEM ntvfs_common +[SUBSYSTEM::ntvfs_common] +ADD_OBJ_FILES = \ + ntvfs/common/brlock.o \ + ntvfs/common/opendb.o \ + ntvfs/common/sidmap.o +# End SUBSYSTEM ntvfs_common +################################################ + + ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::NTVFS] diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 44857feda3..44a1625c5f 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -28,9 +28,7 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_ioctl.o \ ntvfs/posix/pvfs_xattr.o \ ntvfs/posix/pvfs_streams.o \ - ntvfs/posix/pvfs_acl.o \ - ntvfs/common/opendb.o \ - ntvfs/common/brlock.o -REQUIRED_SUBSYSTEMS = NDR_XATTR + ntvfs/posix/pvfs_acl.o +REQUIRED_SUBSYSTEMS = NDR_XATTR ntvfs_common # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 3df3194688..34c8f0c2b4 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -5,5 +5,7 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ ntvfs/unixuid/vfs_unixuid.o +REQUIRED_SUBSYSTEMS = \ + ntvfs_common # End MODULE ntvfs_unixuid ################################################ diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 674ce3e5cf..0535475dd3 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -26,162 +26,12 @@ #include "smb_server/smb_server.h" struct unixuid_private { - void *samctx; + struct sidmap_context *sidmap; struct unix_sec_ctx *last_sec_ctx; struct nt_user_token *last_token; }; -/* - map a sid to a unix uid -*/ -static NTSTATUS sid_to_unixuid(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct dom_sid *sid, uid_t *uid) -{ - struct unixuid_private *private = ntvfs->private_data; - const char *attrs[] = { "sAMAccountName", "unixID", "unixName", "sAMAccountType", NULL }; - int ret; - const char *s; - void *ctx; - struct ldb_message **res; - const char *sidstr; - uint_t atype; - - ctx = talloc(req, 0); - sidstr = dom_sid_string(ctx, sid); - - ret = samdb_search(private->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); - if (ret != 1) { - DEBUG(0,("sid_to_unixuid: unable to find sam record for sid %s\n", sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - - /* make sure its a user, not a group */ - atype = samdb_result_uint(res[0], "sAMAccountType", 0); - if (atype && (!(atype & ATYPE_ACCOUNT))) { - DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - - /* first try to get the uid directly */ - s = samdb_result_string(res[0], "unixID", NULL); - if (s != NULL) { - *uid = strtoul(s, NULL, 0); - talloc_free(ctx); - return NT_STATUS_OK; - } - - /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "unixName", NULL); - if (s != NULL) { - struct passwd *pwd = getpwnam(s); - if (!pwd) { - DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - *uid = pwd->pw_uid; - talloc_free(ctx); - return NT_STATUS_OK; - } - - /* finally try via the sAMAccountName attribute */ - s = samdb_result_string(res[0], "sAMAccountName", NULL); - if (s != NULL) { - struct passwd *pwd = getpwnam(s); - if (!pwd) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", s, sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - *uid = pwd->pw_uid; - talloc_free(ctx); - return NT_STATUS_OK; - } - - DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); - - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; -} - - -/* - map a sid to a unix gid -*/ -static NTSTATUS sid_to_unixgid(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct dom_sid *sid, gid_t *gid) -{ - struct unixuid_private *private = ntvfs->private_data; - const char *attrs[] = { "sAMAccountName", "unixID", "unixName", "sAMAccountType", NULL }; - int ret; - const char *s; - void *ctx; - struct ldb_message **res; - const char *sidstr; - uint_t atype; - - ctx = talloc(req, 0); - sidstr = dom_sid_string(ctx, sid); - - ret = samdb_search(private->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); - if (ret != 1) { - DEBUG(0,("sid_to_unixgid: unable to find sam record for sid %s\n", sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - - /* make sure its not a user */ - atype = samdb_result_uint(res[0], "sAMAccountType", 0); - if (atype && atype == ATYPE_NORMAL_ACCOUNT) { - DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - - /* first try to get the gid directly */ - s = samdb_result_string(res[0], "unixID", NULL); - if (s != NULL) { - *gid = strtoul(s, NULL, 0); - talloc_free(ctx); - return NT_STATUS_OK; - } - - /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "unixName", NULL); - if (s != NULL) { - struct group *grp = getgrnam(s); - if (!grp) { - DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", s, sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - *gid = grp->gr_gid; - talloc_free(ctx); - return NT_STATUS_OK; - } - - /* finally try via the sAMAccountName attribute */ - s = samdb_result_string(res[0], "sAMAccountName", NULL); - if (s != NULL) { - struct group *grp = getgrnam(s); - if (!grp) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; - } - *gid = grp->gr_gid; - talloc_free(ctx); - return NT_STATUS_OK; - } - - DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); - - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; -} struct unix_sec_ctx { uid_t uid; @@ -247,6 +97,7 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, struct nt_user_token *token, struct unix_sec_ctx **sec) { + struct unixuid_private *private = ntvfs->private_data; int i; NTSTATUS status; *sec = talloc_p(req, struct unix_sec_ctx); @@ -256,12 +107,14 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } - status = sid_to_unixuid(ntvfs, req, token->user_sids[0], &(*sec)->uid); + status = sidmap_sid_to_unixuid(private->sidmap, + token->user_sids[0], &(*sec)->uid); if (!NT_STATUS_IS_OK(status)) { return status; } - status = sid_to_unixgid(ntvfs, req, token->user_sids[1], &(*sec)->gid); + status = sidmap_sid_to_unixgid(private->sidmap, + token->user_sids[1], &(*sec)->gid); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -273,7 +126,8 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, } for (i=0;i<(*sec)->ngroups;i++) { - status = sid_to_unixgid(ntvfs, req, token->user_sids[i+2], &(*sec)->groups[i]); + status = sidmap_sid_to_unixgid(private->sidmap, + token->user_sids[i+2], &(*sec)->groups[i]); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -358,8 +212,8 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - private->samctx = samdb_connect(private); - if (private->samctx == NULL) { + private->sidmap = sidmap_open(private); + if (private->sidmap == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From dc0e4975d6da7ccfb5777639eac6f27bf1998e87 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 27 Nov 2004 00:28:03 +0000 Subject: r3983: posix:fakeoplocks should default to False, not True ! (This used to be commit 052d91c59f177851b5e0e53c8a033bdd28702f64) --- source4/ntvfs/posix/vfs_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 95b4c20551..e340e8cbf6 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -44,7 +44,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; - if (lp_parm_bool(snum, "posix", "fakeoplocks", True)) { + if (lp_parm_bool(snum, "posix", "fakeoplocks", False)) { pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; } -- cgit From 8b4c1f448cd698c2f7fa01f537fc4216f3030279 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 29 Nov 2004 03:21:46 +0000 Subject: r3989: added a linear algorithmic mapping for uid->sid and gid->sid within our local domain. Note that this linear mapping does not suffer from the "foreign sid" problems of the linear mappings we have previously rejected for the sid->uid problem. the mapping allows for 1 billion automatically allocated users or groups for the local domain. (This used to be commit 8f573439753e2a425305936107442c85cffb9369) --- source4/ntvfs/common/sidmap.c | 372 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 351 insertions(+), 21 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index ac3aaaecaf..209982ec58 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -21,6 +21,16 @@ */ #include "includes.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* + these are used for the fallback local uid/gid to sid mapping + code. +*/ +#define SIDMAP_LOCAL_USER_BASE 0x80000000 +#define SIDMAP_LOCAL_GROUP_BASE 0xC0000000 +#define SIDMAP_MAX_LOCAL_UID 0x3fffffff +#define SIDMAP_MAX_LOCAL_GID 0x3fffffff /* private context for sid mapping routines @@ -48,6 +58,70 @@ struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx) return sidmap; } + +/* + check the sAMAccountType field of a search result to see if + the account is a user account +*/ +static BOOL is_user_account(struct ldb_message *res) +{ + uint_t atype = samdb_result_uint(res, "sAMAccountType", 0); + if (atype && (!(atype & ATYPE_ACCOUNT))) { + return False; + } + return True; +} + +/* + check the sAMAccountType field of a search result to see if + the account is a group account +*/ +static BOOL is_group_account(struct ldb_message *res) +{ + uint_t atype = samdb_result_uint(res, "sAMAccountType", 0); + if (atype && atype == ATYPE_NORMAL_ACCOUNT) { + return False; + } + return True; +} + + + +/* + return the dom_sid of our primary domain +*/ +static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap, + TALLOC_CTX *mem_ctx, struct dom_sid **sid) +{ + const char *attrs[] = { "objectSid", NULL }; + void *ctx = talloc(mem_ctx, 0); + const char *sidstr; + int ret; + struct ldb_message **res; + + ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + "(&(objectClass=domain)(name=%s))", lp_workgroup()); + if (ret != 1) { + talloc_free(ctx); + return NT_STATUS_NO_SUCH_DOMAIN; + } + + sidstr = samdb_result_string(res[0], "objectSid", NULL); + if (sidstr == NULL) { + talloc_free(ctx); + return NT_STATUS_NO_SUCH_DOMAIN; + } + + *sid = dom_sid_parse_talloc(mem_ctx, sidstr); + talloc_free(ctx); + if (*sid == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + + /* map a sid to a unix uid */ @@ -61,7 +135,8 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, void *ctx; struct ldb_message **res; const char *sidstr; - uint_t atype; + struct dom_sid *domain_sid; + NTSTATUS status; ctx = talloc(sidmap, 0); sidstr = dom_sid_string(ctx, sid); @@ -73,17 +148,14 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); if (ret != 1) { - DEBUG(0,("sid_to_unixuid: unable to find sam record for sid %s\n", sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + goto allocated_sid; } /* make sure its a user, not a group */ - atype = samdb_result_uint(res[0], "sAMAccountType", 0); - if (atype && (!(atype & ATYPE_ACCOUNT))) { + if (!is_user_account(res[0])) { DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_INVALID_SID; } /* first try to get the uid directly */ @@ -101,7 +173,7 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, if (!pwd) { DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_SUCH_USER; } *uid = pwd->pw_uid; talloc_free(ctx); @@ -115,17 +187,37 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, if (!pwd) { DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", s, sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_SUCH_USER; } *uid = pwd->pw_uid; talloc_free(ctx); return NT_STATUS_OK; } - DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); + +allocated_sid: + status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return NT_STATUS_NO_SUCH_DOMAIN; + } + + if (dom_sid_in_domain(domain_sid, sid)) { + uint32_t rid = sid->sub_auths[sid->num_auths-1]; + if (rid >= SIDMAP_LOCAL_USER_BASE && + rid < SIDMAP_LOCAL_GROUP_BASE) { + *uid = rid - SIDMAP_LOCAL_USER_BASE; + talloc_free(ctx); + return NT_STATUS_OK; + } + } + + + DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", + sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_INVALID_SID; } @@ -142,7 +234,8 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, void *ctx; struct ldb_message **res; const char *sidstr; - uint_t atype; + NTSTATUS status; + struct dom_sid *domain_sid; ctx = talloc(sidmap, 0); sidstr = dom_sid_string(ctx, sid); @@ -154,17 +247,14 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); if (ret != 1) { - DEBUG(0,("sid_to_unixgid: unable to find sam record for sid %s\n", sidstr)); - talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + goto allocated_sid; } /* make sure its not a user */ - atype = samdb_result_uint(res[0], "sAMAccountType", 0); - if (atype && atype == ATYPE_NORMAL_ACCOUNT) { + if (!is_group_account(res[0])) { DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_INVALID_SID; } /* first try to get the gid directly */ @@ -183,7 +273,7 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", s, sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_SUCH_USER; } *gid = grp->gr_gid; talloc_free(ctx); @@ -197,16 +287,256 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, if (!grp) { DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_SUCH_USER; } *gid = grp->gr_gid; talloc_free(ctx); return NT_STATUS_OK; } +allocated_sid: + status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return NT_STATUS_NO_SUCH_DOMAIN; + } + + if (dom_sid_in_domain(domain_sid, sid)) { + uint32_t rid = sid->sub_auths[sid->num_auths-1]; + if (rid >= SIDMAP_LOCAL_GROUP_BASE) { + *gid = rid - SIDMAP_LOCAL_GROUP_BASE; + talloc_free(ctx); + return NT_STATUS_OK; + } + } + DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", sidstr)); talloc_free(ctx); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_INVALID_SID; +} + + +/* + map a unix uid to a dom_sid + the returned sid is allocated in the supplied mem_ctx +*/ +NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, + TALLOC_CTX *mem_ctx, + uid_t uid, struct dom_sid **sid) +{ + const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL }; + int ret, i; + void *ctx; + struct ldb_message **res; + struct passwd *pwd; + struct dom_sid *domain_sid; + NTSTATUS status; + + /* + we search for the mapping in the following order: + + - check if the uid is in the dynamic uid range assigned for winbindd + use. If it is, then look in winbindd sid mapping + database (not implemented yet) + - look for a user account in samdb that has unixID set to the + given uid + - look for a user account in samdb that has unixName or + sAMAccountName set to the name given by getpwuid() + - assign a SID by adding the uid to SIDMAP_LOCAL_USER_BASE in the local + domain + */ + + + ctx = talloc(sidmap, 0); + + + /* + step 2: look for a user account in samdb that has unixID set to the + given uid + */ + + ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + "unixID=%u", (unsigned int)uid); + for (i=0;isamctx, ctx, NULL, &res, attrs, + "(|(unixName=%s)(sAMAccountName=%s))", + pwd->pw_name, pwd->pw_name); + for (i=0;i SIDMAP_MAX_LOCAL_UID) { + return NT_STATUS_INVALID_SID; + } + + status = sidmap_primary_domain_sid(sidmap, mem_ctx, &domain_sid); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return status; + } + + *sid = dom_sid_add_rid(mem_ctx, domain_sid, SIDMAP_LOCAL_USER_BASE + uid); + talloc_free(ctx); + + if (*sid == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + + +/* + map a unix gid to a dom_sid + the returned sid is allocated in the supplied mem_ctx +*/ +NTSTATUS sidmap_gid_to_sid(struct sidmap_context *sidmap, + TALLOC_CTX *mem_ctx, + gid_t gid, struct dom_sid **sid) +{ + const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL }; + int ret, i; + void *ctx; + struct ldb_message **res; + struct group *grp; + struct dom_sid *domain_sid; + NTSTATUS status; + + /* + we search for the mapping in the following order: + + - check if the gid is in the dynamic gid range assigned for winbindd + use. If it is, then look in winbindd sid mapping + database (not implemented yet) + - look for a group account in samdb that has unixID set to the + given gid + - look for a group account in samdb that has unixName or + sAMAccountName set to the name given by getgrgid() + - assign a SID by adding the gid to SIDMAP_LOCAL_GROUP_BASE in the local + domain + */ + + + ctx = talloc(sidmap, 0); + + + /* + step 2: look for a group account in samdb that has unixID set to the + given gid + */ + + ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + "unixID=%u", (unsigned int)gid); + for (i=0;isamctx, ctx, NULL, &res, attrs, + "(|(unixName=%s)(sAMAccountName=%s))", + grp->gr_name, grp->gr_name); + for (i=0;i SIDMAP_MAX_LOCAL_GID) { + return NT_STATUS_INVALID_SID; + } + + status = sidmap_primary_domain_sid(sidmap, mem_ctx, &domain_sid); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return status; + } + + *sid = dom_sid_add_rid(mem_ctx, domain_sid, SIDMAP_LOCAL_GROUP_BASE + gid); + talloc_free(ctx); + + if (*sid == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; } -- cgit From 71a81e9dcbbdc3e8d443967e47110ce9187a7c1d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 29 Nov 2004 03:22:44 +0000 Subject: r3990: take advantage of the uid->sid and gid->sid code to create a much better default NT ACL in pvfs (This used to be commit 9ff6ecbdb6c08528193f7958d7ea7d9a8df6defd) --- source4/ntvfs/posix/pvfs_acl.c | 105 ++++++++++++++++++++++++++++++++++------ source4/ntvfs/posix/vfs_posix.c | 5 ++ source4/ntvfs/posix/vfs_posix.h | 1 + 3 files changed, 97 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 216c9b4a71..f079857821 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -36,32 +36,109 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, struct xattr_NTACL *acl) { struct security_descriptor *sd; - struct nt_user_token *token = req->session->session_info->nt_user_token; int i; + struct security_ace ace; + NTSTATUS status; + const char *sid_names[] = { + SID_BUILTIN_ADMINISTRATORS, + SID_CREATOR_OWNER, + SID_CREATOR_GROUP, + SID_WORLD + }; + uint32_t access_masks[4]; + mode_t mode; sd = security_descriptor_initialise(req); if (sd == NULL) { return NT_STATUS_NO_MEMORY; } - /* nasty hack to get a reasonable sec desc - should be based on posix uid/gid - and perms */ - if (token->num_sids > 0) { - sd->owner_sid = token->user_sids[0]; + status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); + if (!NT_STATUS_IS_OK(status)) { + return status; } - if (token->num_sids > 1) { - sd->group_sid = token->user_sids[1]; + status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); + if (!NT_STATUS_IS_OK(status)) { + return status; } + sd->type |= SEC_DESC_DACL_PRESENT; - for (i=0;inum_sids;i++) { - struct security_ace ace; - NTSTATUS status; + /* + we provide 4 ACEs + - Administrator + - Owner + - Group + - Everyone + */ + access_masks[0] = SEC_RIGHTS_FULL_CTRL | STD_RIGHT_ALL_ACCESS; + access_masks[1] = 0; + access_masks[2] = 0; + access_masks[3] = 0; + + mode = name->st.st_mode; + + if (mode & S_IRUSR) { + access_masks[1] |= + SA_RIGHT_FILE_READ_DATA | + SA_RIGHT_FILE_READ_EA | + SA_RIGHT_FILE_READ_ATTRIBUTES | + SA_RIGHT_FILE_EXECUTE; + } + if (mode & S_IWUSR) { + access_masks[1] |= + SA_RIGHT_FILE_WRITE_DATA | + SA_RIGHT_FILE_APPEND_DATA | + SA_RIGHT_FILE_WRITE_EA | + SA_RIGHT_FILE_DELETE_CHILD | + SA_RIGHT_FILE_WRITE_ATTRIBUTES; + } + + if (mode & S_IRGRP) { + access_masks[2] |= + SA_RIGHT_FILE_READ_DATA | + SA_RIGHT_FILE_READ_EA | + SA_RIGHT_FILE_READ_ATTRIBUTES | + SA_RIGHT_FILE_EXECUTE; + } + if (mode & S_IWGRP) { + access_masks[2] |= + SA_RIGHT_FILE_WRITE_DATA | + SA_RIGHT_FILE_APPEND_DATA | + SA_RIGHT_FILE_WRITE_EA | + SA_RIGHT_FILE_DELETE_CHILD | + SA_RIGHT_FILE_WRITE_ATTRIBUTES; + } + + if (mode & S_IROTH) { + access_masks[3] |= + SA_RIGHT_FILE_READ_DATA | + SA_RIGHT_FILE_READ_EA | + SA_RIGHT_FILE_READ_ATTRIBUTES | + SA_RIGHT_FILE_EXECUTE; + } + if (mode & S_IWOTH) { + access_masks[3] |= + SA_RIGHT_FILE_WRITE_DATA | + SA_RIGHT_FILE_APPEND_DATA | + SA_RIGHT_FILE_WRITE_EA | + SA_RIGHT_FILE_DELETE_CHILD | + SA_RIGHT_FILE_WRITE_ATTRIBUTES; + } + + ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED; + ace.flags = 0; + + for (i=0;iuser_sids[i]; + ace.access_mask = access_masks[i]; + + sid = dom_sid_parse_talloc(sd, sid_names[i]); + if (sid == NULL) { + return NT_STATUS_NO_MEMORY; + } + ace.trustee = *sid; status = security_descriptor_dacl_add(sd, &ace); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e340e8cbf6..ff3d3448f2 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -130,6 +130,11 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + pvfs->sidmap = sidmap_open(pvfs); + if (pvfs->sidmap == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + /* allocate the fnum id -> ptr tree */ pvfs->idtree_fnum = idr_init(pvfs); if (pvfs->idtree_fnum == NULL) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 1ae552b116..16c6f807e9 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -40,6 +40,7 @@ struct pvfs_state { struct brl_context *brl_context; struct odb_context *odb_context; + struct sidmap_context *sidmap; /* an id tree mapping open search ID to a pvfs_search_state structure */ struct idr_context *idtree_search; -- cgit From b393de7f051dd339946b73251f818ad8c8601ba9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 29 Nov 2004 04:24:50 +0000 Subject: r3992: provide hooks for lsa to lookup sids allocated using the linear id->sid mapping (This used to be commit e61140510905b6bbe57ad35dad8e4dd68d1f6bd8) --- source4/ntvfs/common/sidmap.c | 61 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 209982ec58..89ad2e2430 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -540,3 +540,64 @@ allocate_sid: return NT_STATUS_OK; } + +/* + check if a sid is in the range of auto-allocated SIDs from our primary domain, + and if it is, then return the name and atype +*/ +NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, + TALLOC_CTX *mem_ctx, + const struct dom_sid *sid, + const char **name, + uint32_t *atype) +{ + NTSTATUS status; + struct dom_sid *domain_sid; + void *ctx = talloc(mem_ctx, 0); + uint32_t rid; + + status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_NO_SUCH_DOMAIN; + } + + if (!dom_sid_in_domain(domain_sid, sid)) { + talloc_free(ctx); + return NT_STATUS_INVALID_SID; + } + + talloc_free(ctx); + + rid = sid->sub_auths[sid->num_auths-1]; + if (rid < SIDMAP_LOCAL_USER_BASE) { + return NT_STATUS_INVALID_SID; + } + + if (rid < SIDMAP_LOCAL_GROUP_BASE) { + struct passwd *pwd; + uid_t uid = rid - SIDMAP_LOCAL_USER_BASE; + *atype = ATYPE_NORMAL_ACCOUNT; + pwd = getpwuid(uid); + if (pwd == NULL) { + *name = talloc_asprintf(mem_ctx, "uid%u", uid); + } else { + *name = talloc_strdup(mem_ctx, pwd->pw_name); + } + } else { + struct group *grp; + gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE; + *atype = ATYPE_LOCAL_GROUP; + grp = getgrgid(gid); + if (grp == NULL) { + *name = talloc_asprintf(mem_ctx, "gid%u", gid); + } else { + *name = talloc_strdup(mem_ctx, grp->gr_name); + } + } + + if (*name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} -- cgit From 96f4d9815346edbb277583d417b4a8ae6c1c0a09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 29 Nov 2004 06:18:58 +0000 Subject: r3993: use distinctive fnums in the ipc backend, to make monitoring sniffs easier (This used to be commit 54209ed05686a442156f7927c58d8656aa5e4900) --- source4/ntvfs/ipc/vfs_ipc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index a53accd533..b4c41d58d3 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -30,6 +30,8 @@ #include "dlinklist.h" #include "smb_server/smb_server.h" +#define IPC_BASE_FNUM 0x400 + /* this is the private structure used to keep the state of an open ipc$ connection. It needs to keep information about all open pipes */ @@ -196,7 +198,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new(private->idtree_fnum, p, UINT16_MAX); + fnum = idr_get_new_above(private->idtree_fnum, p, IPC_BASE_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } -- cgit From 77be33e31c11ac3b667f3019d23c2fcde1e8692f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 29 Nov 2004 06:42:02 +0000 Subject: r3995: improved the default ACL mapping from unix perms (This used to be commit 01e89697fe837ee76fedda149e1e2b389a7d3889) --- source4/ntvfs/posix/pvfs_acl.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index f079857821..2ff873fd78 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -83,15 +83,17 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_READ_EA | SA_RIGHT_FILE_READ_ATTRIBUTES | - SA_RIGHT_FILE_EXECUTE; + SA_RIGHT_FILE_EXECUTE | + STD_RIGHT_SYNCHRONIZE_ACCESS | + STD_RIGHT_READ_CONTROL_ACCESS; } if (mode & S_IWUSR) { access_masks[1] |= SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_APPEND_DATA | SA_RIGHT_FILE_WRITE_EA | - SA_RIGHT_FILE_DELETE_CHILD | - SA_RIGHT_FILE_WRITE_ATTRIBUTES; + SA_RIGHT_FILE_WRITE_ATTRIBUTES | + STD_RIGHT_DELETE_ACCESS; } if (mode & S_IRGRP) { @@ -99,14 +101,15 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_READ_EA | SA_RIGHT_FILE_READ_ATTRIBUTES | - SA_RIGHT_FILE_EXECUTE; + SA_RIGHT_FILE_EXECUTE | + STD_RIGHT_SYNCHRONIZE_ACCESS | + STD_RIGHT_READ_CONTROL_ACCESS; } if (mode & S_IWGRP) { access_masks[2] |= SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_APPEND_DATA | SA_RIGHT_FILE_WRITE_EA | - SA_RIGHT_FILE_DELETE_CHILD | SA_RIGHT_FILE_WRITE_ATTRIBUTES; } @@ -115,14 +118,15 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_READ_EA | SA_RIGHT_FILE_READ_ATTRIBUTES | - SA_RIGHT_FILE_EXECUTE; + SA_RIGHT_FILE_EXECUTE | + STD_RIGHT_SYNCHRONIZE_ACCESS | + STD_RIGHT_READ_CONTROL_ACCESS; } if (mode & S_IWOTH) { access_masks[3] |= SA_RIGHT_FILE_WRITE_DATA | SA_RIGHT_FILE_APPEND_DATA | SA_RIGHT_FILE_WRITE_EA | - SA_RIGHT_FILE_DELETE_CHILD | SA_RIGHT_FILE_WRITE_ATTRIBUTES; } -- cgit From fdc9f417d89fdf9dd6afbc22843d70585e195c9d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Nov 2004 04:33:27 +0000 Subject: r4011: get rid of rpc_secdes.h and replace it with a single sane set of definitions for security access masks, in security.idl The previous definitions were inconsistently named, and contained many duplicate and misleading entries. I kept finding myself tripping up while using them. (This used to be commit 01c0fa722f80ceeb3f81f01987de95f365a2ed3d) --- source4/ntvfs/common/opendb.c | 29 +++++++----- source4/ntvfs/ntvfs_generic.c | 31 +++++++------ source4/ntvfs/posix/pvfs_acl.c | 80 +++++++++++++++++----------------- source4/ntvfs/posix/pvfs_open.c | 24 +++++----- source4/ntvfs/posix/pvfs_read.c | 5 ++- source4/ntvfs/posix/pvfs_setfileinfo.c | 5 ++- source4/ntvfs/posix/pvfs_write.c | 3 +- 7 files changed, 94 insertions(+), 83 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 99c013fc84..8947a5d255 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -40,6 +40,7 @@ #include "includes.h" #include "messages.h" +#include "librpc/gen_ndr/ndr_security.h" struct odb_context { struct tdb_wrap *w; @@ -157,14 +158,18 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) /* if either open involves no read.write or delete access then it can't conflict */ - if (!(e1->access_mask & (SA_RIGHT_FILE_WRITE_APPEND | - SA_RIGHT_FILE_READ_EXEC | - STD_RIGHT_DELETE_ACCESS))) { + if (!(e1->access_mask & (SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_READ_DATA | + SEC_FILE_EXECUTE | + SEC_STD_DELETE))) { return False; } - if (!(e2->access_mask & (SA_RIGHT_FILE_WRITE_APPEND | - SA_RIGHT_FILE_READ_EXEC | - STD_RIGHT_DELETE_ACCESS))) { + if (!(e2->access_mask & (SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_READ_DATA | + SEC_FILE_EXECUTE | + SEC_STD_DELETE))) { return False; } @@ -176,24 +181,24 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) } CHECK_MASK(e1->access_mask, e2->share_access, - SA_RIGHT_FILE_WRITE_APPEND, + SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, NTCREATEX_SHARE_ACCESS_WRITE); CHECK_MASK(e2->access_mask, e1->share_access, - SA_RIGHT_FILE_WRITE_APPEND, + SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, NTCREATEX_SHARE_ACCESS_WRITE); CHECK_MASK(e1->access_mask, e2->share_access, - SA_RIGHT_FILE_READ_EXEC, + SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, NTCREATEX_SHARE_ACCESS_READ); CHECK_MASK(e2->access_mask, e1->share_access, - SA_RIGHT_FILE_READ_EXEC, + SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, NTCREATEX_SHARE_ACCESS_READ); CHECK_MASK(e1->access_mask, e2->share_access, - STD_RIGHT_DELETE_ACCESS, + SEC_STD_DELETE, NTCREATEX_SHARE_ACCESS_DELETE); CHECK_MASK(e2->access_mask, e1->share_access, - STD_RIGHT_DELETE_ACCESS, + SEC_STD_DELETE, NTCREATEX_SHARE_ACCESS_DELETE); /* if a delete is pending then a second open is not allowed */ diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index a9bc8120c8..49de8944ff 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -33,6 +33,7 @@ #include "includes.h" #include "smb_server/smb_server.h" +#include "librpc/gen_ndr/ndr_security.h" /* a second stage function converts from the out parameters of the generic call onto the out parameters of the specific call made */ @@ -178,7 +179,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->openx.out.devstate = 0; io->openx.out.action = io2->generic.out.create_action; io->openx.out.unique_fid = 0; - io->openx.out.access_mask = STANDARD_RIGHTS_ALL_ACCESS; + io->openx.out.access_mask = SEC_STD_ALL; io->openx.out.unknown = 0; /* we need to extend the file to the requested size if @@ -280,17 +281,19 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { case OPENX_MODE_ACCESS_READ: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ; io->openx.out.access = OPENX_MODE_ACCESS_READ; break; case OPENX_MODE_ACCESS_WRITE: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE; io->openx.out.access = OPENX_MODE_ACCESS_WRITE; break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: case OPENX_MODE_ACCESS_EXEC: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE | GENERIC_RIGHTS_FILE_READ; + io2->generic.in.access_mask = + SEC_RIGHTS_FILE_READ | + SEC_RIGHTS_FILE_WRITE; io->openx.out.access = OPENX_MODE_ACCESS_RDWR; break; default: @@ -381,17 +384,17 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; switch (io->openold.in.flags & OPEN_FLAGS_MODE_MASK) { case OPEN_FLAGS_OPEN_READ: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ; + io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ; io->openold.out.rmode = DOS_OPEN_RDONLY; break; case OPEN_FLAGS_OPEN_WRITE: - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE; io->openold.out.rmode = DOS_OPEN_WRONLY; break; case OPEN_FLAGS_OPEN_RDWR: case 0xf: /* FCB mode */ - io2->generic.in.access_mask = GENERIC_RIGHTS_FILE_READ | - GENERIC_RIGHTS_FILE_WRITE; + io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ | + SEC_RIGHTS_FILE_WRITE; io->openold.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ break; default: @@ -463,8 +466,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.fname = io->mknew.in.fname; io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; io2->generic.in.access_mask = - GENERIC_RIGHTS_FILE_READ | - GENERIC_RIGHTS_FILE_WRITE; + SEC_RIGHTS_FILE_READ | + SEC_RIGHTS_FILE_WRITE; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; @@ -476,8 +479,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.fname = io->mknew.in.fname; io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; io2->generic.in.access_mask = - GENERIC_RIGHTS_FILE_READ | - GENERIC_RIGHTS_FILE_WRITE; + SEC_RIGHTS_FILE_READ | + SEC_RIGHTS_FILE_WRITE; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; @@ -493,8 +496,8 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, generate_random_str_list(io2, 5, "0123456789")); io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; io2->generic.in.access_mask = - GENERIC_RIGHTS_FILE_READ | - GENERIC_RIGHTS_FILE_WRITE; + SEC_RIGHTS_FILE_READ | + SEC_RIGHTS_FILE_WRITE; io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 2ff873fd78..2fff6db628 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -71,7 +71,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, - Group - Everyone */ - access_masks[0] = SEC_RIGHTS_FULL_CTRL | STD_RIGHT_ALL_ACCESS; + access_masks[0] = SEC_RIGHTS_FULL_CONTROL; access_masks[1] = 0; access_masks[2] = 0; access_masks[3] = 0; @@ -80,54 +80,54 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, if (mode & S_IRUSR) { access_masks[1] |= - SA_RIGHT_FILE_READ_DATA | - SA_RIGHT_FILE_READ_EA | - SA_RIGHT_FILE_READ_ATTRIBUTES | - SA_RIGHT_FILE_EXECUTE | - STD_RIGHT_SYNCHRONIZE_ACCESS | - STD_RIGHT_READ_CONTROL_ACCESS; + SEC_FILE_READ_DATA | + SEC_FILE_READ_EA | + SEC_FILE_READ_ATTRIBUTE | + SEC_FILE_EXECUTE | + SEC_STD_SYNCHRONIZE | + SEC_STD_READ_CONTROL; } if (mode & S_IWUSR) { access_masks[1] |= - SA_RIGHT_FILE_WRITE_DATA | - SA_RIGHT_FILE_APPEND_DATA | - SA_RIGHT_FILE_WRITE_EA | - SA_RIGHT_FILE_WRITE_ATTRIBUTES | - STD_RIGHT_DELETE_ACCESS; + SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_WRITE_EA | + SEC_FILE_WRITE_ATTRIBUTE | + SEC_STD_DELETE; } if (mode & S_IRGRP) { access_masks[2] |= - SA_RIGHT_FILE_READ_DATA | - SA_RIGHT_FILE_READ_EA | - SA_RIGHT_FILE_READ_ATTRIBUTES | - SA_RIGHT_FILE_EXECUTE | - STD_RIGHT_SYNCHRONIZE_ACCESS | - STD_RIGHT_READ_CONTROL_ACCESS; + SEC_FILE_READ_DATA | + SEC_FILE_READ_EA | + SEC_FILE_READ_ATTRIBUTE | + SEC_FILE_EXECUTE | + SEC_STD_SYNCHRONIZE | + SEC_STD_READ_CONTROL; } if (mode & S_IWGRP) { access_masks[2] |= - SA_RIGHT_FILE_WRITE_DATA | - SA_RIGHT_FILE_APPEND_DATA | - SA_RIGHT_FILE_WRITE_EA | - SA_RIGHT_FILE_WRITE_ATTRIBUTES; + SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_WRITE_EA | + SEC_FILE_WRITE_ATTRIBUTE; } if (mode & S_IROTH) { access_masks[3] |= - SA_RIGHT_FILE_READ_DATA | - SA_RIGHT_FILE_READ_EA | - SA_RIGHT_FILE_READ_ATTRIBUTES | - SA_RIGHT_FILE_EXECUTE | - STD_RIGHT_SYNCHRONIZE_ACCESS | - STD_RIGHT_READ_CONTROL_ACCESS; + SEC_FILE_READ_DATA | + SEC_FILE_READ_EA | + SEC_FILE_READ_ATTRIBUTE | + SEC_FILE_EXECUTE | + SEC_STD_SYNCHRONIZE | + SEC_STD_READ_CONTROL; } if (mode & S_IWOTH) { access_masks[3] |= - SA_RIGHT_FILE_WRITE_DATA | - SA_RIGHT_FILE_APPEND_DATA | - SA_RIGHT_FILE_WRITE_EA | - SA_RIGHT_FILE_WRITE_ATTRIBUTES; + SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_WRITE_EA | + SEC_FILE_WRITE_ATTRIBUTE; } ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED; @@ -163,16 +163,16 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, */ static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_flags) { - if (!(secinfo_flags & OWNER_SECURITY_INFORMATION)) { + if (!(secinfo_flags & SECINFO_OWNER)) { sd->owner_sid = NULL; } - if (!(secinfo_flags & GROUP_SECURITY_INFORMATION)) { + if (!(secinfo_flags & SECINFO_GROUP)) { sd->group_sid = NULL; } - if (!(secinfo_flags & DACL_SECURITY_INFORMATION)) { + if (!(secinfo_flags & SECINFO_DACL)) { sd->dacl = NULL; } - if (!(secinfo_flags & SACL_SECURITY_INFORMATION)) { + if (!(secinfo_flags & SECINFO_SACL)) { sd->sacl = NULL; } } @@ -214,16 +214,16 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, new_sd = info->set_secdesc.in.sd; /* only set the elements that have been specified */ - if (secinfo_flags & OWNER_SECURITY_INFORMATION) { + if (secinfo_flags & SECINFO_OWNER) { sd->owner_sid = new_sd->owner_sid; } - if (secinfo_flags & GROUP_SECURITY_INFORMATION) { + if (secinfo_flags & SECINFO_GROUP) { sd->group_sid = new_sd->group_sid; } - if (secinfo_flags & DACL_SECURITY_INFORMATION) { + if (secinfo_flags & SECINFO_DACL) { sd->dacl = new_sd->dacl; } - if (secinfo_flags & SACL_SECURITY_INFORMATION) { + if (secinfo_flags & SECINFO_SACL) { sd->sacl = new_sd->sacl; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3d0e444d29..4b8de28488 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -380,11 +380,11 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_CANNOT_DELETE; } - if (access_mask & SEC_RIGHT_MAXIMUM_ALLOWED) { - access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { + access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; } - if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { flags = O_RDWR; } else { flags = O_RDONLY; @@ -460,7 +460,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, union smb_setfileinfo set; set.set_secdesc.file.fnum = fnum; - set.set_secdesc.in.secinfo_flags = DACL_SECURITY_INFORMATION; + set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; status = pvfs_acl_set(pvfs, req, name, fd, &set); @@ -676,7 +676,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, (f2->handle->create_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && - (f2->access_mask & SA_RIGHT_FILE_WRITE_DATA) && + (f2->access_mask & SEC_FILE_WRITE_DATA) && StrCaseCmp(f2->handle->name->original_name, io->generic.in.fname)==0) { break; @@ -862,17 +862,17 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, share_access = io->generic.in.share_access; access_mask = io->generic.in.access_mask; - if (access_mask & SEC_RIGHT_MAXIMUM_ALLOWED) { + if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_READONLY)) { - access_mask = GENERIC_RIGHTS_FILE_READ; + access_mask = SEC_RIGHTS_FILE_READ; } else { - access_mask = GENERIC_RIGHTS_FILE_READ | GENERIC_RIGHTS_FILE_WRITE; + access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; } } /* certain create options are not allowed */ if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - !(access_mask & STD_RIGHT_DELETE_ACCESS)) { + !(access_mask & SEC_STD_DELETE)) { return NT_STATUS_INVALID_PARAMETER; } @@ -914,7 +914,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - if (access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { flags |= O_RDWR; } else { flags |= O_RDONLY; @@ -1240,7 +1240,7 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, struct pvfs_filename *name) NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, - STD_RIGHT_DELETE_ACCESS); + SEC_STD_DELETE); return status; } @@ -1263,7 +1263,7 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, struct pvfs_filename *name) NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE, 0, - STD_RIGHT_DELETE_ACCESS); + SEC_STD_DELETE); return status; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 793a97ba62..db597d7097 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -23,6 +23,7 @@ #include "includes.h" #include "vfs_posix.h" #include "system/filesys.h" +#include "librpc/gen_ndr/ndr_security.h" /* read from a file @@ -50,9 +51,9 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - mask = SA_RIGHT_FILE_READ_DATA; + mask = SEC_FILE_READ_DATA; if (req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) { - mask |= SA_RIGHT_FILE_EXECUTE; + mask |= SEC_FILE_EXECUTE; } if (!(f->access_mask & mask)) { return NT_STATUS_ACCESS_DENIED; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 5a758a6b70..c43ef5c40a 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -258,7 +258,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - if (!(f->access_mask & STD_RIGHT_DELETE_ACCESS)) { + if (!(f->access_mask & SEC_STD_DELETE)) { return NT_STATUS_ACCESS_DENIED; } create_options = h->create_options; @@ -322,7 +322,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } } else { int ret; - if (f->access_mask & SA_RIGHT_FILE_WRITE_APPEND) { + if (f->access_mask & + (SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA)) { ret = ftruncate(h->fd, newstats.st.st_size); } else { ret = truncate(h->name->full_name, newstats.st.st_size); diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 3f6e8d908a..025ea3f3eb 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_security.h" /* @@ -48,7 +49,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (!(f->access_mask & SA_RIGHT_FILE_WRITE_APPEND)) { + if (!(f->access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA))) { return NT_STATUS_ACCESS_VIOLATION; } -- cgit From a8a3fec528f6ee9a4a0171fb4186e8dcaba76518 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 1 Dec 2004 11:35:01 +0000 Subject: r4026: added NT ACL checking on pvfs_open() for existing files. I need to work out some way to do a decent test suite for this. (This used to be commit 9a9a0d0e791e4b64f0a35c921729e623b977af47) --- source4/ntvfs/posix/pvfs_acl.c | 80 +++++++++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_open.c | 26 +++++++------- 2 files changed, 90 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 2fff6db628..236bc4d98d 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -208,7 +208,7 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, sd = acl->info.sd; break; default: - return NT_STATUS_INVALID_LEVEL; + return NT_STATUS_INVALID_ACL; } new_sd = info->set_secdesc.in.sd; @@ -263,7 +263,7 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, sd = acl->info.sd; break; default: - return NT_STATUS_INVALID_LEVEL; + return NT_STATUS_INVALID_ACL; } normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags); @@ -273,3 +273,79 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, return NT_STATUS_OK; } + +/* + default access check function based on unix permissions + doing this saves on building a full security descriptor + for the common case of access check on files with no + specific NT ACL +*/ +NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + uint32_t *access_mask) +{ + uid_t uid = geteuid(); + uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL; + + /* owner and root get extra permissions */ + if (uid == 0 || uid == name->st.st_uid) { + max_bits |= SEC_STD_ALL; + } + + if (*access_mask == SEC_FLAG_MAXIMUM_ALLOWED) { + *access_mask = max_bits; + return NT_STATUS_OK; + } + + if (*access_mask & ~max_bits) { + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} + + +/* + check the security descriptor on a file, if any + + *access_mask is modified with the access actually granted +*/ +NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + uint32_t *access_mask) +{ + struct nt_user_token *token = req->session->session_info->nt_user_token; + struct xattr_NTACL *acl; + NTSTATUS status; + struct security_descriptor *sd; + + acl = talloc_p(req, struct xattr_NTACL); + if (acl == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_acl_load(pvfs, name, -1, acl); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + talloc_free(acl); + return pvfs_access_check_unix(pvfs, req, name, access_mask); + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (acl->version) { + case 1: + sd = acl->info.sd; + break; + default: + return NT_STATUS_INVALID_ACL; + } + + status = sec_access_check(sd, token, *access_mask, access_mask); + + talloc_free(acl); + + return status; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 4b8de28488..17740f7636 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -862,14 +862,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, share_access = io->generic.in.share_access; access_mask = io->generic.in.access_mask; - if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { - if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_READONLY)) { - access_mask = SEC_RIGHTS_FILE_READ; - } else { - access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; - } - } - /* certain create options are not allowed */ if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && !(access_mask & SEC_STD_DELETE)) { @@ -914,12 +906,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { - flags |= O_RDWR; - } else { - flags |= O_RDONLY; - } - if (io->generic.in.file_attr & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_INVALID_PARAMETER; } @@ -949,6 +935,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_CANNOT_DELETE; } + /* check the security descriptor */ + status = pvfs_access_check(pvfs, req, name, &access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + f = talloc_p(req, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; @@ -1036,6 +1028,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->have_opendb_entry = True; + if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { + flags |= O_RDWR; + } else { + flags |= O_RDONLY; + } + /* do the actual open */ fd = open(f->handle->name->full_name, flags); if (fd == -1) { -- cgit From cc8f4358cca2404895015e2351394f2f4a16e025 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Dec 2004 04:37:36 +0000 Subject: r4035: more effort on consistent naming of the access mask bits. This removes the duplicate named SEC_RIGHTS_MAXIMUM_ALLOWED and SEC_RIGHTS_FULL_CONTROL, which are just other names for SEC_FLAG_MAXIMUM_ALLOWED and SEC_RIGHTS_FILE_ALL. The latter names match the new naming conventions in security.idl Also added names for the generic->specific mappings for files are directories (This used to be commit 17a4e0b3aca227b40957ed1e0c57e498debc6ddf) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 236bc4d98d..c584ddc4e8 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -71,7 +71,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, - Group - Everyone */ - access_masks[0] = SEC_RIGHTS_FULL_CONTROL; + access_masks[0] = SEC_RIGHTS_FILE_ALL; access_masks[1] = 0; access_masks[2] = 0; access_masks[3] = 0; -- cgit From 4183b2ac3832cdc2055d7eb3ed7121a9ea91085c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 2 Dec 2004 04:51:56 +0000 Subject: r4037: fixed a bunch of "might be uninitialised" warnings after enabling -O1 in my compile (This used to be commit 0928b1f5b68c858922c3ea6c27ed03b5091c6221) --- source4/ntvfs/posix/pvfs_resolve.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 7329968d6c..7e7f49d0af 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -546,8 +546,8 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, struct pvfs_filename *name) { - dev_t device; - ino_t inode; + dev_t device = 0; + ino_t inode = 0; if (name->exists) { device = name->st.st_dev; -- cgit From 58c326809a816703dc516c3022c9c4dbb9d09445 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 06:24:38 +0000 Subject: r4052: fixed a bunch of code to use the type safe _p allocation macros (This used to be commit 80d15fa3402a9d1183467463f6b21c0b674bc442) --- source4/ntvfs/common/opendb.c | 14 ++++++-------- source4/ntvfs/ntvfs_base.c | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 8947a5d255..57beba8c68 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -222,7 +222,6 @@ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, struct odb_context *odb = lck->odb; TDB_DATA dbuf; struct odb_entry e; - char *tp; int i, count; struct odb_entry *elist; @@ -249,13 +248,13 @@ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, } } - tp = Realloc(dbuf.dptr, (count+1) * sizeof(struct odb_entry)); - if (tp == NULL) { + elist = realloc_p(dbuf.dptr, struct odb_entry, count+1); + if (elist == NULL) { if (dbuf.dptr) free(dbuf.dptr); return NT_STATUS_NO_MEMORY; } - dbuf.dptr = tp; + dbuf.dptr = (char *)elist; dbuf.dsize = (count+1) * sizeof(struct odb_entry); memcpy(dbuf.dptr + (count*sizeof(struct odb_entry)), @@ -279,7 +278,6 @@ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) struct odb_context *odb = lck->odb; TDB_DATA dbuf; struct odb_entry e; - char *tp; struct odb_entry *elist; int count; @@ -299,13 +297,13 @@ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) elist = (struct odb_entry *)dbuf.dptr; count = dbuf.dsize / sizeof(struct odb_entry); - tp = Realloc(dbuf.dptr, (count+1) * sizeof(struct odb_entry)); - if (tp == NULL) { + elist = realloc_p(dbuf.dptr, struct odb_entry, count+1); + if (elist == NULL) { if (dbuf.dptr) free(dbuf.dptr); return NT_STATUS_NO_MEMORY; } - dbuf.dptr = tp; + dbuf.dptr = (char *)elist; dbuf.dsize = (count+1) * sizeof(struct odb_entry); memcpy(dbuf.dptr + (count*sizeof(struct odb_entry)), diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 136ef14e4c..ca6fbf0de8 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -32,7 +32,7 @@ /* the list of currently registered NTVFS backends, note that there * can be more than one backend with the same name, as long as they * have different typesx */ -static struct { +static struct ntvfs_backend { const struct ntvfs_ops *ops; } *backends = NULL; static int num_backends; @@ -57,7 +57,7 @@ NTSTATUS ntvfs_register(const void *_ops) return NT_STATUS_OBJECT_NAME_COLLISION; } - backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); + backends = realloc_p(backends, struct ntvfs_backend, num_backends+1); if (!backends) { smb_panic("out of memory in ntvfs_register"); } -- cgit From e5ce904ddbd6175ba86ed827bf096b76b11b5511 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 06:42:06 +0000 Subject: r4054: got rid of Realloc(), replacing it with the type safe macro realloc_p() (This used to be commit b0f6e21481745d1b2ced28d9ed6f09f6ffd99562) --- source4/ntvfs/common/brlock.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e01f458e74..7b351f77b0 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -229,9 +229,8 @@ NTSTATUS brl_lock(struct brl_context *brl, void *notify_ptr) { TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct lock, *locks; - char *tp; + int count=0, i; + struct lock_struct lock, *locks=NULL; NTSTATUS status; kbuf.dptr = (char *)file_key->data; @@ -279,14 +278,14 @@ NTSTATUS brl_lock(struct brl_context *brl, } /* no conflicts - add it to the list of locks */ - tp = Realloc(dbuf.dptr, dbuf.dsize + sizeof(*locks)); - if (!tp) { + locks = realloc_p(locks, struct lock_struct, count+1); + if (!locks) { status = NT_STATUS_NO_MEMORY; goto fail; } else { - dbuf.dptr = tp; + dbuf.dptr = (char *)locks; } - memcpy(dbuf.dptr + dbuf.dsize, &lock, sizeof(lock)); + locks[count] = lock; dbuf.dsize += sizeof(lock); if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { -- cgit From 6e6374cb5bcffb4df8bdb0a83327fff92b61ac84 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 07:20:30 +0000 Subject: r4055: fixed more places to use type safe allocation macros (This used to be commit eec698254f67365f27b4b7569fa982e22472aca1) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index bfba31b46f..736aa3652f 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -121,7 +121,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - private = talloc(req->tcon, sizeof(struct cvfs_private)); + private = talloc_p(req->tcon, struct cvfs_private); if (!private) { return NT_STATUS_NO_MEMORY; } -- cgit From 4075e28a4f87993858e630012cffe96e49ff6717 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 3 Dec 2004 13:04:10 +0000 Subject: r4056: modified the access check code based on results from RAW-ACLS test. Also added generic mapping bits for pvfs. We don't pass RAW-ACLS yet, but its close. (This used to be commit c7cbd966d49a5345ea326732587555d209c531fc) --- source4/ntvfs/posix/pvfs_acl.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index c584ddc4e8..6eb4c13804 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -27,6 +27,38 @@ #include "librpc/gen_ndr/ndr_xattr.h" +/* + map a single access_mask from generic to specific bits for files/dirs +*/ +static uint32_t pvfs_translate_mask(uint32_t access_mask) +{ + if (access_mask & SEC_MASK_GENERIC) { + if (access_mask & SEC_GENERIC_READ) access_mask |= SEC_RIGHTS_FILE_READ; + if (access_mask & SEC_GENERIC_WRITE) access_mask |= SEC_RIGHTS_FILE_WRITE; + if (access_mask & SEC_GENERIC_EXECUTE) access_mask |= SEC_RIGHTS_FILE_EXECUTE; + if (access_mask & SEC_GENERIC_ALL) access_mask |= SEC_RIGHTS_FILE_ALL; + access_mask &= ~SEC_MASK_GENERIC; + } + return access_mask; +} + + +/* + map any generic access bits in the given acl + this relies on the fact that the mappings for files and directories + are the same +*/ +static void pvfs_translate_generic_bits(struct security_acl *acl) +{ + unsigned i; + + for (i=0;inum_aces;i++) { + struct security_ace *ace = &acl->aces[i]; + ace->access_mask = pvfs_translate_mask(ace->access_mask); + } +} + + /* setup a default ACL for a file */ @@ -222,9 +254,11 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } if (secinfo_flags & SECINFO_DACL) { sd->dacl = new_sd->dacl; + pvfs_translate_generic_bits(sd->dacl); } if (secinfo_flags & SECINFO_SACL) { sd->sacl = new_sd->sacl; + pvfs_translate_generic_bits(sd->sacl); } status = pvfs_acl_save(pvfs, name, fd, acl); @@ -343,8 +377,15 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, return NT_STATUS_INVALID_ACL; } + /* expand the generic access bits to file specific bits */ + *access_mask = pvfs_translate_mask(*access_mask); + + /* check the acl against the required access mask */ status = sec_access_check(sd, token, *access_mask, access_mask); + /* this bit is always granted, even if not asked for */ + *access_mask |= SEC_FILE_READ_ATTRIBUTE; + talloc_free(acl); return status; -- cgit From ae3f904038477fdbee2a35ae64b4cf6d7f624d03 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 4 Dec 2004 10:15:54 +0000 Subject: r4060: removed an unused file (This used to be commit 35ca4e1e81c5d927238e90d0c6c09987c11b5d35) --- source4/ntvfs/ntvfs_dfs.c | 117 ---------------------------------------------- 1 file changed, 117 deletions(-) delete mode 100644 source4/ntvfs/ntvfs_dfs.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_dfs.c b/source4/ntvfs/ntvfs_dfs.c deleted file mode 100644 index afba3ee43e..0000000000 --- a/source4/ntvfs/ntvfs_dfs.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NTVFS base code - Copyright (C) Andrew Tridgell 2003 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* - this implements the core code for all NTVFS modules. Backends register themselves here. -*/ - -#include "includes.h" - - -/* the list of currently registered NTVFS backends, note that there - * can be more than one backend with the same name, as long as they - * have different typesx */ -static struct { - const char *name; - enum ntvfs_type type; - struct ntvfs_ops *ops; -} *backends = NULL; -static int num_backends; - -/* - register a NTVFS backend. - - The 'name' can be later used by other backends to find the operations - structure for this backend. - - The 'type' is used to specify whether this is for a disk, printer or IPC$ share -*/ -BOOL ntvfs_register(const char *name, enum ntvfs_type type, struct ntvfs_ops *ops) -{ - if (ntvfs_backend_byname(name, type) != NULL) { - /* its already registered! */ - DEBUG(2,("NTVFS backend '%s' for type %d already registered\n", - name, (int)type)); - return False; - } - - backends = Realloc(backends, sizeof(backends[0]) * (num_backends+1)); - if (!backends) { - smb_panic("out of memory in ntvfs_register"); - } - - backends[num_backends].name = smb_xstrdup(name); - backends[num_backends].type = type; - backends[num_backends].ops = smb_xmemdup(ops, sizeof(*ops)); - - num_backends++; - - return True; -} - - -/* - return the operations structure for a named backend of the specified type -*/ -struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) -{ - int i; - - for (i=0;isizeof_ntvfs_ops = sizeof(struct ntvfs_ops); - sizes->sizeof_off_t = sizeof(off_t); - sizes->sizeof_tcon_context = sizeof(struct tcon_context); - - return NTVFS_INTERFACE_VERSION; -} - - -/* - initialise the NTVFS subsystem -*/ -BOOL ntvfs_init(void) -{ - /* initialise our 3 basic backends. These are assumed to be - * present and are always built in */ - if (!posix_vfs_init() || - !ipc_vfs_init() || - !print_vfs_init()) { - return False; - } - - DEBUG(3,("NTVFS version %d initialised\n", NTVFS_INTERFACE_VERSION)); - return True; -} -- cgit From 4127edc1afd702ac3bcb77893ba864eb98729451 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 4 Dec 2004 12:42:40 +0000 Subject: r4062: the RAW-ACLS test now passes. The SEC_STD_DELETE bit is rather strange though - I expect we'll need to tweak that some more. (This used to be commit e3500811b90b8423ee7694609340f394957d1160) --- source4/ntvfs/posix/pvfs_open.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 17740f7636..a53deda270 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -103,6 +103,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, int fnum; NTSTATUS status; uint32_t create_action; + uint32_t access_mask = io->generic.in.access_mask; if (name->stream_name) { return NT_STATUS_NOT_A_DIRECTORY; @@ -152,6 +153,14 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_TOO_MANY_OPENED_FILES; } + if (name->exists) { + /* check the security descriptor */ + status = pvfs_access_check(pvfs, req, name, &access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + f->fnum = fnum; f->session = req->session; f->smbpid = req->smbpid; @@ -160,6 +169,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->lock_count = 0; f->share_access = io->generic.in.share_access; f->impersonation = io->generic.in.impersonation; + f->access_mask = access_mask; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); -- cgit From 79bb84cea41d8a034283ced22a83614922882df0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 5 Dec 2004 07:58:58 +0000 Subject: r4067: no matches in findnext is not an error (This used to be commit 6da058a28ba44a02964d375c9e390fbd472bc2b6) --- source4/ntvfs/posix/pvfs_search.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index f805f201f6..4ee81503c0 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -552,11 +552,6 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, return status; } - /* not matching any entries is an error */ - if (reply_count == 0) { - return NT_STATUS_NO_MORE_ENTRIES; - } - io->t2fnext.out.count = reply_count; io->t2fnext.out.end_of_search = pvfs_list_eos(dir, search->current_index) ? 1 : 0; -- cgit From 6ca874f71ad77c82d6e161a3e4772100de2ad6c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Dec 2004 05:41:19 +0000 Subject: r4147: converted from NT_USER_TOKEN to struct security_token this is mostly just a tidyup, but also adds the privilege_mask, which I will be using shortly in ACL checking. note that I had to move the definition of struct security_token out of security.idl as pidl doesn't yet handle arrays of pointers, and the usual workaround (to use a intermediate structure) would make things too cumbersome for this structure, especially given we never encode it to NDR. (This used to be commit 7b446af09b8050746bfc2c50e9d56aa94397cc1a) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- source4/ntvfs/unixuid/vfs_unixuid.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 6eb4c13804..e2d779f91c 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -350,7 +350,7 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, struct pvfs_filename *name, uint32_t *access_mask) { - struct nt_user_token *token = req->session->session_info->nt_user_token; + struct security_token *token = req->session->session_info->security_token; struct xattr_NTACL *acl; NTSTATUS status; struct security_descriptor *sd; diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 0535475dd3..1c4572969f 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -28,7 +28,7 @@ struct unixuid_private { struct sidmap_context *sidmap; struct unix_sec_ctx *last_sec_ctx; - struct nt_user_token *last_token; + struct security_token *last_token; }; @@ -90,11 +90,11 @@ static NTSTATUS set_unix_security(struct unix_sec_ctx *sec) } /* - form a unix_sec_ctx from the current nt_user_token + form a unix_sec_ctx from the current security_token */ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, - struct nt_user_token *token, + struct security_token *token, struct unix_sec_ctx **sec) { struct unixuid_private *private = ntvfs->private_data; @@ -108,13 +108,13 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, } status = sidmap_sid_to_unixuid(private->sidmap, - token->user_sids[0], &(*sec)->uid); + token->user_sid, &(*sec)->uid); if (!NT_STATUS_IS_OK(status)) { return status; } status = sidmap_sid_to_unixgid(private->sidmap, - token->user_sids[1], &(*sec)->gid); + token->group_sid, &(*sec)->gid); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -127,7 +127,7 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, for (i=0;i<(*sec)->ngroups;i++) { status = sidmap_sid_to_unixgid(private->sidmap, - token->user_sids[i+2], &(*sec)->groups[i]); + token->sids[i+2], &(*sec)->groups[i]); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -143,7 +143,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct unix_sec_ctx **sec) { struct unixuid_private *private = ntvfs->private_data; - struct nt_user_token *token = req->session->session_info->nt_user_token; + struct security_token *token = req->session->session_info->security_token; void *ctx = talloc(req, 0); struct unix_sec_ctx *newsec; NTSTATUS status; @@ -157,7 +157,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - if (req->session->session_info->nt_user_token == private->last_token) { + if (req->session->session_info->security_token == private->last_token) { newsec = private->last_sec_ctx; } else { status = nt_token_to_unix_security(ntvfs, req, token, &newsec); @@ -169,7 +169,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, talloc_free(private->last_sec_ctx); } private->last_sec_ctx = newsec; - private->last_token = req->session->session_info->nt_user_token; + private->last_token = req->session->session_info->security_token; talloc_steal(private, newsec); } -- cgit From f2dbe4610704d97725a69c076af52fbb6e899640 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Dec 2004 08:33:08 +0000 Subject: r4160: fixed the file_type in ntcreatex reply on a named pipe. NT4 requires this to be right. (This used to be commit e22de9734f66bee3c9eaf8191fcae9fb06a0034f) --- source4/ntvfs/ipc/vfs_ipc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b4c41d58d3..2f482bb5e4 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -267,6 +267,7 @@ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs, ZERO_STRUCT(oi->ntcreatex.out); oi->ntcreatex.out.fnum = p->fnum; oi->ntcreatex.out.ipc_state = p->ipc_state; + oi->ntcreatex.out.file_type = FILE_TYPE_MESSAGE_MODE_PIPE; return status; } -- cgit From bbe03283475d4374f51af2e37ca2464f01885f91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Dec 2004 09:02:18 +0000 Subject: r4162: this should fix the delete/findnext problem from OS/2 clients. Thanks again to kukks for the excellent and detailed bug report (This used to be commit 7dfffe4ac0d6858ae6848708df1baa11a6819680) --- source4/ntvfs/posix/pvfs_dirlist.c | 4 +++- source4/ntvfs/posix/pvfs_search.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 613de08087..b29c776cba 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -282,5 +282,7 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) pvfs_list_hibernate(dir); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; + /* it is not an error to give a bad name (it may have been deleted). Instead + just continue from end of directory */ + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 4ee81503c0..1c49701f04 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -562,6 +562,10 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, talloc_free(search); } + if (reply_count == 0) { + return NT_STATUS_NO_SUCH_FILE; + } + return NT_STATUS_OK; } -- cgit From 08a409f9b935f142de4ac15327fef0535a78942e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Dec 2004 09:11:39 +0000 Subject: r4163: 2nd attempt at fixing the OS/2 "del *" problem (This used to be commit ae14905d9522dbdc1709ef110b9933adcb740a26) --- source4/ntvfs/posix/pvfs_dirlist.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index b29c776cba..1ef6e408c3 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -179,8 +179,6 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) return dir->last_name; } - if (dir->last_name) talloc_free(dir->last_name); - dir->last_name = NULL; dir->end_of_search = True; pvfs_list_hibernate(dir); return NULL; @@ -196,10 +194,6 @@ void pvfs_list_hibernate(struct pvfs_dir *dir) closedir(dir->dir); dir->dir = NULL; } - if (!dir->no_wildcard && dir->last_name) { - talloc_free(dir->last_name); - dir->last_name = NULL; - } } -- cgit From fe01af9fb278a320820b41b7970a1f04b3b696a5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Dec 2004 11:30:30 +0000 Subject: r4165: added a 100 element name cache to cope with some amount of seeking back to filenames that have been deleted. This fixes the new os/2 delete test. (This used to be commit 6d471db13ab132655a07e11533a559446e56fc00) --- source4/ntvfs/posix/pvfs_dirlist.c | 63 +++++++++++++++++++++++++++----------- source4/ntvfs/posix/pvfs_search.c | 10 +++--- 2 files changed, 50 insertions(+), 23 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 1ef6e408c3..5c67b2d189 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -25,15 +25,24 @@ #include "vfs_posix.h" #include "system/dir.h" +#define NAME_CACHE_SIZE 100 + +struct name_cache_entry { + char *name; + off_t offset; +}; + struct pvfs_dir { struct pvfs_state *pvfs; BOOL no_wildcard; - char *last_name; + char *single_name; const char *pattern; off_t offset; DIR *dir; const char *unix_path; BOOL end_of_search; + struct name_cache_entry *name_cache; + uint32_t name_cache_index; }; /* @@ -55,8 +64,8 @@ static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filen return NT_STATUS_NO_MEMORY; } - dir->last_name = talloc_strdup(dir, pattern); - if (!dir->last_name) { + dir->single_name = talloc_strdup(dir, pattern); + if (!dir->single_name) { return NT_STATUS_NO_MEMORY; } @@ -88,7 +97,7 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, char *pattern; struct pvfs_dir *dir; - (*dirp) = talloc_p(mem_ctx, struct pvfs_dir); + (*dirp) = talloc_zero_p(mem_ctx, struct pvfs_dir); if (*dirp == NULL) { return NT_STATUS_NO_MEMORY; } @@ -126,9 +135,15 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, dir->pvfs = pvfs; dir->no_wildcard = False; - dir->last_name = NULL; dir->end_of_search = False; dir->offset = 0; + dir->name_cache = talloc_zero_array_p(dir, + struct name_cache_entry, + NAME_CACHE_SIZE); + if (dir->name_cache == NULL) { + talloc_free(dir); + return NT_STATUS_NO_MEMORY; + } talloc_set_destructor(dir, pvfs_dirlist_destructor); @@ -147,7 +162,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) dir->end_of_search = True; if (*ofs != 0) return NULL; (*ofs)++; - return dir->last_name; + return dir->single_name; } if (*ofs != dir->offset) { @@ -157,6 +172,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) while ((de = readdir(dir->dir))) { const char *dname = de->d_name; + struct name_cache_entry *e; if (ms_fnmatch(dir->pattern, dname, dir->pvfs->tcon->smb_conn->negotiate.protocol) != 0) { @@ -173,10 +189,15 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) dir->offset = telldir(dir->dir); (*ofs) = dir->offset; - if (dir->last_name) talloc_free(dir->last_name); - dir->last_name = talloc_strdup(dir, de->d_name); + dir->name_cache_index = (dir->name_cache_index+1) % NAME_CACHE_SIZE; + e = &dir->name_cache[dir->name_cache_index]; + + if (e->name) talloc_free(e->name); + + e->name = talloc_strdup(dir, de->d_name); + e->offset = dir->offset; - return dir->last_name; + return e->name; } dir->end_of_search = True; @@ -248,16 +269,26 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) { struct dirent *de; NTSTATUS status; + int i; status = pvfs_list_wakeup(dir, ofs); if (!NT_STATUS_IS_OK(status)) { return status; } - if (dir->last_name && - StrCaseCmp(name, dir->last_name) == 0) { - *ofs = dir->offset; - return NT_STATUS_OK; + for (i=dir->name_cache_index;i>=0;i--) { + struct name_cache_entry *e = &dir->name_cache[i]; + if (e->name && StrCaseCmp(name, e->name) == 0) { + *ofs = e->offset; + return NT_STATUS_OK; + } + } + for (i=NAME_CACHE_SIZE-1;i>dir->name_cache_index;i--) { + struct name_cache_entry *e = &dir->name_cache[i]; + if (e->name && StrCaseCmp(name, e->name) == 0) { + *ofs = e->offset; + return NT_STATUS_OK; + } } rewinddir(dir->dir); @@ -266,8 +297,6 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) if (StrCaseCmp(name, de->d_name) == 0) { dir->offset = telldir(dir->dir); *ofs = dir->offset; - if (dir->last_name) talloc_free(dir->last_name); - dir->last_name = talloc_strdup(dir, de->d_name); return NT_STATUS_OK; } } @@ -276,7 +305,5 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) pvfs_list_hibernate(dir); - /* it is not an error to give a bad name (it may have been deleted). Instead - just continue from end of directory */ - return NT_STATUS_OK; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 1c49701f04..c336035218 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -533,7 +533,11 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, if (io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { status = pvfs_list_seek(dir, io->t2fnext.in.last_name, &search->current_index); if (!NT_STATUS_IS_OK(status)) { - return status; + if (io->t2fnext.in.resume_key) { + search->current_index = io->t2fnext.in.resume_key; + } else { + return status; + } } } else if (io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) { /* plain continue - nothing to do */ @@ -562,10 +566,6 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, talloc_free(search); } - if (reply_count == 0) { - return NT_STATUS_NO_SUCH_FILE; - } - return NT_STATUS_OK; } -- cgit From fbd8c61ff7a7c41d16c400ddb87ad290f4af167d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 2004 10:48:21 +0000 Subject: r4173: - new t2open code, that can cope with "create with EAs". Many thanks to kukks on #samba-technical for the sniffs that allowed me to work this out - much simpler ntvfs open generic mapping code - added t2open create with EA torture test to RAW-OPEN test (This used to be commit a56d95ad89b4f32a05974c4fe9a816d67aa369e3) --- source4/ntvfs/ntvfs_generic.c | 332 ++++++++++++++++++---------------------- source4/ntvfs/posix/pvfs_open.c | 36 ----- 2 files changed, 147 insertions(+), 221 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 49de8944ff..407bd38f74 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -150,13 +150,6 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, union smb_setfileinfo *sf; uint_t state; - /* this is really strange, but matches w2k3 */ - if (io->generic.level == RAW_OPEN_T2OPEN && - io->t2open.in.open_func != OPENX_OPEN_FUNC_OPEN && - NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - return NT_STATUS_ACCESS_DENIED; - } - if (!NT_STATUS_IS_OK(status)) { return status; } @@ -167,7 +160,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->openold.out.attrib = io2->generic.out.attrib; io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openold.out.size = io2->generic.out.size; - io->openold.out.rmode = io->openold.in.flags; + io->openold.out.rmode = io->openold.in.open_mode; break; case RAW_OPEN_OPENX: @@ -175,6 +168,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->openx.out.attrib = io2->generic.out.attrib; io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openx.out.size = io2->generic.out.size; + io->openx.out.access = (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK); io->openx.out.ftype = 0; io->openx.out.devstate = 0; io->openx.out.action = io2->generic.out.create_action; @@ -190,15 +184,15 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, break; case RAW_OPEN_T2OPEN: - io->t2open.out.fnum = io2->openx.out.fnum; - io->t2open.out.attrib = io2->openx.out.attrib; - io->t2open.out.write_time = 0; - io->t2open.out.size = io2->openx.out.size; - io->t2open.out.access = io->t2open.in.open_mode; - io->t2open.out.ftype = io2->openx.out.ftype; - io->t2open.out.devstate = io2->openx.out.devstate; - io->t2open.out.action = io2->openx.out.action; - io->t2open.out.unknown = 0; + io->t2open.out.fnum = io2->generic.out.fnum; + io->t2open.out.attrib = io2->generic.out.attrib; + io->t2open.out.write_time = nt_time_to_unix(io2->generic.out.write_time); + io->t2open.out.size = io2->generic.out.size; + io->t2open.out.access = io->t2open.in.open_mode; + io->t2open.out.ftype = 0; + io->t2open.out.devstate = 0; + io->t2open.out.action = io2->generic.out.create_action; + io->t2open.out.file_id = 0; break; case RAW_OPEN_MKNEW: @@ -248,6 +242,106 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, return NT_STATUS_OK; } +/* + the core of the mapping between openx style parameters and ntcreatex + parameters +*/ +static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, + uint16_t open_func, const char *fname, + union smb_open *io2) +{ + if (flags & OPENX_FLAGS_REQUEST_OPLOCK) { + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; + } + if (flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { + io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; + } + + switch (open_mode & OPENX_MODE_ACCESS_MASK) { + case OPENX_MODE_ACCESS_READ: + io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ; + break; + case OPENX_MODE_ACCESS_WRITE: + io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE; + break; + case OPENX_MODE_ACCESS_RDWR: + case OPENX_MODE_ACCESS_FCB: + case OPENX_MODE_ACCESS_EXEC: + io2->generic.in.access_mask = + SEC_RIGHTS_FILE_READ | + SEC_RIGHTS_FILE_WRITE; + break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + switch (open_mode & OPENX_MODE_DENY_MASK) { + case OPENX_MODE_DENY_READ: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_WRITE: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + break; + case OPENX_MODE_DENY_ALL: + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + case OPENX_MODE_DENY_NONE: + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + break; + case OPENX_MODE_DENY_DOS: + /* DENY_DOS is quite strange - it depends on the filename! */ + io2->generic.in.create_options |= + NTCREATEX_OPTIONS_PRIVATE_DENY_DOS; + if (is_exe_filename(fname)) { + io2->generic.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + } else { + if ((open_mode & OPENX_MODE_ACCESS_MASK) == OPENX_MODE_ACCESS_READ) { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; + } else { + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + } + } + break; + case OPENX_MODE_DENY_FCB: + io2->generic.in.create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB; + io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + break; + default: + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + switch (open_func) { + case (OPENX_OPEN_FUNC_OPEN): + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; + break; + case (OPENX_OPEN_FUNC_TRUNC): + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; + break; + case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + break; + case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): + io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; + break; + default: + /* this one is very strange */ + if ((open_mode & OPENX_MODE_ACCESS_MASK) == OPENX_MODE_ACCESS_EXEC) { + io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; + break; + } + return NT_STATUS_INVALID_LOCK_SEQUENCE; + } + + return NT_STATUS_OK; +} + /* NTVFS open generic to any mapper */ @@ -272,105 +366,15 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, switch (io->generic.level) { case RAW_OPEN_OPENX: - if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) { - io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK; - } - if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) { - io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK; - } - - switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) { - case OPENX_MODE_ACCESS_READ: - io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ; - io->openx.out.access = OPENX_MODE_ACCESS_READ; - break; - case OPENX_MODE_ACCESS_WRITE: - io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE; - io->openx.out.access = OPENX_MODE_ACCESS_WRITE; - break; - case OPENX_MODE_ACCESS_RDWR: - case OPENX_MODE_ACCESS_FCB: - case OPENX_MODE_ACCESS_EXEC: - io2->generic.in.access_mask = - SEC_RIGHTS_FILE_READ | - SEC_RIGHTS_FILE_WRITE; - io->openx.out.access = OPENX_MODE_ACCESS_RDWR; - break; - default: - status = NT_STATUS_INVALID_LOCK_SEQUENCE; - goto done; - } - - switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) { - case OPENX_MODE_DENY_READ: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPENX_MODE_DENY_WRITE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - break; - case OPENX_MODE_DENY_ALL: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - case OPENX_MODE_DENY_NONE: - io2->generic.in.share_access = - NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPENX_MODE_DENY_DOS: - /* DENY_DOS is quite strange - it depends on the filename! */ - io2->generic.in.create_options |= - NTCREATEX_OPTIONS_PRIVATE_DENY_DOS; - if (is_exe_filename(io->openx.in.fname)) { - io2->generic.in.share_access = - NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE; - } else { - if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == - OPENX_MODE_ACCESS_READ) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - } else { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - } - } - break; - case OPENX_MODE_DENY_FCB: - io2->generic.in.create_options |= - NTCREATEX_OPTIONS_PRIVATE_DENY_FCB; - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - default: - status = NT_STATUS_INVALID_LOCK_SEQUENCE; - goto done; - } - - switch (io->openx.in.open_func) { - case (OPENX_OPEN_FUNC_OPEN): - io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; - break; - case (OPENX_OPEN_FUNC_TRUNC): - io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE; - break; - case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; - case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF; - break; - case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE): - io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF; - break; - default: - /* this one is very strange */ - if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == - OPENX_MODE_ACCESS_EXEC) { - io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; - break; - } - status = NT_STATUS_INVALID_LOCK_SEQUENCE; + status = map_openx_open(io->openx.in.flags, + io->openx.in.open_mode, + io->openx.in.open_func, + io->openx.in.fname, + io2); + if (!NT_STATUS_IS_OK(status)) { goto done; } - io2->generic.in.alloc_size = 0; io2->generic.in.file_attr = io->openx.in.file_attrs; io2->generic.in.fname = io->openx.in.fname; @@ -379,85 +383,44 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, case RAW_OPEN_OPEN: + status = map_openx_open(0, + io->openold.in.open_mode, + OPENX_OPEN_FUNC_OPEN, + io->openold.in.fname, + io2); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + io2->generic.in.file_attr = io->openold.in.search_attrs; io2->generic.in.fname = io->openold.in.fname; - io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN; - switch (io->openold.in.flags & OPEN_FLAGS_MODE_MASK) { - case OPEN_FLAGS_OPEN_READ: - io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ; - io->openold.out.rmode = DOS_OPEN_RDONLY; - break; - case OPEN_FLAGS_OPEN_WRITE: - io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE; - io->openold.out.rmode = DOS_OPEN_WRONLY; - break; - case OPEN_FLAGS_OPEN_RDWR: - case 0xf: /* FCB mode */ - io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ | - SEC_RIGHTS_FILE_WRITE; - io->openold.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */ - break; - default: - DEBUG(2,("ntvfs_map_open(OPEN): invalid mode 0x%x\n", - io->openold.in.flags & OPEN_FLAGS_MODE_MASK)); - status = NT_STATUS_INVALID_PARAMETER; + + status = ntvfs->ops->openfile(ntvfs, req, io2); + break; + + case RAW_OPEN_T2OPEN: + io2->generic.level = RAW_OPEN_NTTRANS_CREATE; + + if (io->t2open.in.open_func == 0) { + status = NT_STATUS_OBJECT_NAME_COLLISION; goto done; } - - switch (io->openold.in.flags & OPEN_FLAGS_DENY_MASK) { - case OPEN_FLAGS_DENY_DOS: - /* DENY_DOS is quite strange - it depends on the filename! */ - if (is_exe_filename(io->openold.in.fname)) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - } else { - if ((io->openold.in.flags & OPEN_FLAGS_MODE_MASK) == - OPEN_FLAGS_OPEN_READ) { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - } else { - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - } - } - break; - case OPEN_FLAGS_DENY_ALL: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; - break; - case OPEN_FLAGS_DENY_WRITE: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ; - break; - case OPEN_FLAGS_DENY_READ: - io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE; - break; - case OPEN_FLAGS_DENY_NONE: - io2->generic.in.share_access = - NTCREATEX_SHARE_ACCESS_WRITE | - NTCREATEX_SHARE_ACCESS_READ; - break; - case OPEN_FLAGS_DENY_MASK: - io2->generic.in.share_access = - NTCREATEX_SHARE_ACCESS_READ| - NTCREATEX_SHARE_ACCESS_WRITE; - break; - default: - DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n", - io->openold.in.flags & OPEN_FLAGS_DENY_MASK)); - status = NT_STATUS_INVALID_PARAMETER; + + status = map_openx_open(io->t2open.in.flags, + io->t2open.in.open_mode, + io->t2open.in.open_func, + io->t2open.in.fname, + io2); + if (!NT_STATUS_IS_OK(status)) { goto done; } - status = ntvfs->ops->openfile(ntvfs, req, io2); - break; + io2->generic.in.file_attr = io->t2open.in.file_attrs; + io2->generic.in.fname = io->t2open.in.fname; + io2->generic.in.ea_list = talloc_p(io2, struct smb_ea_list); + io2->generic.in.ea_list->num_eas = io->t2open.in.num_eas; + io2->generic.in.ea_list->eas = io->t2open.in.eas; - case RAW_OPEN_T2OPEN: - io2->generic.level = RAW_OPEN_OPENX; - io2->openx.in.flags = io->t2open.in.flags; - io2->openx.in.open_mode = io->t2open.in.open_mode; - io2->openx.in.search_attrs = 0; - io2->openx.in.file_attrs = io->t2open.in.file_attrs; - io2->openx.in.write_time = io->t2open.in.write_time; - io2->openx.in.open_func = OPENX_OPEN_FUNC_OPEN; - io2->openx.in.size = io->t2open.in.size; - io2->openx.in.timeout = io->t2open.in.timeout; - io2->openx.in.fname = io->t2open.in.fname; status = ntvfs->ops->openfile(ntvfs, req, io2); break; @@ -508,7 +471,6 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, status = NT_STATUS_INVALID_LEVEL; break; } - done: return ntvfs_map_async_finish(req, status); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a53deda270..af0858f639 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -794,38 +794,6 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } -/* - special handling for t2open -*/ -static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) -{ - struct pvfs_state *pvfs = ntvfs->private_data; - struct pvfs_filename *name; - NTSTATUS status; - - status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, 0, &name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (io->t2open.in.open_func & OPENX_OPEN_FUNC_CREATE) { - if (!name->stream_exists) return NT_STATUS_ACCESS_DENIED; - } - if (io->t2open.in.open_func & OPENX_OPEN_FUNC_TRUNC) { - if (name->stream_exists) return NT_STATUS_ACCESS_DENIED; - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - if ((io->t2open.in.open_func & 0xF) == OPENX_OPEN_FUNC_FAIL) { - if (!name->stream_exists) return NT_STATUS_ACCESS_DENIED; - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - talloc_free(name); - - return ntvfs_map_open(req, io, ntvfs); -} - /* open a file */ @@ -844,10 +812,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t access_mask; BOOL stream_existed; - if (io->generic.level == RAW_OPEN_T2OPEN) { - return pvfs_open_t2open(ntvfs, req, io); - } - /* use the generic mapping code to avoid implementing all the different open calls. */ if (io->generic.level != RAW_OPEN_GENERIC && -- cgit From 275df9a5c3b1ade9f2467870c3628a2a896c004c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 2004 23:57:59 +0000 Subject: r4182: fixed trans2 mkdir, allowing mkdir with an initial EA list (This used to be commit 7d981c29c28391813c7f93245f64b3ee108378a4) --- source4/ntvfs/posix/pvfs_mkdir.c | 52 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 1bc0fa569e..b43e67faed 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -23,6 +23,54 @@ #include "includes.h" #include "vfs_posix.h" +/* + create a directory with EAs +*/ +static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, + struct smbsrv_request *req, union smb_mkdir *md) +{ + NTSTATUS status; + struct pvfs_filename *name; + mode_t mode; + int i; + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, md->t2mkdir.in.path, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (name->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY); + + if (mkdir(name->full_name, mode) == -1) { + return pvfs_map_errno(pvfs, errno); + } + + status = pvfs_resolve_name(pvfs, req, md->t2mkdir.in.path, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (!name->exists || + !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + return NT_STATUS_INTERNAL_ERROR; + } + + /* setup any EAs that were asked for */ + for (i=0;it2mkdir.in.num_eas;i++) { + status = pvfs_setfileinfo_ea_set(pvfs, name, -1, &md->t2mkdir.in.eas[i]); + if (!NT_STATUS_IS_OK(status)) { + rmdir(name->full_name); + return status; + } + } + + return NT_STATUS_OK; +} + /* create a directory */ @@ -34,6 +82,10 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; mode_t mode; + if (md->generic.level == RAW_MKDIR_T2MKDIR) { + return pvfs_t2mkdir(pvfs, req, md); + } + if (md->generic.level != RAW_MKDIR_MKDIR) { return NT_STATUS_INVALID_LEVEL; } -- cgit From d21a55dda787a65f15eccb6442189ad7d97526f0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Dec 2004 22:17:41 +0000 Subject: r4205: fixed the default acl mapping from posix permissions to use the mapped uid->sid and gid->sid (This used to be commit 590e1a91bfc719c2d84a9a066fb4e0308b6d9803) --- source4/ntvfs/posix/pvfs_acl.c | 66 +++++++++++++++++++++--------------------- 1 file changed, 33 insertions(+), 33 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index e2d779f91c..95a4e5765c 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -68,17 +68,11 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, struct xattr_NTACL *acl) { struct security_descriptor *sd; - int i; - struct security_ace ace; NTSTATUS status; - const char *sid_names[] = { - SID_BUILTIN_ADMINISTRATORS, - SID_CREATOR_OWNER, - SID_CREATOR_GROUP, - SID_WORLD - }; - uint32_t access_masks[4]; + struct security_ace aces[4]; mode_t mode; + struct dom_sid *sid; + int i; sd = security_descriptor_initialise(req); if (sd == NULL) { @@ -103,15 +97,15 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, - Group - Everyone */ - access_masks[0] = SEC_RIGHTS_FILE_ALL; - access_masks[1] = 0; - access_masks[2] = 0; - access_masks[3] = 0; + aces[0].access_mask = SEC_RIGHTS_FILE_ALL; + aces[1].access_mask = 0; + aces[2].access_mask = 0; + aces[3].access_mask = 0; mode = name->st.st_mode; if (mode & S_IRUSR) { - access_masks[1] |= + aces[1].access_mask |= SEC_FILE_READ_DATA | SEC_FILE_READ_EA | SEC_FILE_READ_ATTRIBUTE | @@ -120,7 +114,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, SEC_STD_READ_CONTROL; } if (mode & S_IWUSR) { - access_masks[1] |= + aces[1].access_mask |= SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | SEC_FILE_WRITE_EA | @@ -129,7 +123,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, } if (mode & S_IRGRP) { - access_masks[2] |= + aces[2].access_mask |= SEC_FILE_READ_DATA | SEC_FILE_READ_EA | SEC_FILE_READ_ATTRIBUTE | @@ -138,7 +132,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, SEC_STD_READ_CONTROL; } if (mode & S_IWGRP) { - access_masks[2] |= + aces[2].access_mask |= SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | SEC_FILE_WRITE_EA | @@ -146,7 +140,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, } if (mode & S_IROTH) { - access_masks[3] |= + aces[3].access_mask |= SEC_FILE_READ_DATA | SEC_FILE_READ_EA | SEC_FILE_READ_ATTRIBUTE | @@ -155,31 +149,37 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, SEC_STD_READ_CONTROL; } if (mode & S_IWOTH) { - access_masks[3] |= + aces[3].access_mask |= SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE; } - ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED; - ace.flags = 0; + sid = dom_sid_parse_talloc(sd, SID_BUILTIN_ADMINISTRATORS); + if (sid == NULL) return NT_STATUS_NO_MEMORY; + + aces[0].type = SEC_ACE_TYPE_ACCESS_ALLOWED; + aces[0].flags = 0; + aces[0].trustee = *sid; + + aces[1].type = SEC_ACE_TYPE_ACCESS_ALLOWED; + aces[1].flags = 0; + aces[1].trustee = *sd->owner_sid; - for (i=0;igroup_sid; - ace.access_mask = access_masks[i]; + sid = dom_sid_parse_talloc(sd, SID_WORLD); + if (sid == NULL) return NT_STATUS_NO_MEMORY; - sid = dom_sid_parse_talloc(sd, sid_names[i]); - if (sid == NULL) { - return NT_STATUS_NO_MEMORY; - } - ace.trustee = *sid; + aces[3].type = SEC_ACE_TYPE_ACCESS_ALLOWED; + aces[3].flags = 0; + aces[3].trustee = *sid; - status = security_descriptor_dacl_add(sd, &ace); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + for (i=0;i<4;i++) { + security_descriptor_dacl_add(sd, &aces[i]); } acl->version = 1; -- cgit From 145702b75604be85f71d9e0e5b8fe048da439958 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 16 Dec 2004 12:29:47 +0000 Subject: r4230: now that we set the FLAGS2_EXTENDED_ATTRIBUTES flag, we should mark empty EAs as being of size 4, not size 0 (This used to be commit 76bd6476785e4145437768caa702c01a7801590e) --- source4/ntvfs/posix/pvfs_fileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index fa45444159..aafecf0950 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -95,7 +95,7 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.attrib = dos_mode_from_stat(pvfs, &name->st); name->dos.alloc_size = pvfs_round_alloc_size(pvfs, name->st.st_size); name->dos.nlink = name->st.st_nlink; - name->dos.ea_size = 0; + name->dos.ea_size = 4; name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; name->dos.flags = 0; -- cgit From 50005129ab0a5c5f2422460e6d7c19616e5e1124 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Dec 2004 03:39:29 +0000 Subject: r4242: added support for storing xattrs in a tdb. This allows all advanced NT attributes (streams, EAs, NT ACLs, timestamps etc) to be used on filesystems that don't support xattrs. It also allows for large streams, although they are very inefficient. I won't enable this by default, as I really wrote it as a way of testing large stream support while still using ext3, but perhaps with a bit more work this could be generally usable. To enable this use: posix:eadb = /home/test/myeas.tdb (This used to be commit 0c927d912cb65754351189d3a0442004a14aa5c6) --- source4/ntvfs/posix/config.mk | 4 +- source4/ntvfs/posix/pvfs_open.c | 6 + source4/ntvfs/posix/pvfs_unlink.c | 5 + source4/ntvfs/posix/pvfs_xattr.c | 93 +++++---------- source4/ntvfs/posix/vfs_posix.c | 16 +++ source4/ntvfs/posix/vfs_posix.h | 3 + source4/ntvfs/posix/xattr_system.c | 134 +++++++++++++++++++++ source4/ntvfs/posix/xattr_tdb.c | 232 +++++++++++++++++++++++++++++++++++++ 8 files changed, 425 insertions(+), 68 deletions(-) create mode 100644 source4/ntvfs/posix/xattr_system.c create mode 100644 source4/ntvfs/posix/xattr_tdb.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 44a1625c5f..f2f7207773 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -28,7 +28,9 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_ioctl.o \ ntvfs/posix/pvfs_xattr.o \ ntvfs/posix/pvfs_streams.o \ - ntvfs/posix/pvfs_acl.o + ntvfs/posix/pvfs_acl.o \ + ntvfs/posix/xattr_system.o \ + ntvfs/posix/xattr_tdb.o REQUIRED_SUBSYSTEMS = NDR_XATTR ntvfs_common # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index af0858f639..e31d79b9e0 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -267,6 +267,12 @@ static int pvfs_handle_destructor(void *p) if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && h->name->stream_name == NULL) { + NTSTATUS status; + status = pvfs_xattr_unlink_hook(h->pvfs, h->name->full_name); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + } if (unlink(h->name->full_name) != 0) { DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", h->name->full_name, strerror(errno))); diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 434577a862..f29a70600f 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -86,6 +86,11 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_FILE_IS_A_DIRECTORY; } + status = pvfs_xattr_unlink_hook(pvfs, name->full_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* finally try the actual unlink */ if (unlink(name->full_name) == -1) { status = pvfs_map_errno(pvfs, errno); diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 47549499e6..4487663e8d 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -21,12 +21,11 @@ */ #include "includes.h" -#include "system/filesys.h" #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" /* - pull a xattr as a blob, from either a file or a file descriptor + pull a xattr as a blob */ static NTSTATUS pull_xattr_blob(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, @@ -36,45 +35,16 @@ static NTSTATUS pull_xattr_blob(struct pvfs_state *pvfs, size_t estimated_size, DATA_BLOB *blob) { -#if HAVE_XATTR_SUPPORT - int ret; - - *blob = data_blob_talloc(mem_ctx, NULL, estimated_size); - if (blob->data == NULL) { - return NT_STATUS_NO_MEMORY; - } - -again: - if (fd != -1) { - ret = fgetxattr(fd, attr_name, blob->data, estimated_size); - } else { - ret = getxattr(fname, attr_name, blob->data, estimated_size); - } - if (ret == -1 && errno == ERANGE) { - estimated_size *= 2; - blob->data = talloc_realloc(mem_ctx, blob->data, estimated_size); - if (blob->data == NULL) { - return NT_STATUS_NO_MEMORY; - } - blob->length = estimated_size; - goto again; + if (pvfs->ea_db) { + return pull_xattr_blob_tdb(pvfs, mem_ctx, attr_name, fname, + fd, estimated_size, blob); } - - if (ret == -1) { - data_blob_free(blob); - return pvfs_map_errno(pvfs, errno); - } - - blob->length = ret; - - return NT_STATUS_OK; -#else - return NT_STATUS_NOT_SUPPORTED; -#endif + return pull_xattr_blob_system(pvfs, mem_ctx, attr_name, fname, + fd, estimated_size, blob); } /* - push a xattr as a blob, from either a file or a file descriptor + push a xattr as a blob */ static NTSTATUS push_xattr_blob(struct pvfs_state *pvfs, const char *attr_name, @@ -82,22 +52,10 @@ static NTSTATUS push_xattr_blob(struct pvfs_state *pvfs, int fd, const DATA_BLOB *blob) { -#if HAVE_XATTR_SUPPORT - int ret; - - if (fd != -1) { - ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0); - } else { - ret = setxattr(fname, attr_name, blob->data, blob->length, 0); + if (pvfs->ea_db) { + return push_xattr_blob_tdb(pvfs, attr_name, fname, fd, blob); } - if (ret == -1) { - return pvfs_map_errno(pvfs, errno); - } - - return NT_STATUS_OK; -#else - return NT_STATUS_NOT_SUPPORTED; -#endif + return push_xattr_blob_system(pvfs, attr_name, fname, fd, blob); } @@ -107,24 +65,24 @@ static NTSTATUS push_xattr_blob(struct pvfs_state *pvfs, static NTSTATUS delete_xattr(struct pvfs_state *pvfs, const char *attr_name, const char *fname, int fd) { -#if HAVE_XATTR_SUPPORT - int ret; - - if (fd != -1) { - ret = fremovexattr(fd, attr_name); - } else { - ret = removexattr(fname, attr_name); - } - if (ret == -1) { - return pvfs_map_errno(pvfs, errno); + if (pvfs->ea_db) { + return delete_xattr_tdb(pvfs, attr_name, fname, fd); } + return delete_xattr_system(pvfs, attr_name, fname, fd); +} - return NT_STATUS_OK; -#else - return NT_STATUS_NOT_SUPPORTED; -#endif +/* + a hook called on unlink - allows the tdb xattr backend to cleanup +*/ +NTSTATUS pvfs_xattr_unlink_hook(struct pvfs_state *pvfs, const char *fname) +{ + if (pvfs->ea_db) { + return unlink_xattr_tdb(pvfs, fname); + } + return unlink_xattr_system(pvfs, fname); } + /* load a NDR structure from a xattr */ @@ -211,7 +169,7 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name /* not having a DosAttrib is not an error */ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { talloc_free(mem_ctx); - return NT_STATUS_OK; + return pvfs_stream_info(pvfs, name, fd); } if (!NT_STATUS_IS_OK(status)) { @@ -493,3 +451,4 @@ NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, talloc_free(aname); return status; } + diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ff3d3448f2..6f4de1e038 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -35,6 +35,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) { int snum = pvfs->tcon->service; int delay; + const char *eadb; if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; @@ -66,6 +67,21 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) FS_ATTR_UNICODE_ON_DISK | FS_ATTR_SPARSE_FILES; + /* allow xattrs to be stored in a external tdb */ + eadb = lp_parm_string(snum, "posix", "eadb"); + if (eadb != NULL) { + pvfs->ea_db = tdb_wrap_open(pvfs, eadb, 50000, + TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + if (pvfs->ea_db != NULL) { + pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; + } else { + DEBUG(0,("Failed to open eadb '%s' - %s\n", + eadb, strerror(errno))); + pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; + } + } + + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_NAMED_STREAMS; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 16c6f807e9..e80790f6fa 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -57,6 +57,9 @@ struct pvfs_state { /* filesystem attributes (see FS_ATTR_*) */ uint32_t fs_attribs; + + /* if posix:eadb is set, then this gets setup */ + struct tdb_wrap *ea_db; }; /* this is the basic information needed about a file from the filesystem */ diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c new file mode 100644 index 0000000000..c86ee0bd87 --- /dev/null +++ b/source4/ntvfs/posix/xattr_system.c @@ -0,0 +1,134 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - xattr support using filesystem xattrs + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "vfs_posix.h" + +/* + pull a xattr as a blob, from either a file or a file descriptor +*/ +NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs, + TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *fname, + int fd, + size_t estimated_size, + DATA_BLOB *blob) +{ +#if HAVE_XATTR_SUPPORT + int ret; + + *blob = data_blob_talloc(mem_ctx, NULL, estimated_size); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + +again: + if (fd != -1) { + ret = fgetxattr(fd, attr_name, blob->data, estimated_size); + } else { + ret = getxattr(fname, attr_name, blob->data, estimated_size); + } + if (ret == -1 && errno == ERANGE) { + estimated_size *= 2; + blob->data = talloc_realloc(mem_ctx, blob->data, estimated_size); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + blob->length = estimated_size; + goto again; + } + + if (ret == -1) { + data_blob_free(blob); + return pvfs_map_errno(pvfs, errno); + } + + blob->length = ret; + + return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif +} + +/* + push a xattr as a blob, from either a file or a file descriptor +*/ +NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs, + const char *attr_name, + const char *fname, + int fd, + const DATA_BLOB *blob) +{ +#if HAVE_XATTR_SUPPORT + int ret; + + if (fd != -1) { + ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0); + } else { + ret = setxattr(fname, attr_name, blob->data, blob->length, 0); + } + if (ret == -1) { + return pvfs_map_errno(pvfs, errno); + } + + return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif +} + + +/* + delete a xattr +*/ +NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name, + const char *fname, int fd) +{ +#if HAVE_XATTR_SUPPORT + int ret; + + if (fd != -1) { + ret = fremovexattr(fd, attr_name); + } else { + ret = removexattr(fname, attr_name); + } + if (ret == -1) { + return pvfs_map_errno(pvfs, errno); + } + + return NT_STATUS_OK; +#else + return NT_STATUS_NOT_SUPPORTED; +#endif +} + +/* + unlink a file - cleanup any xattrs +*/ +NTSTATUS unlink_xattr_system(struct pvfs_state *pvfs, const char *fname) +{ + /* nothing needs to be done for filesystem based xattrs */ + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c new file mode 100644 index 0000000000..08a2ea4c18 --- /dev/null +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -0,0 +1,232 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - xattr support using a tdb + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "vfs_posix.h" + +#define XATTR_LIST_ATTR ".xattr_list" + +/* + we need to maintain a list of attributes on each file, so that unlink + can automatically clean them up +*/ +static NTSTATUS xattr_tdb_add_list(struct pvfs_state *pvfs, const char *attr_name, + const char *fname, int fd) +{ + DATA_BLOB blob; + TALLOC_CTX *mem_ctx; + const char *s; + NTSTATUS status; + size_t len; + + if (strcmp(attr_name, XATTR_LIST_ATTR) == 0) { + return NT_STATUS_OK; + } + + mem_ctx = talloc(pvfs, 0); + + status = pull_xattr_blob_tdb(pvfs, mem_ctx, XATTR_LIST_ATTR, + fname, fd, 100, &blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + + for (s=blob.data; s < (char *)(blob.data+blob.length); s += strlen(s) + 1) { + if (strcmp(attr_name, s) == 0) { + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + } + + len = strlen(attr_name) + 1; + + blob.data = talloc_realloc_p(mem_ctx, blob.data, uint8_t, blob.length + len); + if (blob.data == NULL) { + talloc_free(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + memcpy(blob.data + blob.length, attr_name, len); + blob.length += len; + + status = push_xattr_blob_tdb(pvfs, XATTR_LIST_ATTR, fname, fd, &blob); + talloc_free(mem_ctx); + + return status; +} + +/* + form a key for using in the ea_db +*/ +static NTSTATUS get_ea_db_key(TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *fname, int fd, + TDB_DATA *key) +{ + struct stat st; + size_t len = strlen(attr_name); + + if (fd == -1) { + if (stat(fname, &st) == -1) { + return NT_STATUS_NOT_FOUND; + } + } else { + if (fstat(fd, &st) == -1) { + return NT_STATUS_NOT_FOUND; + } + } + + key->dptr = talloc_array_p(mem_ctx, char, 16 + len); + if (key->dptr == NULL) { + return NT_STATUS_NO_MEMORY; + } + key->dsize = 16 + len; + + SBVAL(key->dptr, 0, st.st_dev); + SBVAL(key->dptr, 8, st.st_ino); + memcpy(key->dptr+16, attr_name, len); + + return NT_STATUS_OK; +} + +/* + pull a xattr as a blob, using the ea_db tdb +*/ +NTSTATUS pull_xattr_blob_tdb(struct pvfs_state *pvfs, + TALLOC_CTX *mem_ctx, + const char *attr_name, + const char *fname, + int fd, + size_t estimated_size, + DATA_BLOB *blob) +{ + TDB_DATA tkey, tdata; + NTSTATUS status; + + status = get_ea_db_key(mem_ctx, attr_name, fname, fd, &tkey); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + tdata = tdb_fetch(pvfs->ea_db->tdb, tkey); + if (tdata.dptr == NULL) { + return NT_STATUS_NOT_FOUND; + } + + *blob = data_blob_talloc(mem_ctx, tdata.dptr, tdata.dsize); + free(tdata.dptr); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + +/* + push a xattr as a blob, using ea_db +*/ +NTSTATUS push_xattr_blob_tdb(struct pvfs_state *pvfs, + const char *attr_name, + const char *fname, + int fd, + const DATA_BLOB *blob) +{ + TDB_DATA tkey, tdata; + NTSTATUS status; + + status = get_ea_db_key(pvfs, attr_name, fname, fd, &tkey); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + tdata.dptr = blob->data; + tdata.dsize = blob->length; + + if (tdb_chainlock(pvfs->ea_db->tdb, tkey) != 0) { + talloc_free(tkey.dptr); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = xattr_tdb_add_list(pvfs, attr_name, fname, fd); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + if (tdb_store(pvfs->ea_db->tdb, tkey, tdata, TDB_REPLACE) == -1) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + +done: + tdb_chainunlock(pvfs->ea_db->tdb, tkey); + talloc_free(tkey.dptr); + return status; +} + + +/* + delete a xattr +*/ +NTSTATUS delete_xattr_tdb(struct pvfs_state *pvfs, const char *attr_name, + const char *fname, int fd) +{ + TDB_DATA tkey; + NTSTATUS status; + + status = get_ea_db_key(NULL, attr_name, fname, fd, &tkey); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (tdb_delete(pvfs->ea_db->tdb, tkey) == -1) { + talloc_free(tkey.dptr); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + talloc_free(tkey.dptr); + return NT_STATUS_OK; +} + + + +/* + delete all xattrs for a file +*/ +NTSTATUS unlink_xattr_tdb(struct pvfs_state *pvfs, const char *fname) +{ + TALLOC_CTX *mem_ctx = talloc(pvfs, 0); + DATA_BLOB blob; + const char *s; + NTSTATUS status; + + status = pull_xattr_blob_tdb(pvfs, mem_ctx, XATTR_LIST_ATTR, + fname, -1, 100, &blob); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return NT_STATUS_OK; + } + + for (s=blob.data; s < (char *)(blob.data+blob.length); s += strlen(s) + 1) { + delete_xattr_tdb(pvfs, s, fname, -1); + } + + return delete_xattr_tdb(pvfs, XATTR_LIST_ATTR, fname, -1); +} -- cgit From 3b8e83a8c8f32ca658841f1fae344399a48d66a4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Dec 2004 04:51:23 +0000 Subject: r4243: a sniff from kukks showed that the ea_set interface in trans2 setfileinfo allows for multiple EAs to be set at once. This fixes all the ea code to allow for that. (This used to be commit b26828bef5d55e5eef0e34a164e76292df45e207) --- source4/ntvfs/posix/pvfs_mkdir.c | 18 +++++++----- source4/ntvfs/posix/pvfs_open.c | 21 +++++++------ source4/ntvfs/posix/pvfs_setfileinfo.c | 54 ++++++++++++++++++++++------------ 3 files changed, 58 insertions(+), 35 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index b43e67faed..549f4b9780 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -32,7 +32,6 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, NTSTATUS status; struct pvfs_filename *name; mode_t mode; - int i; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, md->t2mkdir.in.path, 0, &name); @@ -60,12 +59,12 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, } /* setup any EAs that were asked for */ - for (i=0;it2mkdir.in.num_eas;i++) { - status = pvfs_setfileinfo_ea_set(pvfs, name, -1, &md->t2mkdir.in.eas[i]); - if (!NT_STATUS_IS_OK(status)) { - rmdir(name->full_name); - return status; - } + status = pvfs_setfileinfo_ea_set(pvfs, name, -1, + md->t2mkdir.in.num_eas, + md->t2mkdir.in.eas); + if (!NT_STATUS_IS_OK(status)) { + rmdir(name->full_name); + return status; } return NT_STATUS_OK; @@ -129,6 +128,11 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + status = pvfs_xattr_unlink_hook(pvfs, name->full_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (rmdir(name->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index e31d79b9e0..bd96b935ad 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -70,6 +70,11 @@ static int pvfs_dir_handle_destructor(void *p) struct pvfs_file_handle *h = p; if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + NTSTATUS status = pvfs_xattr_unlink_hook(h->pvfs, h->name->full_name); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Warning: xattr rmdir hook failed for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + } if (rmdir(h->name->full_name) != 0) { DEBUG(0,("pvfs_close: failed to rmdir '%s' - %s\n", h->name->full_name, strerror(errno))); @@ -459,15 +464,13 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* setup any EAs that were asked for */ if (io->ntcreatex.in.ea_list) { - int i; - for (i=0;intcreatex.in.ea_list->num_eas;i++) { - status = pvfs_setfileinfo_ea_set(pvfs, name, fd, - &io->ntcreatex.in.ea_list->eas[i]); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return status; - } + status = pvfs_setfileinfo_ea_set(pvfs, name, fd, + io->ntcreatex.in.ea_list->num_eas, + io->ntcreatex.in.ea_list->eas); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + return status; } } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index c43ef5c40a..2a06def2b4 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -115,40 +115,53 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, */ NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, struct pvfs_filename *name, - int fd, struct ea_struct *ea) + int fd, uint16_t num_eas, + struct ea_struct *eas) { - struct xattr_DosEAs *ealist = talloc_p(pvfs, struct xattr_DosEAs); - int i; + struct xattr_DosEAs *ealist; + int i, j; NTSTATUS status; + if (num_eas == 0) { + return NT_STATUS_OK; + } + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_NOT_SUPPORTED; } + ealist = talloc_p(name, struct xattr_DosEAs); + /* load the current list */ status = pvfs_doseas_load(pvfs, name, fd, ealist); if (!NT_STATUS_IS_OK(status)) { return status; } - /* see if its already there */ - for (i=0;inum_eas;i++) { - if (StrCaseCmp(ealist->eas[i].name, ea->name.s) == 0) { - ealist->eas[i].value = ea->value; - goto save; + for (j=0;jnum_eas;i++) { + if (StrCaseCmp(ealist->eas[i].name, ea->name.s) == 0) { + ealist->eas[i].value = ea->value; + break; + } } - } - /* add it */ - ealist->eas = talloc_realloc_p(ealist, ealist->eas, struct xattr_EA, ealist->num_eas+1); - if (ealist->eas == NULL) { - return NT_STATUS_NO_MEMORY; + if (i==ealist->num_eas) { + /* add it */ + ealist->eas = talloc_realloc_p(ealist, ealist->eas, + struct xattr_EA, + ealist->num_eas+1); + if (ealist->eas == NULL) { + return NT_STATUS_NO_MEMORY; + } + ealist->eas[i].name = ea->name.s; + ealist->eas[i].value = ea->value; + ealist->num_eas++; + } } - ealist->eas[i].name = ea->name.s; - ealist->eas[i].value = ea->value; - ealist->num_eas++; -save: /* pull out any null EAs */ for (i=0;inum_eas;i++) { if (ealist->eas[i].value.length == 0) { @@ -233,7 +246,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_EA_SET: return pvfs_setfileinfo_ea_set(pvfs, h->name, h->fd, - &info->ea_set.in.ea); + info->ea_set.in.num_eas, + info->ea_set.in.eas); case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: @@ -419,7 +433,9 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, break; case RAW_SFILEINFO_EA_SET: - return pvfs_setfileinfo_ea_set(pvfs, name, -1, &info->ea_set.in.ea); + return pvfs_setfileinfo_ea_set(pvfs, name, -1, + info->ea_set.in.num_eas, + info->ea_set.in.eas); case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: -- cgit From d5d0651bb98be2d060a61048c50cbc20e7901416 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Dec 2004 05:03:57 +0000 Subject: r4244: add more calls to pvfs_xattr_unlink_hook() on file/dir create, to try to beat race conditions in the tdb xattr backend (This used to be commit 3ac840159881ce6eeac27ff0dc324e4d6ac0a70a) --- source4/ntvfs/posix/pvfs_mkdir.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 549f4b9780..c4c03f3ad4 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -49,6 +49,8 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return pvfs_map_errno(pvfs, errno); } + pvfs_xattr_unlink_hook(pvfs, name->full_name); + status = pvfs_resolve_name(pvfs, req, md->t2mkdir.in.path, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; @@ -105,6 +107,8 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } + pvfs_xattr_unlink_hook(pvfs, name->full_name); + return NT_STATUS_OK; } -- cgit From daae3bbb290ce0f4467c806acaefe3b1d6f4ae4d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Dec 2004 06:35:11 +0000 Subject: r4247: two more places that need the unlink hook (This used to be commit 795897b64f3c63baaf53a36eb1611293c2fd8974) --- source4/ntvfs/posix/pvfs_open.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index bd96b935ad..7cb8a5d90c 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -202,6 +202,9 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, if (mkdir(name->full_name, mode) == -1) { return pvfs_map_errno(pvfs,errno); } + + pvfs_xattr_unlink_hook(pvfs, name->full_name); + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; @@ -436,6 +439,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return pvfs_map_errno(pvfs, errno); } + pvfs_xattr_unlink_hook(pvfs, name->full_name); + /* if this was a stream create then create the stream as well */ if (name->stream_name) { status = pvfs_stream_create(pvfs, name, fd); -- cgit From b706555b3a4ed3c8d459ae86b4c332fa41041f57 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 17 Dec 2004 22:47:49 +0000 Subject: r4261: added the RAW_FILEINFO_EA_LIST trans2 qfileinfo and qpathinfo level. Interestingly, this level did now show up on our trans2 scanner previously as we didn't have the FLAGS2_EXTENDED_ATTRIBUTES bit set in the client code. Now that we set that bit, new levels appear in windows servers. (This used to be commit 0b76d405a73e924dc2706f28bbf1084a59c9b393) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 58 ++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index fe53b0a415..ae55ad5e98 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -24,6 +24,45 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" +/* + reply to a RAW_FILEINFO_EA_LIST call +*/ +static NTSTATUS pvfs_query_ea_list(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + struct pvfs_filename *name, int fd, + uint_t num_names, + struct ea_name *names, + struct smb_ea_list *eas) +{ + NTSTATUS status; + int i; + struct xattr_DosEAs *ealist = talloc_p(mem_ctx, struct xattr_DosEAs); + + ZERO_STRUCTP(eas); + status = pvfs_doseas_load(pvfs, name, fd, ealist); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + eas->eas = talloc_array_p(mem_ctx, struct ea_struct, num_names); + if (eas->eas == NULL) { + return NT_STATUS_NO_MEMORY; + } + eas->num_eas = num_names; + for (i=0;ieas[i].flags = 0; + eas->eas[i].name.s = names[i].name.s; + eas->eas[i].value = data_blob(NULL, 0); + for (j=0;jnum_eas;j++) { + if (StrCaseCmp(eas->eas[i].name.s, + ealist->eas[j].name) == 0) { + eas->eas[i].value = ealist->eas[j].value; + break; + } + } + } + return NT_STATUS_OK; +} + /* reply to a RAW_FILEINFO_ALL_EAS call */ @@ -40,15 +79,16 @@ static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { return status; } - eas->num_eas = ealist->num_eas; - eas->eas = talloc_array_p(mem_ctx, struct ea_struct, eas->num_eas); + eas->eas = talloc_array_p(mem_ctx, struct ea_struct, ealist->num_eas); if (eas->eas == NULL) { return NT_STATUS_NO_MEMORY; } - for (i=0;inum_eas;i++) { - eas->eas[i].flags = 0; - eas->eas[i].name.s = ealist->eas[i].name; - eas->eas[i].value = ealist->eas[i].value; + eas->num_eas = 0; + for (i=0;inum_eas;i++) { + eas->eas[eas->num_eas].flags = 0; + eas->eas[eas->num_eas].name.s = ealist->eas[i].name; + eas->eas[eas->num_eas].value = ealist->eas[i].value; + eas->num_eas++; } return NT_STATUS_OK; } @@ -91,6 +131,12 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, info->ea_size.out.ea_size = name->dos.ea_size; return NT_STATUS_OK; + case RAW_FILEINFO_EA_LIST: + return pvfs_query_ea_list(pvfs, req, name, fd, + info->ea_list.in.num_names, + info->ea_list.in.ea_names, + &info->ea_list.out); + case RAW_FILEINFO_ALL_EAS: return pvfs_query_all_eas(pvfs, req, name, fd, &info->all_eas.out); -- cgit From b02c5abfb470575a67ced192b2913b5a1c73dd3e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Dec 2004 01:16:04 +0000 Subject: r4262: a sniff from kukks showed that the FILE_ATTRIBUTE_NORMAL handling in pvfs was not correct. This should fix a xcopy bug on OS/2. (This used to be commit 7251f1fcdd8980e9c49a58e665374025e07bb8d0) --- source4/ntvfs/posix/pvfs_fileinfo.c | 9 --------- source4/ntvfs/posix/pvfs_util.c | 3 --- 2 files changed, 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index aafecf0950..888d5f78c0 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -57,15 +57,6 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) if (S_ISDIR(st->st_mode)) result = FILE_ATTRIBUTE_DIRECTORY | (result & FILE_ATTRIBUTE_READONLY); - if (!(result & - (FILE_ATTRIBUTE_READONLY| - FILE_ATTRIBUTE_ARCHIVE| - FILE_ATTRIBUTE_SYSTEM| - FILE_ATTRIBUTE_HIDDEN| - FILE_ATTRIBUTE_DIRECTORY))) { - result |= FILE_ATTRIBUTE_NORMAL; - } - return result; } diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 67dd9d22b3..6026b9fbf3 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -70,9 +70,6 @@ NTSTATUS pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, */ uint32_t pvfs_attrib_normalise(uint32_t attrib) { - if (attrib == 0) { - attrib = FILE_ATTRIBUTE_NORMAL; - } if (attrib != FILE_ATTRIBUTE_NORMAL) { attrib &= ~FILE_ATTRIBUTE_NORMAL; } -- cgit From ed42a64901ba0a7ad8cbaac582600688af1b7d72 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Dec 2004 04:38:43 +0000 Subject: r4263: added support for the trans2 RAW_SEARCH_EA_LIST information level. This is quite a strange level that we've never seen before, but is used by the os2 workplace shell. note w2k screws up this level when unicode is negotiated, so it only passes the RAW-SEARCH test when you force non-unicode (This used to be commit 25189b8fbf6515d573e3398dc9fca56505dc37b9) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 10 +++++----- source4/ntvfs/posix/pvfs_search.c | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index ae55ad5e98..75a9909492 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -27,11 +27,11 @@ /* reply to a RAW_FILEINFO_EA_LIST call */ -static NTSTATUS pvfs_query_ea_list(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, - struct pvfs_filename *name, int fd, - uint_t num_names, - struct ea_name *names, - struct smb_ea_list *eas) +NTSTATUS pvfs_query_ea_list(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + struct pvfs_filename *name, int fd, + uint_t num_names, + struct ea_name *names, + struct smb_ea_list *eas) { NTSTATUS status; int i; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index c336035218..34f5f2208e 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -35,6 +35,8 @@ struct pvfs_search_state { uint16_t must_attrib; struct pvfs_dir *dir; time_t last_used; + uint_t num_ea_names; + struct ea_name *ea_names; }; @@ -118,6 +120,20 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->ea_size.name.s = fname; return NT_STATUS_OK; + case RAW_SEARCH_EA_LIST: + file->ea_list.resume_key = dir_index; + file->ea_list.create_time = nt_time_to_unix(name->dos.create_time); + file->ea_list.access_time = nt_time_to_unix(name->dos.access_time); + file->ea_list.write_time = nt_time_to_unix(name->dos.write_time); + file->ea_list.size = name->st.st_size; + file->ea_list.alloc_size = name->dos.alloc_size; + file->ea_list.attrib = name->dos.attrib; + file->ea_list.name.s = fname; + return pvfs_query_ea_list(pvfs, file, name, -1, + search->num_ea_names, + search->ea_names, + &file->ea_list.eas); + case RAW_SEARCH_DIRECTORY_INFO: file->directory_info.file_index = dir_index; file->directory_info.create_time = name->dos.create_time; @@ -471,6 +487,8 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, search->search_attrib = search_attrib; search->must_attrib = 0; search->last_used = 0; + search->num_ea_names = io->t2ffirst.in.num_names; + search->ea_names = io->t2ffirst.in.ea_names; talloc_set_destructor(search, pvfs_search_destructor); @@ -550,6 +568,9 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, return status; } + search->num_ea_names = io->t2fnext.in.num_names; + search->ea_names = io->t2fnext.in.ea_names; + status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { -- cgit From 114bcfe837699083be2a5145b9f44092a649cae4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Dec 2004 23:31:17 +0000 Subject: r4264: fix acl handling on systems without xattr support (This used to be commit 89845388ea82d9bfbdc6ca8da40f47437a270400) --- source4/ntvfs/posix/pvfs_xattr.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 4487663e8d..baa6c15e31 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -35,12 +35,24 @@ static NTSTATUS pull_xattr_blob(struct pvfs_state *pvfs, size_t estimated_size, DATA_BLOB *blob) { + NTSTATUS status; + if (pvfs->ea_db) { return pull_xattr_blob_tdb(pvfs, mem_ctx, attr_name, fname, fd, estimated_size, blob); } - return pull_xattr_blob_system(pvfs, mem_ctx, attr_name, fname, - fd, estimated_size, blob); + + status = pull_xattr_blob_system(pvfs, mem_ctx, attr_name, fname, + fd, estimated_size, blob); + + /* if the filesystem doesn't support them, then tell pvfs not to try again */ + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + DEBUG(5,("pvfs_xattr: xattr not supported in filesystem\n")); + pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; + status = NT_STATUS_NOT_FOUND; + } + + return status; } /* @@ -158,14 +170,6 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name &attrib, (ndr_pull_flags_fn_t)ndr_pull_xattr_DosAttrib); - /* if the filesystem doesn't support them, then tell pvfs not to try again */ - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { - DEBUG(5,("pvfs_xattr: xattr not supported in filesystem\n")); - pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; - talloc_free(mem_ctx); - return NT_STATUS_OK; - } - /* not having a DosAttrib is not an error */ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { talloc_free(mem_ctx); @@ -341,7 +345,7 @@ NTSTATUS pvfs_acl_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int NTSTATUS status; ZERO_STRUCTP(acl); if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { - return NT_STATUS_OK; + return NT_STATUS_NOT_FOUND; } status = pvfs_xattr_ndr_load(pvfs, acl, name->full_name, fd, XATTR_NTACL_NAME, -- cgit From 8fe7d2974ca1c5e73177560a5138f73ae42bb66a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 19 Dec 2004 03:31:57 +0000 Subject: r4274: make the prototype RAP netshareenum call return something a bit more sensible. (This used to be commit b2e29756c2084f11d841d027e7d32952daae18d0) --- source4/ntvfs/ipc/rap_server.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 70b65442ff..0e6c18ca3b 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -28,20 +28,21 @@ NTSTATUS rap_netshareenum(struct smbsrv_request *req, struct rap_NetShareEnum *r) { + int i; r->out.status = 0; - r->out.available = 2; + r->out.available = dcesrv_common_get_count_of_shares(req, NULL); r->out.info = talloc_array_p(req, - union rap_shareenum_info, 2); + union rap_shareenum_info, r->out.available); - strncpy(r->out.info[0].info1.name, "C$", sizeof(r->out.info[0].info1.name)); - r->out.info[0].info1.pad = 0; - r->out.info[0].info1.type = 0; - r->out.info[0].info1.comment = talloc_strdup(req, "Bla"); - - strncpy(r->out.info[1].info1.name, "IPC$", sizeof(r->out.info[0].info1.name)); - r->out.info[1].info1.pad = 0; - r->out.info[1].info1.type = 1; - r->out.info[1].info1.comment = talloc_strdup(req, "Blub"); + for (i=0;iout.available;i++) { + strncpy(r->out.info[i].info1.name, + dcesrv_common_get_share_name(req, NULL, i), + sizeof(r->out.info[0].info1.name)); + r->out.info[i].info1.pad = 0; + r->out.info[i].info1.type = dcesrv_common_get_share_type(req, NULL, i); + r->out.info[i].info1.comment = talloc_strdup(req, + dcesrv_common_get_share_comment(req, NULL, i)); + } return NT_STATUS_OK; } -- cgit From de2ccc5ca93e0a0476aa829afd987cc043479e91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Dec 2004 11:43:46 +0000 Subject: r4313: fixed a bug in handling new xattrs in the tdb xattr backend (This used to be commit c66b5a100c1b83adf034087fe2ce49fc77d84161) --- source4/ntvfs/posix/xattr_tdb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index 08a2ea4c18..12fe50c277 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -47,8 +47,7 @@ static NTSTATUS xattr_tdb_add_list(struct pvfs_state *pvfs, const char *attr_nam status = pull_xattr_blob_tdb(pvfs, mem_ctx, XATTR_LIST_ATTR, fname, fd, 100, &blob); if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return NT_STATUS_OK; + blob = data_blob(NULL, 0); } for (s=blob.data; s < (char *)(blob.data+blob.length); s += strlen(s) + 1) { -- cgit From a66a985cde1606d0ed6f66f2dc80357b0f7d3363 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Dec 2004 11:44:32 +0000 Subject: r4314: added ACL checking on unlink (This used to be commit f25c469693517ed993e0379d8b07cd7eb235a669) --- source4/ntvfs/posix/pvfs_acl.c | 13 +++++++++++++ source4/ntvfs/posix/pvfs_open.c | 8 +++++++- source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_unlink.c | 15 +++++++++------ 5 files changed, 31 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 95a4e5765c..5302cc9524 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -390,3 +390,16 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, return status; } + + +/* + a simplified interface to access check, designed for calls that + do not take or return an access check mask +*/ +NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + uint32_t access_needed) +{ + return pvfs_access_check(pvfs, req, name, &access_needed); +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 7cb8a5d90c..34052fc44a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1211,7 +1211,9 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, determine if a file can be deleted, or if it is prevented by an already open file */ -NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, struct pvfs_filename *name) +NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name) { NTSTATUS status; DATA_BLOB key; @@ -1228,6 +1230,10 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, struct pvfs_filename *name) NTCREATEX_OPTIONS_DELETE_ON_CLOSE, SEC_STD_DELETE); + if (NT_STATUS_IS_OK(status)) { + status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE); + } + return status; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index cba9cace59..0ca05bbc17 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -162,7 +162,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, status = pvfs_resolve_partial(pvfs, mem_ctx, dir_path, fname2, &name2); if (NT_STATUS_IS_OK(status)) { - status = pvfs_can_delete(pvfs, name2); + status = pvfs_can_delete(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return status; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 2a06def2b4..295d2e919e 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -91,7 +91,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_can_delete(pvfs, name2); + status = pvfs_can_delete(pvfs, req, name2); if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index f29a70600f..09732d7735 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -27,7 +27,9 @@ /* unlink a stream */ -static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct pvfs_filename *name, +static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, uint16_t attrib) { NTSTATUS status; @@ -42,7 +44,7 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct pvfs_filename return status; } - status = pvfs_can_delete(pvfs, name); + status = pvfs_can_delete(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -54,7 +56,8 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct pvfs_filename /* unlink one file */ -static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, +static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, + struct smbsrv_request *req, const char *unix_path, const char *fname, uint32_t attrib) { @@ -62,7 +65,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, NTSTATUS status; /* get a pvfs_filename object */ - status = pvfs_resolve_partial(pvfs, mem_ctx, + status = pvfs_resolve_partial(pvfs, req, unix_path, fname, &name); if (!NT_STATUS_IS_OK(status)) { return status; @@ -75,7 +78,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return status; } - status = pvfs_can_delete(pvfs, name); + status = pvfs_can_delete(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { talloc_free(name); return status; @@ -133,7 +136,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (name->stream_name) { - return pvfs_unlink_stream(pvfs, name, unl->in.attrib); + return pvfs_unlink_stream(pvfs, req, name, unl->in.attrib); } /* get list of matching files */ -- cgit From 359cf872df35096aaf30a36612c62f42d7015378 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Dec 2004 12:41:27 +0000 Subject: r4391: bring the default ACL inline with what w2k3 uses (This used to be commit 16967f7502ea6d2efa0fc08decc955a1516c3a02) --- source4/ntvfs/posix/pvfs_acl.c | 109 ++++++++++++------------------------ source4/ntvfs/posix/pvfs_fileinfo.c | 4 +- 2 files changed, 39 insertions(+), 74 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 5302cc9524..970cddf6f7 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -69,10 +69,8 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, { struct security_descriptor *sd; NTSTATUS status; - struct security_ace aces[4]; + struct security_ace ace; mode_t mode; - struct dom_sid *sid; - int i; sd = security_descriptor_initialise(req); if (sd == NULL) { @@ -90,97 +88,64 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, sd->type |= SEC_DESC_DACL_PRESENT; + mode = name->st.st_mode; + /* - we provide 4 ACEs - - Administrator + we provide up to 4 ACEs - Owner - Group - Everyone + - Administrator */ - aces[0].access_mask = SEC_RIGHTS_FILE_ALL; - aces[1].access_mask = 0; - aces[2].access_mask = 0; - aces[3].access_mask = 0; - mode = name->st.st_mode; + + /* setup owner ACE */ + ace.type = SEC_ACE_TYPE_ACCESS_ALLOWED; + ace.flags = 0; + ace.trustee = *sd->owner_sid; + ace.access_mask = 0; if (mode & S_IRUSR) { - aces[1].access_mask |= - SEC_FILE_READ_DATA | - SEC_FILE_READ_EA | - SEC_FILE_READ_ATTRIBUTE | - SEC_FILE_EXECUTE | - SEC_STD_SYNCHRONIZE | - SEC_STD_READ_CONTROL; + ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; } if (mode & S_IWUSR) { - aces[1].access_mask |= - SEC_FILE_WRITE_DATA | - SEC_FILE_APPEND_DATA | - SEC_FILE_WRITE_EA | - SEC_FILE_WRITE_ATTRIBUTE | - SEC_STD_DELETE; + ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE; + } + if (ace.access_mask) { + security_descriptor_dacl_add(sd, &ace); } + + /* setup group ACE */ + ace.trustee = *sd->group_sid; + ace.access_mask = 0; if (mode & S_IRGRP) { - aces[2].access_mask |= - SEC_FILE_READ_DATA | - SEC_FILE_READ_EA | - SEC_FILE_READ_ATTRIBUTE | - SEC_FILE_EXECUTE | - SEC_STD_SYNCHRONIZE | - SEC_STD_READ_CONTROL; + ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; } if (mode & S_IWGRP) { - aces[2].access_mask |= - SEC_FILE_WRITE_DATA | - SEC_FILE_APPEND_DATA | - SEC_FILE_WRITE_EA | - SEC_FILE_WRITE_ATTRIBUTE; + ace.access_mask |= SEC_RIGHTS_FILE_WRITE; + } + if (ace.access_mask) { + security_descriptor_dacl_add(sd, &ace); } + /* setup other ACE */ + ace.trustee = *dom_sid_parse_talloc(req, SID_WORLD); + ace.access_mask = 0; if (mode & S_IROTH) { - aces[3].access_mask |= - SEC_FILE_READ_DATA | - SEC_FILE_READ_EA | - SEC_FILE_READ_ATTRIBUTE | - SEC_FILE_EXECUTE | - SEC_STD_SYNCHRONIZE | - SEC_STD_READ_CONTROL; + ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; } if (mode & S_IWOTH) { - aces[3].access_mask |= - SEC_FILE_WRITE_DATA | - SEC_FILE_APPEND_DATA | - SEC_FILE_WRITE_EA | - SEC_FILE_WRITE_ATTRIBUTE; + ace.access_mask |= SEC_RIGHTS_FILE_WRITE; } - - sid = dom_sid_parse_talloc(sd, SID_BUILTIN_ADMINISTRATORS); - if (sid == NULL) return NT_STATUS_NO_MEMORY; - - aces[0].type = SEC_ACE_TYPE_ACCESS_ALLOWED; - aces[0].flags = 0; - aces[0].trustee = *sid; - - aces[1].type = SEC_ACE_TYPE_ACCESS_ALLOWED; - aces[1].flags = 0; - aces[1].trustee = *sd->owner_sid; - - aces[2].type = SEC_ACE_TYPE_ACCESS_ALLOWED; - aces[2].flags = 0; - aces[2].trustee = *sd->group_sid; - - sid = dom_sid_parse_talloc(sd, SID_WORLD); - if (sid == NULL) return NT_STATUS_NO_MEMORY; - - aces[3].type = SEC_ACE_TYPE_ACCESS_ALLOWED; - aces[3].flags = 0; - aces[3].trustee = *sid; - - for (i=0;i<4;i++) { - security_descriptor_dacl_add(sd, &aces[i]); + if (ace.access_mask) { + security_descriptor_dacl_add(sd, &ace); } + + /* setup system ACE */ + ace.trustee = *dom_sid_parse_talloc(req, SID_NT_SYSTEM); + ace.access_mask = SEC_RIGHTS_FILE_ALL; + security_descriptor_dacl_add(sd, &ace); acl->version = 1; acl->info.sd = sd; diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 888d5f78c0..fc60aa6e89 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -99,10 +99,10 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, */ mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32 attrib) { - mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; + mode_t mode = S_IRUSR; if (attrib & FILE_ATTRIBUTE_DIRECTORY) { - mode |= S_IXUSR | S_IXGRP | S_IXOTH; + mode |= S_IXUSR; } if (!(attrib & FILE_ATTRIBUTE_READONLY) || -- cgit From abe22d0351955adb1ad7c304d45b9539d202aadb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 02:25:20 +0000 Subject: r4403: - added ACL inheritance in the pvfs backend. ACLs are now inherited on file and directory creation via ntcreatex. pvfs now passes the inheritance test in RAW-ACLS - cleaned up the error handling a bit in pvfs_open() (This used to be commit f4dfb63d5395a365961a21388639809fcd3112d0) --- source4/ntvfs/posix/pvfs_acl.c | 164 ++++++++++++++++++++++++++++++++++++- source4/ntvfs/posix/pvfs_open.c | 116 ++++++++++++++++---------- source4/ntvfs/posix/pvfs_resolve.c | 51 ++++++++++++ 3 files changed, 287 insertions(+), 44 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 970cddf6f7..c2309b92ea 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -106,7 +106,11 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, ace.access_mask = 0; if (mode & S_IRUSR) { - ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + if (mode & S_IWUSR) { + ace.access_mask |= SEC_RIGHTS_FILE_ALL; + } else { + ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; + } } if (mode & S_IWUSR) { ace.access_mask |= SEC_RIGHTS_FILE_WRITE | SEC_STD_DELETE; @@ -123,6 +127,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, ace.access_mask |= SEC_RIGHTS_FILE_READ | SEC_FILE_EXECUTE; } if (mode & S_IWGRP) { + /* note that delete is not granted - this matches posix behaviour */ ace.access_mask |= SEC_RIGHTS_FILE_WRITE; } if (ace.access_mask) { @@ -368,3 +373,160 @@ NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, { return pvfs_access_check(pvfs, req, name, &access_needed); } + + +/* + determine if an ACE is inheritable +*/ +static BOOL pvfs_inheritable_ace(struct pvfs_state *pvfs, + const struct security_ace *ace, + BOOL container) +{ + if (!container) { + return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0; + } + + if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) { + return True; + } + + if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) && + !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) { + return True; + } + + return False; +} + +/* + this is the core of ACL inheritance. It copies any inheritable + aces from the parent SD to the child SD. Note that the algorithm + depends on whether the child is a container or not +*/ +static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, + struct security_descriptor *parent_sd, + struct security_descriptor *sd, + BOOL container) +{ + int i; + + for (i=0;idacl->num_aces;i++) { + struct security_ace ace = parent_sd->dacl->aces[i]; + NTSTATUS status; + + if (!pvfs_inheritable_ace(pvfs, &ace, container)) { + continue; + } + + /* see the RAW-ACLS inheritance test for details on these rules */ + if (!container) { + ace.flags = 0; + } else { + ace.flags &= ~SEC_ACE_FLAG_INHERIT_ONLY; + + if (!(ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) { + ace.flags |= SEC_ACE_FLAG_INHERIT_ONLY; + } + if (ace.flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) { + ace.flags = 0; + } + } + + status = security_descriptor_dacl_add(sd, &ace); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + return NT_STATUS_OK; +} + + + +/* + setup an ACL on a new file/directory based on the inherited ACL from + the parent. If there is no inherited ACL then we don't set anything, + as the default ACL applies anyway +*/ +NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + int fd) +{ + struct xattr_NTACL *acl; + NTSTATUS status; + struct pvfs_filename *parent; + struct security_descriptor *parent_sd, *sd; + BOOL container; + + /* form the parents path */ + status = pvfs_resolve_parent(pvfs, req, name, &parent); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + acl = talloc_p(req, struct xattr_NTACL); + if (acl == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = pvfs_acl_load(pvfs, parent, -1, acl); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { + return NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + switch (acl->version) { + case 1: + parent_sd = acl->info.sd; + break; + default: + return NT_STATUS_INVALID_ACL; + } + + if (parent_sd == NULL || + parent_sd->dacl == NULL || + parent_sd->dacl->num_aces == 0) { + /* go with the default ACL */ + return NT_STATUS_OK; + } + + /* create the new sd */ + sd = security_descriptor_initialise(req); + if (sd == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + sd->type |= SEC_DESC_DACL_PRESENT; + + container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? True:False; + + /* fill in the aces from the parent */ + status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* if there is nothing to inherit then we fallback to the + default acl */ + if (sd->dacl == NULL || sd->dacl->num_aces == 0) { + return NT_STATUS_OK; + } + + acl->info.sd = sd; + + status = pvfs_acl_save(pvfs, name, fd, acl); + + return status; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 34052fc44a..1695d8e1d9 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -95,6 +95,43 @@ static int pvfs_dir_fnum_destructor(void *p) return 0; } +/* + setup any EAs and the ACL on newly created files/directories +*/ +static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + int fd, int fnum, + union smb_open *io) +{ + NTSTATUS status; + + /* setup any EAs that were asked for */ + if (io->ntcreatex.in.ea_list) { + status = pvfs_setfileinfo_ea_set(pvfs, name, fd, + io->ntcreatex.in.ea_list->num_eas, + io->ntcreatex.in.ea_list->eas); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + /* setup an initial sec_desc if requested */ + if (io->ntcreatex.in.sec_desc) { + union smb_setfileinfo set; + + set.set_secdesc.file.fnum = fnum; + set.set_secdesc.in.secinfo_flags = SECINFO_DACL; + set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; + + status = pvfs_acl_set(pvfs, req, name, fd, &set); + } else { + /* otherwise setup an inherited acl from the parent */ + status = pvfs_acl_inherit(pvfs, req, name, fd); + } + + return status; +} /* open a directory @@ -162,6 +199,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* check the security descriptor */ status = pvfs_access_check(pvfs, req, name, &access_mask); if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); return status; } } @@ -200,6 +238,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY; mode_t mode = pvfs_fileperms(pvfs, attrib); if (mkdir(name->full_name, mode) == -1) { + idr_remove(pvfs->idtree_fnum, fnum); return pvfs_map_errno(pvfs,errno); } @@ -207,14 +246,21 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { - return status; + goto cleanup_delete; } + + status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, fnum, io); + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; + } + create_action = NTCREATEX_ACTION_CREATED; } else { create_action = NTCREATEX_ACTION_EXISTED; } if (!name->exists) { + idr_remove(pvfs->idtree_fnum, fnum); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -236,6 +282,11 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, io->generic.out.is_directory = 1; return NT_STATUS_OK; + +cleanup_delete: + idr_remove(pvfs->idtree_fnum, fnum); + rmdir(name->full_name); + return status; } /* @@ -462,53 +513,25 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, name->dos.attrib = attrib; status = pvfs_dosattrib_save(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return status; + goto cleanup_delete; } - /* setup any EAs that were asked for */ - if (io->ntcreatex.in.ea_list) { - status = pvfs_setfileinfo_ea_set(pvfs, name, fd, - io->ntcreatex.in.ea_list->num_eas, - io->ntcreatex.in.ea_list->eas); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return status; - } - } - - /* setup an initial sec_desc is required */ - if (io->ntcreatex.in.sec_desc) { - union smb_setfileinfo set; - - set.set_secdesc.file.fnum = fnum; - set.set_secdesc.in.secinfo_flags = SECINFO_DACL; - set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; - status = pvfs_acl_set(pvfs, req, name, fd, &set); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return status; - } + status = pvfs_open_setup_eas_acl(pvfs, req, name, fd, fnum, io); + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; } /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return status; + goto cleanup_delete; } status = pvfs_brl_locking_key(name, f->handle, &f->handle->brl_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return status; + goto cleanup_delete; } /* grab a lock on the open file record */ @@ -518,16 +541,17 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ - idr_remove(pvfs->idtree_fnum, fnum); - close(fd); - return NT_STATUS_INTERNAL_DB_CORRUPTION; + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto cleanup_delete; } status = odb_open_file(lck, f->handle, name->stream_id, share_access, create_options, access_mask); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { - /* bad news, we must have hit a race */ + /* bad news, we must have hit a race - we don't delete the file + here as the most likely scenario is that someone else created + the file at the same time */ idr_remove(pvfs->idtree_fnum, fnum); close(fd); return status; @@ -583,6 +607,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, talloc_steal(pvfs, f); return NT_STATUS_OK; + +cleanup_delete: + idr_remove(pvfs->idtree_fnum, fnum); + close(fd); + unlink(name->full_name); + return status; } @@ -846,6 +876,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return pvfs_open_directory(pvfs, req, name, io); } + /* FILE_ATTRIBUTE_DIRECTORY is ignored if the above test for directory + open doesn't match */ + io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY; + create_options = io->generic.in.create_options; share_access = io->generic.in.share_access; access_mask = io->generic.in.access_mask; @@ -894,10 +928,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - if (io->generic.in.file_attr & FILE_ATTRIBUTE_DIRECTORY) { - return NT_STATUS_INVALID_PARAMETER; - } - /* handle creating a new file separately */ if (!name->exists) { status = pvfs_create_file(pvfs, req, name, io); diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 7e7f49d0af..4ad3476795 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -579,3 +579,54 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, return pvfs_fill_dos_info(pvfs, name, fd); } + + +/* + resolve the parent of a given name +*/ +NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, + const struct pvfs_filename *child, + struct pvfs_filename **name) +{ + NTSTATUS status; + char *p; + + *name = talloc_p(mem_ctx, struct pvfs_filename); + if (*name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + (*name)->full_name = talloc_strdup(*name, child->full_name); + if ((*name)->full_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + + p = strrchr_m((*name)->full_name, '/'); + if (p == NULL) { + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; + } + + /* this handles the root directory */ + if (p == (*name)->full_name) { + p[1] = 0; + } else { + p[0] = 0; + } + + if (stat((*name)->full_name, &(*name)->st) == -1) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + (*name)->exists = True; + (*name)->stream_exists = True; + (*name)->has_wildcard = False; + /* we can't get the correct 'original_name', but for the purposes + of this call this is close enough */ + (*name)->original_name = talloc_reference(*name, child->original_name); + (*name)->stream_name = NULL; + (*name)->stream_id = 0; + + status = pvfs_fill_dos_info(pvfs, *name, -1); + + return status; +} -- cgit From 1e4a4c4d6e8ce13378cfa54730159b19911af8a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 02:38:44 +0000 Subject: r4405: added acl inheritance to the mkdir and t2mkdir backends. (This used to be commit b44d4d17df8af4941740e5d5e0842ca01d8f403c) --- source4/ntvfs/posix/pvfs_mkdir.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index c4c03f3ad4..14fffb6a2e 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -60,6 +60,13 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_ERROR; } + /* setup an inherited acl from the parent */ + status = pvfs_acl_inherit(pvfs, req, name, -1); + if (!NT_STATUS_IS_OK(status)) { + rmdir(name->full_name); + return status; + } + /* setup any EAs that were asked for */ status = pvfs_setfileinfo_ea_set(pvfs, name, -1, md->t2mkdir.in.num_eas, @@ -109,6 +116,13 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, pvfs_xattr_unlink_hook(pvfs, name->full_name); + /* setup an inherited acl from the parent */ + status = pvfs_acl_inherit(pvfs, req, name, -1); + if (!NT_STATUS_IS_OK(status)) { + rmdir(name->full_name); + return status; + } + return NT_STATUS_OK; } -- cgit From 1c092c5ba6c812e05b63b633c8e9bf0f5ac3deb3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 03:19:27 +0000 Subject: r4406: - don't call the xattr unlink hook on unlink unless the link count is 1, otherwise the xattrs of the remaining link are removed - fix the handling of attribute set on directories (This used to be commit fa44e3cce00b75656c85378c7825960540d2f282) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 10 ++++------ source4/ntvfs/posix/pvfs_unlink.c | 8 +++++--- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 295d2e919e..31db6ce630 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -365,12 +365,10 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the attribute */ if (newstats.dos.attrib != h->name->dos.attrib) { mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib); - if (h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { - /* ignore on directories for now */ - return NT_STATUS_OK; - } - if (fchmod(h->fd, mode) == -1) { - return pvfs_map_errno(pvfs, errno); + if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + if (fchmod(h->fd, mode) == -1) { + return pvfs_map_errno(pvfs, errno); + } } } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 09732d7735..5f8a828f15 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -89,9 +89,11 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - status = pvfs_xattr_unlink_hook(pvfs, name->full_name); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (name->st.st_nlink == 1) { + status = pvfs_xattr_unlink_hook(pvfs, name->full_name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } /* finally try the actual unlink */ -- cgit From e913a48ded85e7baf91a355fff46fe270afed936 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 05:50:23 +0000 Subject: r4408: added the remaining access check hooks into pvfs. All calls should now have acl checking, and obey the various inheritance rules. (This used to be commit 5fe51807d6b97e68b65f152c0f405e5c5a025d21) --- source4/ntvfs/posix/pvfs_acl.c | 21 ++++++++++++++ source4/ntvfs/posix/pvfs_mkdir.c | 16 +++++++++++ source4/ntvfs/posix/pvfs_open.c | 18 +++++++++--- source4/ntvfs/posix/pvfs_qfileinfo.c | 37 ++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_rename.c | 22 ++++++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 52 ++++++++++++++++++++++++++++++++-- 6 files changed, 159 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index c2309b92ea..a5cd9ebd79 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -371,9 +371,30 @@ NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, struct pvfs_filename *name, uint32_t access_needed) { + if (access_needed == 0) { + return NT_STATUS_OK; + } return pvfs_access_check(pvfs, req, name, &access_needed); } +/* + access check for creating a new file/directory +*/ +NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name) +{ + struct pvfs_filename *parent; + NTSTATUS status; + + status = pvfs_resolve_parent(pvfs, req, name, &parent); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); +} + /* determine if an ACE is inheritable diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 14fffb6a2e..d2d431ae79 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_security.h" /* create a directory with EAs @@ -43,6 +44,11 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } + status = pvfs_access_check_create(pvfs, req, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY); if (mkdir(name->full_name, mode) == -1) { @@ -108,6 +114,11 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } + status = pvfs_access_check_create(pvfs, req, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + mode = pvfs_fileperms(pvfs, FILE_ATTRIBUTE_DIRECTORY); if (mkdir(name->full_name, mode) == -1) { @@ -146,6 +157,11 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = pvfs_xattr_unlink_hook(pvfs, name->full_name); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1695d8e1d9..3941414cd8 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -198,10 +198,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, if (name->exists) { /* check the security descriptor */ status = pvfs_access_check(pvfs, req, name, &access_mask); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - return status; - } + } else { + status = pvfs_access_check_create(pvfs, req, name); + } + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + return status; } f->fnum = fnum; @@ -450,6 +452,11 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, mode_t mode; uint32_t attrib; + status = pvfs_access_check_create(pvfs, req, name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return NT_STATUS_CANNOT_DELETE; @@ -1065,6 +1072,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* if this was a stream create then create the stream as well */ if (!name->stream_exists) { + if (!(access_mask & SEC_FILE_WRITE_ATTRIBUTE)) { + return NT_STATUS_ACCESS_DENIED; + } status = pvfs_stream_create(pvfs, f->handle->name, fd); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 75a9909492..dae9ca649c 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -24,6 +24,31 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" + +/* + determine what access bits are needed for a call +*/ +static uint32_t pvfs_fileinfo_access(enum smb_fileinfo_level level) +{ + uint32_t needed; + + switch (level) { + case RAW_FILEINFO_EA_LIST: + case RAW_FILEINFO_ALL_EAS: + needed = SEC_FILE_READ_EA; + break; + + case RAW_FILEINFO_IS_NAME_VALID: + needed = 0; + break; + + default: + needed = SEC_FILE_READ_ATTRIBUTE; + break; + } + return needed; +} + /* reply to a RAW_FILEINFO_EA_LIST call */ @@ -269,6 +294,12 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + status = pvfs_access_check_simple(pvfs, req, name, + pvfs_fileinfo_access(info->generic.level)); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = pvfs_map_fileinfo(pvfs, req, name, info, -1); return status; @@ -284,6 +315,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct pvfs_file *f; struct pvfs_file_handle *h; NTSTATUS status; + uint32_t access_needed; f = pvfs_find_fd(pvfs, req, info->generic.in.fnum); if (!f) { @@ -291,6 +323,11 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, } h = f->handle; + access_needed = pvfs_fileinfo_access(info->generic.level); + if (!(f->access_mask & access_needed)) { + return NT_STATUS_ACCESS_DENIED; + } + /* update the file information */ status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 0ca05bbc17..9fe92c9173 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -169,6 +169,11 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, } } + status = pvfs_access_check_create(pvfs, req, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + fname2 = talloc_asprintf(mem_ctx, "%s/%s", dir_path, fname2); if (fname2 == NULL) { return NT_STATUS_NO_MEMORY; @@ -283,6 +288,11 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } + status = pvfs_access_check_create(pvfs, req, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + status = pvfs_can_rename(pvfs, name1); if (!NT_STATUS_IS_OK(status)) { return status; @@ -357,18 +367,30 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: + status = pvfs_access_check_create(pvfs, req, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } if (rename(name1->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } break; case RENAME_FLAG_HARD_LINK: + status = pvfs_access_check_create(pvfs, req, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } if (link(name1->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } break; case RENAME_FLAG_COPY: + status = pvfs_access_check_create(pvfs, req, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } return pvfs_copy_file(pvfs, name1, name2); case RENAME_FLAG_MOVE_CLUSTER_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 31db6ce630..10eb082183 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -26,6 +26,38 @@ #include "librpc/gen_ndr/ndr_xattr.h" +/* + determine what access bits are needed for a call +*/ +static uint32_t pvfs_setfileinfo_access(enum smb_setfileinfo_level level) +{ + uint32_t needed; + + switch (level) { + case RAW_SFILEINFO_EA_SET: + needed = SEC_FILE_WRITE_EA; + break; + + case RAW_SFILEINFO_DISPOSITION_INFO: + case RAW_SFILEINFO_DISPOSITION_INFORMATION: + needed = SEC_STD_DELETE; + break; + + case RAW_SFILEINFO_END_OF_FILE_INFO: + needed = SEC_FILE_WRITE_DATA; + break; + + case RAW_SFILEINFO_POSITION_INFORMATION: + needed = 0; + break; + + default: + needed = SEC_FILE_WRITE_ATTRIBUTE; + break; + } + return needed; +} + /* rename_information level */ @@ -100,6 +132,11 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } } + status = pvfs_access_check_create(pvfs, req, name2); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (rename(name->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } @@ -202,6 +239,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, uint32_t create_options; struct pvfs_filename newstats; NTSTATUS status; + uint32_t access_needed; f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); if (!f) { @@ -210,6 +248,11 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, h = f->handle; + access_needed = pvfs_setfileinfo_access(info->generic.level); + if (!(f->access_mask & access_needed)) { + return NT_STATUS_ACCESS_DENIED; + } + /* update the file information */ status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); if (!NT_STATUS_IS_OK(status)) { @@ -272,9 +315,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - if (!(f->access_mask & SEC_STD_DELETE)) { - return NT_STATUS_ACCESS_DENIED; - } create_options = h->create_options; if (info->disposition_info.in.delete_on_close) { create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; @@ -389,6 +429,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct pvfs_filename newstats; NTSTATUS status; struct utimbuf unix_times; + uint32_t access_needed; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, @@ -401,6 +442,11 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + access_needed = pvfs_setfileinfo_access(info->generic.level); + status = pvfs_access_check_simple(pvfs, req, name, access_needed); + if (!NT_STATUS_IS_OK(status)) { + return status; + } /* we take a copy of the current file stats, then update newstats in each of the elements below. At the end we -- cgit From 91190fdad861077d0c33bf85f8fd284f69e3e3fe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 06:02:54 +0000 Subject: r4409: fixed handling of zero access masks for the POSITION_INFORMATION query/set levels (This used to be commit 75e7229476e1af6ab78fa5b41a7bb67df8e3d2dd) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index dae9ca649c..efd95e7674 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -324,7 +324,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, h = f->handle; access_needed = pvfs_fileinfo_access(info->generic.level); - if (!(f->access_mask & access_needed)) { + if ((f->access_mask & access_needed) != access_needed) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 10eb082183..fbc71dc9d4 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -249,7 +249,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, h = f->handle; access_needed = pvfs_setfileinfo_access(info->generic.level); - if (!(f->access_mask & access_needed)) { + if ((f->access_mask & access_needed) != access_needed) { return NT_STATUS_ACCESS_DENIED; } -- cgit From 4f16988ead0684daa4d2ffef01e7b6f61eb83f81 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 06:37:37 +0000 Subject: r4410: pvfs_rename_one() should not check for create permissions, as the rename is always in the same directory (This used to be commit babf3480a4c29ce28d9a4525c4174a3d765dcbab) --- source4/ntvfs/posix/pvfs_rename.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 9fe92c9173..f8d0ba1c27 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -141,21 +141,18 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, status = pvfs_resolve_partial(pvfs, mem_ctx, dir_path, fname1, &name1); if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return status; + goto failed; } /* make sure its matches the given attributes */ status = pvfs_match_attrib(pvfs, name1, attrib, 0); if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return status; + goto failed; } status = pvfs_can_rename(pvfs, name1); if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return status; + goto failed; } /* get a pvfs_filename dest object */ @@ -164,15 +161,11 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, if (NT_STATUS_IS_OK(status)) { status = pvfs_can_delete(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { - talloc_free(mem_ctx); - return status; + goto failed; } } - status = pvfs_access_check_create(pvfs, req, name2); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + status = NT_STATUS_OK; fname2 = talloc_asprintf(mem_ctx, "%s/%s", dir_path, fname2); if (fname2 == NULL) { @@ -184,9 +177,9 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, return pvfs_map_errno(pvfs, errno); } +failed: talloc_free(mem_ctx); - - return NT_STATUS_OK; + return status; } -- cgit From 373bca5bcd9555acda8ecf526c82f136c2312ee8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 06:51:13 +0000 Subject: r4411: when checking for create permissions, we need to check the parent, not the child! (This used to be commit 30b4c20b1c9aea94dd2a0611b58860797d244e5a) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index a5cd9ebd79..6741fb851d 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -392,7 +392,7 @@ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, return status; } - return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); + return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE); } -- cgit From ef179fddb3c4feae9d048034c035cbda71457ccc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Dec 2004 07:10:31 +0000 Subject: r4412: SEC_FILE_READ_ATTRIBUTE is always granted, even if not requested. This was being done in the full ACL code, but not in the unix access check code, which meant that qfileinfo was failing for some parameters (This used to be commit 96d017e521f5a996a7a274682838855d077834bc) --- source4/ntvfs/posix/pvfs_acl.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 6741fb851d..4cc22b0918 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -306,6 +306,8 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, return NT_STATUS_ACCESS_DENIED; } + *access_mask |= SEC_FILE_READ_ATTRIBUTE; + return NT_STATUS_OK; } -- cgit From b5b1c52a9850de18e756cdd073cf5f44f26882fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Dec 2004 20:34:20 +0000 Subject: r4419: move security_token stuff to the libcli/security/ and debug privileges metze (This used to be commit c981808ed4cfa63c7ba7c4f9190b6b14f74bab40) --- source4/ntvfs/unixuid/vfs_unixuid.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 1c4572969f..f29ed51a49 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -23,6 +23,7 @@ #include "includes.h" #include "auth/auth.h" +#include "libcli/security/security.h" #include "smb_server/smb_server.h" struct unixuid_private { -- cgit From 0128bd6d3f06fd433ec3747686da1e1a1133ab3d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Dec 2004 01:03:57 +0000 Subject: r4423: give lp_parm_int() and lp_parm_ulong() default values metze (This used to be commit c44f4d44b51789916e50c9da93046d0a15245edc) --- source4/ntvfs/posix/pvfs_shortname.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index c0fc2fb136..9efd1cec85 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -604,7 +604,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) memset(ctx->prefix_cache, 0, sizeof(char *)*MANGLE_CACHE_SIZE); memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t)*MANGLE_CACHE_SIZE); - ctx->mangle_prefix = lp_parm_int(-1, "mangle", "prefix"); + ctx->mangle_prefix = lp_parm_int(-1, "mangle", "prefix", -1); if (ctx->mangle_prefix < 0 || ctx->mangle_prefix > 6) { ctx->mangle_prefix = DEFAULT_MANGLE_PREFIX; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 6f4de1e038..eecc379064 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -34,7 +34,6 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) { int snum = pvfs->tcon->service; - int delay; const char *eadb; if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; @@ -53,11 +52,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif - pvfs->sharing_violation_delay = 1000000; - delay = lp_parm_int(snum, "posix", "sharedelay"); - if (delay != -1) { - pvfs->sharing_violation_delay = delay; - } + pvfs->sharing_violation_delay = lp_parm_int(snum, "posix", "sharedelay", 1000000); pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); @@ -81,7 +76,6 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) } } - if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_NAMED_STREAMS; } -- cgit From 291b02a639aa6551ac1f59e47a78d5590d2b7f6e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 Dec 2004 08:56:32 +0000 Subject: r4448: - fixed access_mask checking on acl set - honor the change ownership requests of acl set, changing the underlying unix owner/group - fix the access mask on file create with SEC_FLAG_MAXIMUM_ALLOWED (This used to be commit 5761fa35ab727b51ef1b52459911bafbdd788755) --- source4/ntvfs/posix/pvfs_acl.c | 38 ++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_open.c | 7 +++++-- source4/ntvfs/posix/pvfs_qfileinfo.c | 4 ++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 17 ++++++++++----- 4 files changed, 57 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 4cc22b0918..ce5f3a248b 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -185,12 +185,15 @@ static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, struct smbsrv_request *req, struct pvfs_filename *name, int fd, + uint32_t access_mask, union smb_setfileinfo *info) { struct xattr_NTACL *acl; uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags; struct security_descriptor *new_sd, *sd; NTSTATUS status; + uid_t uid = -1; + gid_t gid = -1; acl = talloc_p(req, struct xattr_NTACL); if (acl == NULL) { @@ -215,12 +218,28 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, new_sd = info->set_secdesc.in.sd; + uid = name->st.st_uid; + gid = name->st.st_gid; + /* only set the elements that have been specified */ - if (secinfo_flags & SECINFO_OWNER) { + if ((secinfo_flags & SECINFO_OWNER) && + !dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) { + if (!(access_mask & SEC_STD_WRITE_OWNER)) { + return NT_STATUS_ACCESS_DENIED; + } sd->owner_sid = new_sd->owner_sid; + status = sidmap_sid_to_unixuid(pvfs->sidmap, sd->owner_sid, &uid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } - if (secinfo_flags & SECINFO_GROUP) { + if ((secinfo_flags & SECINFO_GROUP) && + !dom_sid_equal(sd->group_sid, new_sd->group_sid)) { sd->group_sid = new_sd->group_sid; + status = sidmap_sid_to_unixgid(pvfs->sidmap, sd->owner_sid, &gid); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } if (secinfo_flags & SECINFO_DACL) { sd->dacl = new_sd->dacl; @@ -228,9 +247,24 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } if (secinfo_flags & SECINFO_SACL) { sd->sacl = new_sd->sacl; + if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) { + return NT_STATUS_ACCESS_DENIED; + } pvfs_translate_generic_bits(sd->sacl); } + if (uid != -1 || gid != -1) { + int ret; + if (fd == -1) { + ret = chown(name->full_name, uid, gid); + } else { + ret = fchown(fd, uid, gid); + } + if (ret == -1) { + return pvfs_map_errno(pvfs, errno); + } + } + status = pvfs_acl_save(pvfs, name, fd, acl); return status; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3941414cd8..c59f2d22e9 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -124,7 +124,7 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; - status = pvfs_acl_set(pvfs, req, name, fd, &set); + status = pvfs_acl_set(pvfs, req, name, fd, SEC_STD_WRITE_DAC, &set); } else { /* otherwise setup an inherited acl from the parent */ status = pvfs_acl_inherit(pvfs, req, name, fd); @@ -463,9 +463,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { - access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; + access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE | + SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; } + access_mask |= SEC_FILE_READ_ATTRIBUTE; + if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { flags = O_RDWR; } else { diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index efd95e7674..463574c8cf 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -42,6 +42,10 @@ static uint32_t pvfs_fileinfo_access(enum smb_fileinfo_level level) needed = 0; break; + case RAW_FILEINFO_SEC_DESC: + needed = SEC_STD_READ_CONTROL; + break; + default: needed = SEC_FILE_READ_ATTRIBUTE; break; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index fbc71dc9d4..7144f37a14 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -29,11 +29,11 @@ /* determine what access bits are needed for a call */ -static uint32_t pvfs_setfileinfo_access(enum smb_setfileinfo_level level) +static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) { uint32_t needed; - switch (level) { + switch (info->generic.level) { case RAW_SFILEINFO_EA_SET: needed = SEC_FILE_WRITE_EA; break; @@ -51,6 +51,13 @@ static uint32_t pvfs_setfileinfo_access(enum smb_setfileinfo_level level) needed = 0; break; + case RAW_SFILEINFO_SEC_DESC: + needed = 0; + if (info->set_secdesc.in.secinfo_flags & (SECINFO_DACL|SECINFO_SACL)) { + needed |= SEC_STD_WRITE_DAC; + } + break; + default: needed = SEC_FILE_WRITE_ATTRIBUTE; break; @@ -248,7 +255,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, h = f->handle; - access_needed = pvfs_setfileinfo_access(info->generic.level); + access_needed = pvfs_setfileinfo_access(info); if ((f->access_mask & access_needed) != access_needed) { return NT_STATUS_ACCESS_DENIED; } @@ -358,7 +365,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, &info->rename_information.in); case RAW_SFILEINFO_SEC_DESC: - return pvfs_acl_set(pvfs, req, h->name, h->fd, info); + return pvfs_acl_set(pvfs, req, h->name, h->fd, f->access_mask, info); default: return NT_STATUS_INVALID_LEVEL; @@ -442,7 +449,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - access_needed = pvfs_setfileinfo_access(info->generic.level); + access_needed = pvfs_setfileinfo_access(info); status = pvfs_access_check_simple(pvfs, req, name, access_needed); if (!NT_STATUS_IS_OK(status)) { return status; -- cgit From d4b16573966d2b5e45a3a83d75fe0827ce9dc4be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 1 Jan 2005 04:25:46 +0000 Subject: r4464: added pvfs backend support for the special CREATOR_OWNER and CREATOR_GROUP inheritance rules (This used to be commit 0a29fb45c310b4b8c348d187b8ff1833deaac6c3) --- source4/ntvfs/posix/pvfs_acl.c | 38 +++++++++++++++++++++++++++++++++++++- source4/ntvfs/posix/vfs_posix.c | 4 ++++ source4/ntvfs/posix/vfs_posix.h | 6 ++++++ 3 files changed, 47 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index ce5f3a248b..ba5fa96b07 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -470,11 +470,15 @@ static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, for (i=0;idacl->num_aces;i++) { struct security_ace ace = parent_sd->dacl->aces[i]; NTSTATUS status; + const struct dom_sid *creator = NULL, *new_id = NULL; + uint32_t orig_flags; if (!pvfs_inheritable_ace(pvfs, &ace, container)) { continue; } + orig_flags = ace.flags; + /* see the RAW-ACLS inheritance test for details on these rules */ if (!container) { ace.flags = 0; @@ -489,7 +493,39 @@ static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, } } - status = security_descriptor_dacl_add(sd, &ace); + /* the CREATOR sids are special when inherited */ + if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_owner)) { + creator = pvfs->sid_cache.creator_owner; + new_id = sd->owner_sid; + } else if (dom_sid_equal(&ace.trustee, pvfs->sid_cache.creator_group)) { + creator = pvfs->sid_cache.creator_group; + new_id = sd->group_sid; + } else { + new_id = &ace.trustee; + } + + if (creator && container && + (ace.flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) { + uint32_t flags = ace.flags; + + ace.trustee = *new_id; + ace.flags = 0; + status = security_descriptor_dacl_add(sd, &ace); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ace.trustee = *creator; + ace.flags = flags | SEC_ACE_FLAG_INHERIT_ONLY; + status = security_descriptor_dacl_add(sd, &ace); + } else if (container && + !(orig_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) { + status = security_descriptor_dacl_add(sd, &ace); + } else { + ace.trustee = *new_id; + status = security_descriptor_dacl_add(sd, &ace); + } + if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index eecc379064..e5bdc3faae 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -26,6 +26,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_security.h" /* @@ -82,6 +83,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs->fs_attribs |= FS_ATTR_PERSISTANT_ACLS; } + + pvfs->sid_cache.creator_owner = dom_sid_parse_talloc(pvfs, SID_CREATOR_OWNER); + pvfs->sid_cache.creator_group = dom_sid_parse_talloc(pvfs, SID_CREATOR_GROUP); } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index e80790f6fa..f7bf19c3dc 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -60,6 +60,12 @@ struct pvfs_state { /* if posix:eadb is set, then this gets setup */ struct tdb_wrap *ea_db; + + /* used to accelerate acl mapping */ + struct { + const struct dom_sid *creator_owner; + const struct dom_sid *creator_group; + } sid_cache; }; /* this is the basic information needed about a file from the filesystem */ -- cgit From 586949362684864a18f9a56b5a96f7c4b8331281 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2005 07:57:05 +0000 Subject: r4501: when copying files it is common for clients to copy the ACL. When the ACL is the default ACL this menas the copied file would have an xattr but the original would not. Avoid this by checking if the ACL being set is the original ACL, and avoid the copy. (This used to be commit 1df985a49b200a41eed39023aa668afb233f2e53) --- source4/ntvfs/posix/pvfs_acl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index ba5fa96b07..86a9a56ee9 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -190,7 +190,7 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, { struct xattr_NTACL *acl; uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags; - struct security_descriptor *new_sd, *sd; + struct security_descriptor *new_sd, *sd, orig_sd; NTSTATUS status; uid_t uid = -1; gid_t gid = -1; @@ -217,6 +217,7 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } new_sd = info->set_secdesc.in.sd; + orig_sd = *sd; uid = name->st.st_uid; gid = name->st.st_gid; @@ -265,7 +266,12 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } } - status = pvfs_acl_save(pvfs, name, fd, acl); + /* we avoid saving if the sd is the same. This means when clients + copy files and end up copying the default sd that we don't + needlessly use xattrs */ + if (!security_descriptor_equal(sd, &orig_sd)) { + status = pvfs_acl_save(pvfs, name, fd, acl); + } return status; } -- cgit From cc55aef7c116d03ba2817625b0ba9edb378525e3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jan 2005 02:32:43 +0000 Subject: r4547: - added talloc_new(ctx) macro that is a neater form of the common talloc(ctx, 0) call. - cleaned up some talloc usage in various files I'd like to get to the point that we have no calls to talloc(), at which point we will rename talloc_p() to talloc(), to encourage everyone to use the typesafe functions. (This used to be commit e6c81d7c9f8a6938947d3c1c8a971a0d6d50b67a) --- source4/ntvfs/common/sidmap.c | 12 ++++++------ source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_xattr.c | 4 ++-- source4/ntvfs/posix/xattr_tdb.c | 4 ++-- source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 89ad2e2430..3254330c2f 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -94,7 +94,7 @@ static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap, TALLOC_CTX *mem_ctx, struct dom_sid **sid) { const char *attrs[] = { "objectSid", NULL }; - void *ctx = talloc(mem_ctx, 0); + void *ctx = talloc_new(mem_ctx); const char *sidstr; int ret; struct ldb_message **res; @@ -138,7 +138,7 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, struct dom_sid *domain_sid; NTSTATUS status; - ctx = talloc(sidmap, 0); + ctx = talloc_new(sidmap); sidstr = dom_sid_string(ctx, sid); if (sidstr == NULL) { talloc_free(ctx); @@ -237,7 +237,7 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, NTSTATUS status; struct dom_sid *domain_sid; - ctx = talloc(sidmap, 0); + ctx = talloc_new(sidmap); sidstr = dom_sid_string(ctx, sid); if (sidstr == NULL) { talloc_free(ctx); @@ -349,7 +349,7 @@ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, */ - ctx = talloc(sidmap, 0); + ctx = talloc_new(sidmap); /* @@ -461,7 +461,7 @@ NTSTATUS sidmap_gid_to_sid(struct sidmap_context *sidmap, */ - ctx = talloc(sidmap, 0); + ctx = talloc_new(sidmap); /* @@ -553,7 +553,7 @@ NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, { NTSTATUS status; struct dom_sid *domain_sid; - void *ctx = talloc(mem_ctx, 0); + void *ctx = talloc_new(mem_ctx); uint32_t rid; status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid); diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index f8d0ba1c27..8e057f214b 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -128,7 +128,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, uint16_t attrib) { struct pvfs_filename *name1, *name2; - TALLOC_CTX *mem_ctx = talloc(req, 0); + TALLOC_CTX *mem_ctx = talloc_new(req); NTSTATUS status; /* resolve the wildcard pattern for this name */ diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index baa6c15e31..ca535db168 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -127,7 +127,7 @@ static NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, const char *fname, int fd, const char *attr_name, void *p, ndr_push_flags_fn_t push_fn) { - TALLOC_CTX *mem_ctx = talloc(NULL, 0); + TALLOC_CTX *mem_ctx = talloc_new(NULL); DATA_BLOB blob; NTSTATUS status; @@ -151,7 +151,7 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name { NTSTATUS status; struct xattr_DosAttrib attrib; - TALLOC_CTX *mem_ctx = talloc(name, 0); + TALLOC_CTX *mem_ctx = talloc_new(name); struct xattr_DosInfo1 *info1; struct xattr_DosInfo2 *info2; diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index 12fe50c277..eebae38ab7 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -42,7 +42,7 @@ static NTSTATUS xattr_tdb_add_list(struct pvfs_state *pvfs, const char *attr_nam return NT_STATUS_OK; } - mem_ctx = talloc(pvfs, 0); + mem_ctx = talloc_new(pvfs); status = pull_xattr_blob_tdb(pvfs, mem_ctx, XATTR_LIST_ATTR, fname, fd, 100, &blob); @@ -211,7 +211,7 @@ NTSTATUS delete_xattr_tdb(struct pvfs_state *pvfs, const char *attr_name, */ NTSTATUS unlink_xattr_tdb(struct pvfs_state *pvfs, const char *fname) { - TALLOC_CTX *mem_ctx = talloc(pvfs, 0); + TALLOC_CTX *mem_ctx = talloc_new(pvfs); DATA_BLOB blob; const char *s; NTSTATUS status; diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index f29ed51a49..a1a5244453 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -145,7 +145,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, { struct unixuid_private *private = ntvfs->private_data; struct security_token *token = req->session->session_info->security_token; - void *ctx = talloc(req, 0); + void *ctx = talloc_new(req); struct unix_sec_ctx *newsec; NTSTATUS status; -- cgit From ddc10d4d37984246a6547e34a32d629c689c40d1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jan 2005 03:06:58 +0000 Subject: r4549: got rid of a lot more uses of plain talloc(), instead using talloc_size() or talloc_array_p() where appropriate. also fixed a memory leak in pvfs_copy_file() (failed to free a memory context) (This used to be commit 89b74b53546e1570b11b3702f40bee58aed8c503) --- source4/ntvfs/ntvfs_generic.c | 11 +++++++---- source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_resolve.c | 2 +- source4/ntvfs/posix/pvfs_util.c | 3 ++- 4 files changed, 11 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 407bd38f74..051e92b19c 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -713,8 +713,10 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info case RAW_FILEINFO_STREAM_INFORMATION: info->stream_info.out.num_streams = info2->generic.out.num_streams; if (info->stream_info.out.num_streams > 0) { - info->stream_info.out.streams = talloc(req, - info->stream_info.out.num_streams * sizeof(struct stream_struct)); + info->stream_info.out.streams = + talloc_array_p(req, + struct stream_struct, + info->stream_info.out.num_streams); if (!info->stream_info.out.streams) { DEBUG(2,("ntvfs_map_fileinfo: no memory for %d streams\n", info->stream_info.out.num_streams)); @@ -751,8 +753,9 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info case RAW_FILEINFO_ALL_EAS: info->all_eas.out.num_eas = info2->generic.out.num_eas; if (info->all_eas.out.num_eas > 0) { - info->all_eas.out.eas = talloc(req, - info->all_eas.out.num_eas * sizeof(struct ea_struct)); + info->all_eas.out.eas = talloc_array_p(req, + struct ea_struct, + info->all_eas.out.num_eas); if (!info->all_eas.out.eas) { DEBUG(2,("ntvfs_map_fileinfo: no memory for %d eas\n", info->all_eas.out.num_eas)); diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 8e057f214b..3203f7fa86 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -35,7 +35,7 @@ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, char *dest, *d; /* the length is bounded by the length of the two strings combined */ - dest = talloc(mem_ctx, strlen(fname) + strlen(pattern) + 1); + dest = talloc_size(mem_ctx, strlen(fname) + strlen(pattern) + 1); if (dest == NULL) { return NULL; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 4ad3476795..fc1576b955 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -412,7 +412,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t } /* rebuild the name */ - ret = talloc(mem_ctx, len+1); + ret = talloc_size(mem_ctx, len+1); if (ret == NULL) { talloc_free(s); return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 6026b9fbf3..eb0f04728c 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -89,7 +89,7 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs, mode_t mode; NTSTATUS status; size_t buf_size = 0x10000; - char *buf = talloc(name2, buf_size); + char *buf = talloc_size(name2, buf_size); if (buf == NULL) { return NT_STATUS_NO_MEMORY; @@ -134,6 +134,7 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs, } } + talloc_free(buf); close(fd1); mode = pvfs_fileperms(pvfs, name1->dos.attrib); -- cgit From 5db389cbdc606be3f66766dd80a0b7ecf10d7a2d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 6 Jan 2005 12:22:20 +0000 Subject: r4567: Fix the build for metze. Andrew Bartlett (This used to be commit d05a9bf1a12c9f0b18c9e65b6aa03fa4283a1b68) --- source4/ntvfs/ipc/rap_server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 0e6c18ca3b..4875592ad6 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -21,6 +21,7 @@ #include "includes.h" #include "rap.h" +#include "librpc/gen_ndr/ndr_srvsvc.h" /* At this moment these are just dummy functions, but you might get the * idea. */ -- cgit From ad7da47948a5a3ed2c3fc18392b83c059bec5b6e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 02:14:34 +0000 Subject: r4584: fix pvfs backend to pass the new enhanced RAW-ACLS test. Easy once I really the strange behaviour I saw was a w2k3 bug :-) (This used to be commit e729061bcde25d0565a72222e4720ca8074ef23f) --- source4/ntvfs/posix/pvfs_acl.c | 34 ++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_mkdir.c | 4 ++-- source4/ntvfs/posix/pvfs_open.c | 15 ++++----------- source4/ntvfs/posix/pvfs_rename.c | 8 ++++---- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 5 files changed, 43 insertions(+), 20 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 86a9a56ee9..5d8225f8ec 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -392,6 +392,8 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, /* expand the generic access bits to file specific bits */ *access_mask = pvfs_translate_mask(*access_mask); + *access_mask &= ~SEC_FILE_READ_ATTRIBUTE; + /* check the acl against the required access mask */ status = sec_access_check(sd, token, *access_mask, access_mask); @@ -424,7 +426,35 @@ NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, */ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, struct smbsrv_request *req, - struct pvfs_filename *name) + struct pvfs_filename *name, + uint32_t *access_mask) +{ + struct pvfs_filename *parent; + NTSTATUS status; + + status = pvfs_resolve_parent(pvfs, req, name, &parent); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_access_check(pvfs, req, parent, access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (! ((*access_mask) & SEC_DIR_ADD_FILE)) { + return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); + } + + return status; +} + +/* + access check for creating a new file/directory - no access mask supplied +*/ +NTSTATUS pvfs_access_check_create_nomask(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name) { struct pvfs_filename *parent; NTSTATUS status; @@ -434,7 +464,7 @@ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, return status; } - return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE); + return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); } diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index d2d431ae79..42b5109673 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -44,7 +44,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_access_check_create(pvfs, req, name); + status = pvfs_access_check_create_nomask(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -114,7 +114,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_access_check_create(pvfs, req, name); + status = pvfs_access_check_create_nomask(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c59f2d22e9..b34d75d24d 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -199,7 +199,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* check the security descriptor */ status = pvfs_access_check(pvfs, req, name, &access_mask); } else { - status = pvfs_access_check_create(pvfs, req, name); + status = pvfs_access_check_create(pvfs, req, name, &access_mask); } if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->idtree_fnum, fnum); @@ -452,23 +452,16 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, mode_t mode; uint32_t attrib; - status = pvfs_access_check_create(pvfs, req, name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return NT_STATUS_CANNOT_DELETE; } - if (access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { - access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE | - SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL; + status = pvfs_access_check_create(pvfs, req, name, &access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; } - access_mask |= SEC_FILE_READ_ATTRIBUTE; - if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { flags = O_RDWR; } else { diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 3203f7fa86..91ad9aa3d9 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -281,7 +281,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -360,7 +360,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -370,7 +370,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, break; case RENAME_FLAG_HARD_LINK: - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -380,7 +380,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, break; case RENAME_FLAG_COPY: - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 7144f37a14..8c4d016ccc 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -139,7 +139,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } } - status = pvfs_access_check_create(pvfs, req, name2); + status = pvfs_access_check_create_nomask(pvfs, req, name2); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 11ce2cfd70df264c5c91b4daaa9a01c5abc673b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 04:39:16 +0000 Subject: r4591: - converted the other _p talloc functions to not need _p - added #if TALLOC_DEPRECATED around the _p functions - fixes the code that broke from the above while doing this I fixed quite a number of places that were incorrectly using the non type-safe talloc functions to use the type safe ones. Some were even doing multiplies for array allocation, which is potentially unsafe. (This used to be commit 6e7754abd0c225527fb38363996a6e241b87b37e) --- source4/ntvfs/posix/pvfs_dirlist.c | 6 +++--- source4/ntvfs/posix/pvfs_streams.c | 4 ++-- source4/ntvfs/posix/xattr_system.c | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 5c67b2d189..c2e8f826a2 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -137,9 +137,9 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, dir->no_wildcard = False; dir->end_of_search = False; dir->offset = 0; - dir->name_cache = talloc_zero_array_p(dir, - struct name_cache_entry, - NAME_CACHE_SIZE); + dir->name_cache = talloc_zero_array(dir, + struct name_cache_entry, + NAME_CACHE_SIZE); if (dir->name_cache == NULL) { talloc_free(dir); return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 12f783e172..e92732b810 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -283,7 +283,7 @@ ssize_t pvfs_stream_write(struct pvfs_state *pvfs, blob = data_blob(NULL, 0); } if (count+offset > blob.length) { - blob.data = talloc_realloc(blob.data, blob.data, count+offset); + blob.data = talloc_realloc(blob.data, blob.data, uint8_t, count+offset); if (blob.data == NULL) { errno = ENOMEM; return -1; @@ -339,7 +339,7 @@ NTSTATUS pvfs_stream_truncate(struct pvfs_state *pvfs, if (length <= blob.length) { blob.length = length; } else if (length > blob.length) { - blob.data = talloc_realloc(blob.data, blob.data, length); + blob.data = talloc_realloc(blob.data, blob.data, uint8_t, length); if (blob.data == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index c86ee0bd87..f19177f44c 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -51,7 +51,8 @@ again: } if (ret == -1 && errno == ERANGE) { estimated_size *= 2; - blob->data = talloc_realloc(mem_ctx, blob->data, estimated_size); + blob->data = talloc_realloc(mem_ctx, blob->data, + uint8_t, estimated_size); if (blob->data == NULL) { return NT_STATUS_NO_MEMORY; } -- cgit From c012669b5538dfbc66697da07b5295431a35ac13 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2005 05:24:38 +0000 Subject: r4595: on create check access against parent not child ... (This used to be commit 5a1a17d3fc771b1e1c61297067f38c87901891d3) --- source4/ntvfs/posix/pvfs_acl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 5d8225f8ec..590c9c18b5 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -443,7 +443,7 @@ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, } if (! ((*access_mask) & SEC_DIR_ADD_FILE)) { - return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); + return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE); } return status; @@ -464,7 +464,7 @@ NTSTATUS pvfs_access_check_create_nomask(struct pvfs_state *pvfs, return status; } - return pvfs_access_check_simple(pvfs, req, name, SEC_DIR_ADD_FILE); + return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE); } -- cgit From c13ada4e35a3ad68950a19a981499acebb521128 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 9 Jan 2005 02:33:16 +0000 Subject: r4608: - use better error codes - use new NT_STATUS_* macros for error checking return - don't use talloc_p anymore metze (This used to be commit 372a8eeeefc2ebff50211985372888b5b6d4eb65) --- source4/ntvfs/ntvfs_base.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index ca6fbf0de8..b8aeed419c 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -126,37 +126,32 @@ NTSTATUS ntvfs_init_connection(struct smbsrv_request *req, enum ntvfs_type type) struct ntvfs_context *ctx; if (!handlers) { - return NT_STATUS_FOOBAR; + return NT_STATUS_INTERNAL_ERROR; } - ctx = talloc_p(req->tcon, struct ntvfs_context); - if (!ctx) { - return NT_STATUS_NO_MEMORY; - } + ctx = talloc(req->tcon, struct ntvfs_context); + NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->type = type; ctx->modules = NULL; for (i=0; handlers[i]; i++) { struct ntvfs_module_context *ntvfs; - ntvfs = talloc_p(ctx, struct ntvfs_module_context); - if (!ntvfs) { - return NT_STATUS_NO_MEMORY; - } + ntvfs = talloc(ctx, struct ntvfs_module_context); + NT_STATUS_HAVE_NO_MEMORY(ntvfs); ntvfs->ops = ntvfs_backend_byname(handlers[i], ctx->type); if (!ntvfs->ops) { DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", handlers[i], ctx->type)); - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_INTERNAL_ERROR; } ntvfs->depth = i; DLIST_ADD_END(ctx->modules, ntvfs, struct ntvfs_module_context *); } if (!ctx->modules) { - talloc_free(ctx); - return NT_STATUS_FOOBAR; + return NT_STATUS_INTERNAL_ERROR; } req->tcon->ntvfs_ctx = ctx; -- cgit From 3feb4423f3ec35dd3dfa2c358797a4f6a86b2fb5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Jan 2005 08:27:35 +0000 Subject: r4615: added acl checking on directory search in pvfs (This used to be commit 0e61a422bd9a1596a284c176f033e958bbeaa8ce) --- source4/ntvfs/posix/pvfs_acl.c | 9 +++++---- source4/ntvfs/posix/pvfs_mkdir.c | 4 ++-- source4/ntvfs/posix/pvfs_rename.c | 10 +++++----- source4/ntvfs/posix/pvfs_search.c | 11 +++++++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 5 files changed, 24 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 590c9c18b5..e38f2c9ecb 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -452,9 +452,10 @@ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, /* access check for creating a new file/directory - no access mask supplied */ -NTSTATUS pvfs_access_check_create_nomask(struct pvfs_state *pvfs, - struct smbsrv_request *req, - struct pvfs_filename *name) +NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + uint32_t access_mask) { struct pvfs_filename *parent; NTSTATUS status; @@ -464,7 +465,7 @@ NTSTATUS pvfs_access_check_create_nomask(struct pvfs_state *pvfs, return status; } - return pvfs_access_check_simple(pvfs, req, parent, SEC_DIR_ADD_FILE); + return pvfs_access_check_simple(pvfs, req, parent, access_mask); } diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 42b5109673..03bc16cdbe 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -44,7 +44,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_access_check_create_nomask(pvfs, req, name); + status = pvfs_access_check_parent(pvfs, req, name, SEC_DIR_ADD_FILE); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -114,7 +114,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_access_check_create_nomask(pvfs, req, name); + status = pvfs_access_check_parent(pvfs, req, name, SEC_DIR_ADD_FILE); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 91ad9aa3d9..b70f129888 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" - +#include "librpc/gen_ndr/ndr_security.h" /* resolve a wildcard rename pattern. This works on one component of the name @@ -281,7 +281,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_access_check_create_nomask(pvfs, req, name2); + status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -360,7 +360,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: - status = pvfs_access_check_create_nomask(pvfs, req, name2); + status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -370,7 +370,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, break; case RENAME_FLAG_HARD_LINK: - status = pvfs_access_check_create_nomask(pvfs, req, name2); + status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -380,7 +380,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, break; case RENAME_FLAG_COPY: - status = pvfs_access_check_create_nomask(pvfs, req, name2); + status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 34f5f2208e..2106758784 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -24,6 +24,7 @@ #include "vfs_posix.h" #include "system/time.h" #include "system/filesys.h" +#include "librpc/gen_ndr/ndr_security.h" /* the state of a search started with pvfs_search_first() */ @@ -325,6 +326,11 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, return STATUS_NO_MORE_FILES; } + status = pvfs_access_check_parent(pvfs, req, name, SEC_DIR_TRAVERSE | SEC_DIR_LIST); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* we initially make search a child of the request, then if we need to keep it long term we steal it for the private structure */ @@ -461,6 +467,11 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_SUCH_FILE; } + status = pvfs_access_check_parent(pvfs, req, name, SEC_DIR_TRAVERSE | SEC_DIR_LIST); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* we initially make search a child of the request, then if we need to keep it long term we steal it for the private structure */ diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 8c4d016ccc..9934388461 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -139,7 +139,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } } - status = pvfs_access_check_create_nomask(pvfs, req, name2); + status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 91e9cf6d1a53cc63410e1535907a2ad015e80c82 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Jan 2005 14:32:15 +0000 Subject: r4684: the smbsrv code should not know about rpc stuff just vfs_ipc metze (This used to be commit f85ebd1e8e19f5ff271dd7d79190fea16d6a98c4) --- source4/ntvfs/ipc/vfs_ipc.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2f482bb5e4..2a19de1ec0 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -38,6 +38,8 @@ struct ipc_private { struct idr_context *idtree_fnum; + struct dcesrv_context *dcesrv; + /* a list of open pipes */ struct pipe_state { struct pipe_state *next, *prev; @@ -73,6 +75,7 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) { + NTSTATUS status; struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; @@ -80,18 +83,19 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, tcon->dev_type = talloc_strdup(tcon, "IPC"); /* prepare the private state for this connection */ - private = talloc_p(tcon, struct ipc_private); - if (!private) { - return NT_STATUS_NO_MEMORY; - } + private = talloc(tcon, struct ipc_private); + NT_STATUS_HAVE_NO_MEMORY(private); + ntvfs->private_data = private; private->pipe_list = NULL; private->idtree_fnum = idr_init(private); - if (private->idtree_fnum == NULL) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum); + + /* setup the DCERPC server subsystem */ + status = dcesrv_init_context(private, &private->dcesrv); + NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; } @@ -226,7 +230,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, session_info = req->session->session_info; } - status = dcesrv_endpoint_search_connect(req->smb_conn->dcesrv, + status = dcesrv_endpoint_search_connect(private->dcesrv, &ep_description, session_info, &p->dce_conn); -- cgit From fae215266b6711b24f4893653b146751885e4e5f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Jan 2005 16:53:02 +0000 Subject: r4690: - add support for async rpc server replies the backend should check for (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_MAY_ASYNC) then it's allowed to reply async then the backend should mark that call as async with dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; later it has to manualy set r->out.result and then send the reply by calling status = dcesrv_reply(p->dce_call); NOTE: that ncacn_np doesn't support async replies yet - implement an async version of echo_TestSleep - reenable the echo_TestSleep torture test (this need to be more strict when we have support for async ncacn_np) metze (This used to be commit f0a0dbeb25b034b1333078ca085999359f5f6209) --- source4/ntvfs/ipc/vfs_ipc.c | 49 ++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 29 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2a19de1ec0..402d1ead64 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -3,7 +3,7 @@ default IPC$ NTVFS backend Copyright (C) Andrew Tridgell 2003 - Copyright (C) Stefan (metze) Metzmacher 2004 + Copyright (C) Stefan (metze) Metzmacher 2004-2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -94,7 +94,7 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum); /* setup the DCERPC server subsystem */ - status = dcesrv_init_context(private, &private->dcesrv); + status = dcesrv_init_ipc_context(private, &private->dcesrv); NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; @@ -106,13 +106,6 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, static NTSTATUS ipc_disconnect(struct ntvfs_module_context *ntvfs, struct smbsrv_tcon *tcon) { - struct ipc_private *private = ntvfs->private_data; - - /* close any pipes that are open. Discard any unread data */ - while (private->pipe_list) { - talloc_free(private->pipe_list); - } - return NT_STATUS_OK; } @@ -171,7 +164,6 @@ static int ipc_fd_destructor(void *ptr) struct pipe_state *p = ptr; idr_remove(p->private->idtree_fnum, p->fnum); DLIST_REMOVE(p->private->pipe_list, p); - talloc_free(p->dce_conn); return 0; } @@ -186,21 +178,21 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, struct pipe_state *p; NTSTATUS status; struct dcerpc_binding ep_description; - struct auth_session_info *session_info = NULL; struct ipc_private *private = ntvfs->private_data; int fnum; + struct server_connection *srv_conn; - p = talloc_p(req, struct pipe_state); - if (!p) { - return NT_STATUS_NO_MEMORY; + if (!req->session || !req->session->session_info) { + return NT_STATUS_ACCESS_DENIED; } + p = talloc(req, struct pipe_state); + NT_STATUS_HAVE_NO_MEMORY(p); + while (fname[0] == '\\') fname++; p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); - if (!p->pipe_name) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(p->pipe_name); fnum = idr_get_new_above(private->idtree_fnum, p, IPC_BASE_FNUM, UINT16_MAX); if (fnum == -1) { @@ -215,24 +207,23 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, endpoint. At this stage the pipe isn't bound, so we don't know what interface the user actually wants, just that they want one of the interfaces attached to this pipe endpoint. - - TODO: note that we aren't passing any credentials here. We - will need to do that once the credentials infrastructure is - finalised for Samba4 */ ep_description.transport = NCACN_NP; ep_description.endpoint = p->pipe_name; - /* tell the RPC layer the session_info */ - if (req->session) { - /* The session info is refcount-increased in the - dcesrv_endpoint_search_connect() function */ - session_info = req->session->session_info; - } + /* TOTO: pass in full server_connection in here */ + srv_conn = talloc_zero(p, struct server_connection); + NT_STATUS_HAVE_NO_MEMORY(srv_conn); + srv_conn->event.ctx = talloc_reference(srv_conn, req->smb_conn->connection->event.ctx); - status = dcesrv_endpoint_search_connect(private->dcesrv, + /* The session info is refcount-increased in the + * dcesrv_endpoint_search_connect() function + */ + status = dcesrv_endpoint_search_connect(private->dcesrv, + p, &ep_description, - session_info, + req->session->session_info, + srv_conn, &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { idr_remove(private->idtree_fnum, p->fnum); -- cgit From 592fce7fb149ca5e82b14d9c8f13a4da1babe2b7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Jan 2005 18:49:10 +0000 Subject: r4726: - use the name tcon and tid instead of conn and cnum - make use of talloc destructors metze (This used to be commit 8308da6ce4a95f8c10e22949ef00e9e64f2dbb85) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 736aa3652f..2a76d245ac 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -88,7 +88,7 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, if (!smbcli_transport_process(private->transport)) { /* the connection to our server is dead */ - close_cnum(tcon); + talloc_free(tcon); } } -- cgit From 9327ec51d11855ec0ceac3ce1f4e0a75c8b57081 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 14 Jan 2005 01:32:56 +0000 Subject: r4728: split up server_services into: - stream_socket services the smb, ldap and rpc service which sets up a srtam socket end then waits for connections and - task services which this you can create a seperate task that do something (this is also going through the process_model subsystem so with -M standard a new process for this created with -M thread a new thread ... I'll add datagram services later when we whave support for datagram sockets in lib/socket/ see the next commit as an example for service_task's metze (This used to be commit d5fa02746c6569b09b6e05785642da2fad3ba3e0) --- source4/ntvfs/posix/pvfs_wait.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 479d339592..4b757e0be1 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -134,7 +134,7 @@ static int pvfs_wait_destructor(void *ptr) pwait->private = private; pwait->handler = fn; - pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging_ctx; + pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging.ctx; pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; pwait->req = talloc_reference(pwait, req); diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e5bdc3faae..0b642adb01 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -130,16 +130,16 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = pvfs; pvfs->brl_context = brl_init(pvfs, - pvfs->tcon->smb_conn->connection->server_id, + pvfs->tcon->smb_conn->connection->connection.id, pvfs->tcon->service, - pvfs->tcon->smb_conn->connection->messaging_ctx); + pvfs->tcon->smb_conn->connection->messaging.ctx); if (pvfs->brl_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } pvfs->odb_context = odb_init(pvfs, - pvfs->tcon->smb_conn->connection->server_id, - pvfs->tcon->smb_conn->connection->messaging_ctx); + pvfs->tcon->smb_conn->connection->connection.id, + pvfs->tcon->smb_conn->connection->messaging.ctx); if (pvfs->odb_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From e89fd49df7e63dcf37ee1aa7e2f50965851725c9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 15 Jan 2005 10:38:12 +0000 Subject: r4757: added the ability of the clisocket level of libcli to handle async socket connections. This was complicated by a few factors: - it meant moving the event context from clitransport to clisocket, so lots of structures changed - we need to asynchronously handle connection to lists of port numbers, not just one port number. The code internally tries each port in the list in turn, without ever blocking - the man page on how connect() is supposed to work asynchronously doesn't work in practice (now why doesn't this surprise me?). The getsockopt() for SOL_ERROR is supposed to retrieve the error, but in fact the next (unrelated) connect() call on the same socket also gets an error, though not the right error. To work around this I need to tear down the whole socket between each attempted port. I hate posix. Note that clisocket.c still does a blocking name resolution call in smbcli_sock_connect_byname(). That will be fixed when we add the async NBT resolution code. Also note that I arranged things so that every SMB connection is now async internally, so using plain smbclient or smbtorture tests all the async features of this new code. (This used to be commit 468f8ebbfdbdf37c757fdc4863626aa9946a8870) --- source4/ntvfs/cifs/vfs_cifs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2a76d245ac..1a5a5ac042 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -152,12 +152,12 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, smbcli_oplock_handler(private->transport, oplock_handler, private); smbcli_transport_idle_handler(private->transport, idle_func, 50000, private); - private->transport->event.fde->handler = cifs_socket_handler; - private->transport->event.fde->private = private; + private->transport->socket->event.fde->handler = cifs_socket_handler; + private->transport->socket->event.fde->private = private; - private->transport->event.ctx = event_context_merge(tcon->smb_conn->connection->event.ctx, - private->transport->event.ctx); - talloc_reference(private, private->transport->event.ctx); + private->transport->socket->event.ctx = event_context_merge(tcon->smb_conn->connection->event.ctx, + private->transport->socket->event.ctx); + talloc_reference(private, private->transport->socket->event.ctx); private->map_generic = lp_parm_bool(req->tcon->service, "cifs", "mapgeneric", False); -- cgit From 4ce2cf2199c88f2845bf3bf861407642d6cd04d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Jan 2005 06:56:13 +0000 Subject: r4887: removed a bogus cast (This used to be commit a034556faa5d15fee44a58be3aea8aee8ffae3c8) --- source4/ntvfs/posix/pvfs_xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index ca535db168..c930fcbd68 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -131,7 +131,7 @@ static NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, DATA_BLOB blob; NTSTATUS status; - status = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn); + status = ndr_push_struct_blob(&blob, mem_ctx, p, push_fn); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return status; -- cgit From 54eff1435dd69d489ae35834f17989f79011418e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 11:42:56 +0000 Subject: r4942: converted the cifs backend to not use event_context_merge(). Instead, is supplies the server event context during the connect. (This used to be commit 133e67bb1fa661b0e0d340091be4160f9af04fe3) --- source4/ntvfs/cifs/vfs_cifs.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 1a5a5ac042..cf6caebc76 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -28,6 +28,7 @@ #include "includes.h" #include "events.h" #include "libcli/raw/libcliraw.h" +#include "libcli/composite/composite.h" #include "smb_server/smb_server.h" /* this is stored in ntvfs_private */ @@ -96,12 +97,14 @@ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct smbsrv_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; NTSTATUS status; struct cvfs_private *private; const char *host, *user, *pass, *domain, *remote_share; + struct smb_composite_connect io; + struct smbcli_composite *creq; /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. @@ -121,7 +124,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - private = talloc_p(req->tcon, struct cvfs_private); + private = talloc(req->tcon, struct cvfs_private); if (!private) { return NT_STATUS_NO_MEMORY; } @@ -129,17 +132,22 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; - status = smbcli_tree_full_connection(private, - &private->tree, - "vfs_cifs", - host, - 0, - remote_share, "?????", - user, domain, - pass); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + /* connect to the server, using the smbd event context */ + io.in.dest_host = host; + io.in.port = 0; + io.in.called_name = host; + io.in.calling_name = "vfs_cifs"; + io.in.service = remote_share; + io.in.service_type = "?????"; + io.in.domain = domain; + io.in.user = user; + io.in.password = pass; + + creq = smb_composite_connect_send(&io, tcon->smb_conn->connection->event.ctx); + status = smb_composite_connect_recv(creq, private); + NT_STATUS_NOT_OK_RETURN(status); + + private->tree = io.out.tree; private->transport = private->tree->session->transport; SETUP_PID; @@ -155,9 +163,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, private->transport->socket->event.fde->handler = cifs_socket_handler; private->transport->socket->event.fde->private = private; - private->transport->socket->event.ctx = event_context_merge(tcon->smb_conn->connection->event.ctx, - private->transport->socket->event.ctx); - talloc_reference(private, private->transport->socket->event.ctx); private->map_generic = lp_parm_bool(req->tcon->service, "cifs", "mapgeneric", False); -- cgit From fd62df64188c0f992876c72fdda8a6da5dba3090 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 11:49:15 +0000 Subject: r4943: Smplified the events handling code a lot. The first source of complexity was that events didn't automatically cleanup themselves. This was because the events code was written before we had talloc destructors, so you needed to call event_remove_XX() to clean the event out of the event lists from every piece of code that used events. I have now added automatic event destructors, which in turn allowed me to simplify a lot of the calling code. The 2nd source of complexity was caused by the ref_count, which was needed to cope with event handlers destroying events while handling them, which meant the linked lists became invalid, so the ref_count ws used to mark events for later destruction. The new system is much simpler. I now have a ev->destruction_count, which is incremented in all event destructors. The event dispatch code checks for changes to this and handles it. (This used to be commit a3c7417cfeab429ffb22d5546b205818f531a7b4) --- source4/ntvfs/posix/pvfs_wait.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 4b757e0be1..e4175ca8cc 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -105,7 +105,6 @@ static int pvfs_wait_destructor(void *ptr) { struct pvfs_wait *pwait = ptr; messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); - event_remove_timed(pwait->ev, pwait->te); DLIST_REMOVE(pwait->pvfs->wait_list, pwait); return 0; } @@ -145,6 +144,7 @@ static int pvfs_wait_destructor(void *ptr) te.handler = pvfs_wait_timeout; te.private = pwait; pwait->te = event_add_timed(pwait->ev, &te); + talloc_steal(pwait, pwait->te); /* register with the messaging subsystem for this message type */ -- cgit From 6c14b0133dede38294a812be7f5f5bd5ec3d498b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Jan 2005 12:17:45 +0000 Subject: r4944: every event_add_*() caller was having to call talloc_steal() to take control of the event, so instead build that into the function. If you pass NULL as mem_ctx then it leaves it as a child of the events structure. (This used to be commit 7f981b9ed96f39027cbfd500f41e0c2be64cbb50) --- source4/ntvfs/posix/pvfs_wait.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index e4175ca8cc..da36ac2239 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -143,8 +143,7 @@ static int pvfs_wait_destructor(void *ptr) te.next_event = end_time; te.handler = pvfs_wait_timeout; te.private = pwait; - pwait->te = event_add_timed(pwait->ev, &te); - talloc_steal(pwait, pwait->te); + pwait->te = event_add_timed(pwait->ev, &te, pwait); /* register with the messaging subsystem for this message type */ -- cgit From bdbd32d3ff1848aacbc1d1784a99beb8f388c301 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Jan 2005 03:33:36 +0000 Subject: r4956: - moved the definition of the mangle context structure into a pvfs_shortname - made the mangle cache size configurable (This used to be commit 4adbd01812a53395f175bd6d8e402ad5451f7561) --- source4/ntvfs/posix/pvfs_shortname.c | 46 +++++++++++++++++++++++++++--------- source4/ntvfs/posix/vfs_posix.h | 25 -------------------- 2 files changed, 35 insertions(+), 36 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 9efd1cec85..98cd4a99f6 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -71,11 +71,6 @@ #define FLAG_POSSIBLE3 64 #define FLAG_POSSIBLE4 128 -/* by default have a max of 512 entries in the cache. */ -#ifndef MANGLE_CACHE_SIZE -#define MANGLE_CACHE_SIZE 512 -#endif - #define DEFAULT_MANGLE_PREFIX 4 #define MANGLE_BASECHARS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -87,6 +82,31 @@ static const char *reserved_names[] = "LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL }; +struct pvfs_mangle_context { + uint8_t char_flags[256]; + /* + this determines how many characters are used from the original + filename in the 8.3 mangled name. A larger value leads to a weaker + hash and more collisions. The largest possible value is 6. + */ + int mangle_prefix; + uint32_t mangle_modulus; + + /* we will use a very simple direct mapped prefix cache. The big + advantage of this cache structure is speed and low memory usage + + The cache is indexed by the low-order bits of the hash, and confirmed by + hashing the resulting cache entry to match the known hash + */ + uint32_t cache_size; + char **prefix_cache; + uint32_t *prefix_cache_hashes; + + /* this is used to reverse the base 36 mapping */ + unsigned char base_reverse[256]; +}; + + /* hash a string of the specified length. The string does not need to be null terminated @@ -105,7 +125,7 @@ static uint32_t mangle_hash(struct pvfs_mangle_context *ctx, static void cache_insert(struct pvfs_mangle_context *ctx, const char *prefix, int length, uint32_t hash) { - int i = hash % MANGLE_CACHE_SIZE; + int i = hash % ctx->cache_size; if (ctx->prefix_cache[i]) { talloc_free(ctx->prefix_cache[i]); @@ -120,7 +140,7 @@ static void cache_insert(struct pvfs_mangle_context *ctx, */ static const char *cache_lookup(struct pvfs_mangle_context *ctx, uint32_t hash) { - int i = hash % MANGLE_CACHE_SIZE; + int i = hash % ctx->cache_size; if (!ctx->prefix_cache[i] || hash != ctx->prefix_cache_hashes[i]) { @@ -592,17 +612,21 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) if (ctx == NULL) { return NT_STATUS_NO_MEMORY; } - ctx->prefix_cache = talloc_array_p(ctx, char *, MANGLE_CACHE_SIZE); + + /* by default have a max of 512 entries in the cache. */ + ctx->cache_size = lp_parm_int(-1, "mangle", "cachesize", 512); + + ctx->prefix_cache = talloc_array(ctx, char *, ctx->cache_size); if (ctx->prefix_cache == NULL) { return NT_STATUS_NO_MEMORY; } - ctx->prefix_cache_hashes = talloc_array_p(ctx, uint32_t, MANGLE_CACHE_SIZE); + ctx->prefix_cache_hashes = talloc_array(ctx, uint32_t, ctx->cache_size); if (ctx->prefix_cache_hashes == NULL) { return NT_STATUS_NO_MEMORY; } - memset(ctx->prefix_cache, 0, sizeof(char *)*MANGLE_CACHE_SIZE); - memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t)*MANGLE_CACHE_SIZE); + memset(ctx->prefix_cache, 0, sizeof(char *) * ctx->cache_size); + memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t) * ctx->cache_size); ctx->mangle_prefix = lp_parm_int(-1, "mangle", "prefix", -1); if (ctx->mangle_prefix < 0 || ctx->mangle_prefix > 6) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index f7bf19c3dc..28f1aab94f 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -164,31 +164,6 @@ struct pvfs_file { }; -struct pvfs_mangle_context { - uint8_t char_flags[256]; - /* - this determines how many characters are used from the original - filename in the 8.3 mangled name. A larger value leads to a weaker - hash and more collisions. The largest possible value is 6. - */ - int mangle_prefix; - uint32_t mangle_modulus; - - /* we will use a very simple direct mapped prefix cache. The big - advantage of this cache structure is speed and low memory usage - - The cache is indexed by the low-order bits of the hash, and confirmed by - hashing the resulting cache entry to match the known hash - */ - char **prefix_cache; - uint32_t *prefix_cache_hashes; - - /* this is used to reverse the base 36 mapping */ - unsigned char base_reverse[256]; -}; - - - /* flags to pvfs_resolve_name() */ #define PVFS_RESOLVE_WILDCARD (1<<0) #define PVFS_RESOLVE_STREAMS (1<<1) -- cgit From 6cec461c8c8e6faad93e6d2a24d8da705c4ae8a0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 25 Jan 2005 09:46:00 +0000 Subject: r4979: Return NT_STATUS_INVALID_SYSTEM_SERVICE for unimplemented RAP calls as this is what win2k3 does. (This used to be commit 145d7c03df477eca08cb81d221e3a1b60ccf8c7f) --- source4/ntvfs/ipc/ipc_rap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index eeea7e24f7..e985d81baa 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -417,7 +417,7 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) call->ndr_push_param->flags = RAPNDR_FLAGS; call->ndr_push_data->flags = RAPNDR_FLAGS; - result = NT_STATUS_NOT_IMPLEMENTED; + result = NT_STATUS_INVALID_SYSTEM_SERVICE; for (i=0; api_commands[i].name != NULL; i++) { if (api_commands[i].id == call->callno) { -- cgit From 051c7b5e0c5db64e3da783471663996d6568e13f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 25 Jan 2005 10:03:57 +0000 Subject: r4980: Copy RAP callno constants from Samba 3 and start to use them. (This used to be commit e32ade44858b869001d2990c788a7e34fb70b121) --- source4/ntvfs/ipc/ipc_rap.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index e985d81baa..aedb7acaef 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -374,16 +374,13 @@ static NTSTATUS api_Unsupported(struct smbsrv_request *req, return NT_STATUS_OK; } -#define RAP_NetShareEnum 0 -#define RAP_NetServerEnum2 104 - static const struct { const char *name; int id; NTSTATUS (*fn)(struct smbsrv_request *req, struct rap_call *call); } api_commands[] = { - {"NetShareEnum", RAP_NetShareEnum, _rap_netshareenum }, + {"NetShareEnum", RAP_WshareEnum, _rap_netshareenum }, {"NetServerEnum2", RAP_NetServerEnum2, _rap_netserverenum2 }, {NULL, -1, api_Unsupported} }; -- cgit From 759da3b915e2006d4c87b5ace47f399accd9ce91 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 07:08:20 +0000 Subject: r5037: got rid of all of the TALLOC_DEPRECATED stuff. My apologies for the large commit. I thought this was worthwhile to get done for consistency. (This used to be commit ec32b22ed5ec224f6324f5e069d15e92e38e15c0) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/common/brlock.c | 2 +- source4/ntvfs/common/opendb.c | 4 ++-- source4/ntvfs/common/sidmap.c | 2 +- source4/ntvfs/ipc/ipc_rap.c | 6 +++--- source4/ntvfs/ipc/rap_server.c | 2 +- source4/ntvfs/nbench/vfs_nbench.c | 2 +- source4/ntvfs/ntvfs_generic.c | 36 +++++++++++++++++----------------- source4/ntvfs/ntvfs_util.c | 2 +- source4/ntvfs/posix/pvfs_acl.c | 8 ++++---- source4/ntvfs/posix/pvfs_dirlist.c | 2 +- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 14 ++++++------- source4/ntvfs/posix/pvfs_qfileinfo.c | 8 ++++---- source4/ntvfs/posix/pvfs_resolve.c | 10 +++++----- source4/ntvfs/posix/pvfs_search.c | 6 +++--- source4/ntvfs/posix/pvfs_setfileinfo.c | 4 ++-- source4/ntvfs/posix/pvfs_shortname.c | 4 ++-- source4/ntvfs/posix/pvfs_streams.c | 12 ++++++------ source4/ntvfs/posix/pvfs_wait.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 2 +- source4/ntvfs/posix/xattr_tdb.c | 4 ++-- source4/ntvfs/simple/svfs_util.c | 4 ++-- source4/ntvfs/simple/vfs_simple.c | 8 ++++---- source4/ntvfs/unixuid/vfs_unixuid.c | 10 +++++----- 25 files changed, 79 insertions(+), 79 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index cf6caebc76..7ac687dd46 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -201,7 +201,7 @@ static void async_simple(struct smbcli_request *c_req) if (!c_req) return NT_STATUS_UNSUCCESSFUL; \ { \ struct async_info *async; \ - async = talloc_p(req, struct async_info); \ + async = talloc(req, struct async_info); \ if (!async) return NT_STATUS_NO_MEMORY; \ async->parms = io; \ async->req = req; \ diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 7b351f77b0..f51e3d0694 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -78,7 +78,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, char *path; struct brl_context *brl; - brl = talloc_p(mem_ctx, struct brl_context); + brl = talloc(mem_ctx, struct brl_context); if (brl == NULL) { return NULL; } diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 57beba8c68..0aa257073d 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -84,7 +84,7 @@ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, char *path; struct odb_context *odb; - odb = talloc_p(mem_ctx, struct odb_context); + odb = talloc(mem_ctx, struct odb_context); if (odb == NULL) { return NULL; } @@ -124,7 +124,7 @@ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, { struct odb_lock *lck; - lck = talloc_p(mem_ctx, struct odb_lock); + lck = talloc(mem_ctx, struct odb_lock); if (lck == NULL) { return NULL; } diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 3254330c2f..46e02b5da1 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -45,7 +45,7 @@ struct sidmap_context { struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx) { struct sidmap_context *sidmap; - sidmap = talloc_p(mem_ctx, struct sidmap_context); + sidmap = talloc(mem_ctx, struct sidmap_context); if (sidmap == NULL) { return NULL; } diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index aedb7acaef..a61dbcb852 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -77,7 +77,7 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, { struct rap_call *call; - call = talloc_p(mem_ctx, struct rap_call); + call = talloc(mem_ctx, struct rap_call); if (call == NULL) return NULL; @@ -92,7 +92,7 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, call->ndr_pull_data = ndr_pull_init_blob(&trans->in.data, mem_ctx); call->ndr_pull_data->flags = RAPNDR_FLAGS; - call->heap = talloc_p(mem_ctx, struct rap_string_heap); + call->heap = talloc(mem_ctx, struct rap_string_heap); if (call->heap == NULL) return NULL; @@ -179,7 +179,7 @@ static NTSTATUS rap_push_string(struct ndr_push *data_push, NDR_CHECK(ndr_push_uint16(data_push, heap->offset)); NDR_CHECK(ndr_push_uint16(data_push, 0)); - heap->strings = talloc_realloc_p(heap->mem_ctx, + heap->strings = talloc_realloc(heap->mem_ctx, heap->strings, const char *, heap->num_strings + 1); diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 4875592ad6..c69ba2d168 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -32,7 +32,7 @@ NTSTATUS rap_netshareenum(struct smbsrv_request *req, int i; r->out.status = 0; r->out.available = dcesrv_common_get_count_of_shares(req, NULL); - r->out.info = talloc_array_p(req, + r->out.info = talloc_array(req, union rap_shareenum_info, r->out.available); for (i=0;iout.available;i++) { diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 560f4a646b..a1f03da367 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -97,7 +97,7 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, NTSTATUS status; char *logname = NULL; - nprivates = talloc_p(req->tcon, struct nbench_private); + nprivates = talloc(req->tcon, struct nbench_private); if (!nprivates) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 051e92b19c..9b6c75e5c6 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -79,7 +79,7 @@ static NTSTATUS ntvfs_map_async_setup(struct smbsrv_request *req, second_stage_t fn) { struct ntvfs_map_async *m; - m = talloc_p(req, struct ntvfs_map_async); + m = talloc(req, struct ntvfs_map_async); if (m == NULL) { return NT_STATUS_NO_MEMORY; } @@ -217,7 +217,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; if (write_time != 0) { - sf = talloc_p(req, union smb_setfileinfo); + sf = talloc(req, union smb_setfileinfo); sf->generic.level = RAW_SFILEINFO_STANDARD; sf->generic.file.fnum = io2->generic.out.fnum; sf->standard.in.create_time = 0; @@ -227,7 +227,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, } if (set_size != 0) { - sf = talloc_p(req, union smb_setfileinfo); + sf = talloc(req, union smb_setfileinfo); sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; sf->generic.file.fnum = io2->generic.out.fnum; sf->end_of_file_info.in.size = set_size; @@ -351,7 +351,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, NTSTATUS status; union smb_open *io2; - io2 = talloc_zero_p(req, union smb_open); + io2 = talloc_zero(req, union smb_open); if (io2 == NULL) { return NT_STATUS_NO_MEMORY; } @@ -417,7 +417,7 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.file_attr = io->t2open.in.file_attrs; io2->generic.in.fname = io->t2open.in.fname; - io2->generic.in.ea_list = talloc_p(io2, struct smb_ea_list); + io2->generic.in.ea_list = talloc(io2, struct smb_ea_list); io2->generic.in.ea_list->num_eas = io->t2open.in.num_eas; io2->generic.in.ea_list->eas = io->t2open.in.eas; @@ -485,7 +485,7 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, NTSTATUS status; union smb_fsinfo *fs2; - fs2 = talloc_p(req, union smb_fsinfo); + fs2 = talloc(req, union smb_fsinfo); if (fs2 == NULL) { return NT_STATUS_NO_MEMORY; } @@ -714,7 +714,7 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info info->stream_info.out.num_streams = info2->generic.out.num_streams; if (info->stream_info.out.num_streams > 0) { info->stream_info.out.streams = - talloc_array_p(req, + talloc_array(req, struct stream_struct, info->stream_info.out.num_streams); if (!info->stream_info.out.streams) { @@ -753,7 +753,7 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info case RAW_FILEINFO_ALL_EAS: info->all_eas.out.num_eas = info2->generic.out.num_eas; if (info->all_eas.out.num_eas > 0) { - info->all_eas.out.eas = talloc_array_p(req, + info->all_eas.out.eas = talloc_array(req, struct ea_struct, info->all_eas.out.num_eas); if (!info->all_eas.out.eas) { @@ -840,7 +840,7 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf NTSTATUS status; union smb_fileinfo *info2; - info2 = talloc_p(req, union smb_fileinfo); + info2 = talloc(req, union smb_fileinfo); if (info2 == NULL) { return NT_STATUS_NO_MEMORY; } @@ -869,7 +869,7 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf NTSTATUS status; union smb_fileinfo *info2; - info2 = talloc_p(req, union smb_fileinfo); + info2 = talloc(req, union smb_fileinfo); if (info2 == NULL) { return NT_STATUS_NO_MEMORY; } @@ -902,12 +902,12 @@ NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck, union smb_lock *lck2; struct smb_lock_entry *locks; - lck2 = talloc_p(req, union smb_lock); + lck2 = talloc(req, union smb_lock); if (lck2 == NULL) { return NT_STATUS_NO_MEMORY; } - locks = talloc_array_p(lck2, struct smb_lock_entry, 1); + locks = talloc_array(lck2, struct smb_lock_entry, 1); if (locks == NULL) { return NT_STATUS_NO_MEMORY; } @@ -966,7 +966,7 @@ static NTSTATUS ntvfs_map_write_finish(struct smbsrv_request *req, case RAW_WRITE_WRITEUNLOCK: wr->writeunlock.out.nwritten = wr2->generic.out.nwritten; - lck = talloc_p(wr2, union smb_lock); + lck = talloc(wr2, union smb_lock); if (lck == NULL) { return NT_STATUS_NO_MEMORY; } @@ -988,7 +988,7 @@ static NTSTATUS ntvfs_map_write_finish(struct smbsrv_request *req, case RAW_WRITE_WRITECLOSE: wr->writeclose.out.nwritten = wr2->generic.out.nwritten; - cl = talloc_p(wr2, union smb_close); + cl = talloc(wr2, union smb_close); if (cl == NULL) { return NT_STATUS_NO_MEMORY; } @@ -1025,7 +1025,7 @@ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, union smb_write *wr2; NTSTATUS status; - wr2 = talloc_p(req, union smb_write); + wr2 = talloc(req, union smb_write); if (wr2 == NULL) { return NT_STATUS_NO_MEMORY; } @@ -1125,7 +1125,7 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, NTSTATUS status; uint_t state; - rd2 = talloc_p(req, union smb_read); + rd2 = talloc(req, union smb_read); if (rd2 == NULL) { return NT_STATUS_NO_MEMORY; } @@ -1168,7 +1168,7 @@ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, state = req->async_states->state; req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; - lck = talloc_p(rd2, union smb_lock); + lck = talloc(rd2, union smb_lock); if (lck == NULL) { status = NT_STATUS_NO_MEMORY; goto done; @@ -1206,7 +1206,7 @@ NTSTATUS ntvfs_map_close(struct smbsrv_request *req, union smb_close *cl, { union smb_close *cl2; - cl2 = talloc_p(req, union smb_close); + cl2 = talloc(req, union smb_close); if (cl2 == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 41e1b04d49..e360321882 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -33,7 +33,7 @@ NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, { struct ntvfs_async_state *async; - async = talloc_p(req, struct ntvfs_async_state); + async = talloc(req, struct ntvfs_async_state); if (!async) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index e38f2c9ecb..c2856ad292 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -195,7 +195,7 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, uid_t uid = -1; gid_t gid = -1; - acl = talloc_p(req, struct xattr_NTACL); + acl = talloc(req, struct xattr_NTACL); if (acl == NULL) { return NT_STATUS_NO_MEMORY; } @@ -289,7 +289,7 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, NTSTATUS status; struct security_descriptor *sd; - acl = talloc_p(req, struct xattr_NTACL); + acl = talloc(req, struct xattr_NTACL); if (acl == NULL) { return NT_STATUS_NO_MEMORY; } @@ -367,7 +367,7 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, NTSTATUS status; struct security_descriptor *sd; - acl = talloc_p(req, struct xattr_NTACL); + acl = talloc(req, struct xattr_NTACL); if (acl == NULL) { return NT_STATUS_NO_MEMORY; } @@ -595,7 +595,7 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, return status; } - acl = talloc_p(req, struct xattr_NTACL); + acl = talloc(req, struct xattr_NTACL); if (acl == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index c2e8f826a2..1b60f17462 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -97,7 +97,7 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, char *pattern; struct pvfs_dir *dir; - (*dirp) = talloc_zero_p(mem_ctx, struct pvfs_dir); + (*dirp) = talloc_zero(mem_ctx, struct pvfs_dir); if (*dirp == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 74ee48ba15..6ad654f505 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -296,7 +296,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, if (lck->lockx.in.timeout != 0 && (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - pending = talloc_p(f, struct pvfs_pending_lock); + pending = talloc(f, struct pvfs_pending_lock); if (pending == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index b34d75d24d..ae8841e7b5 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -180,12 +180,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_INVALID_PARAMETER; } - f = talloc_p(req, struct pvfs_file); + f = talloc(req, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; } - f->handle = talloc_p(f, struct pvfs_file_handle); + f->handle = talloc(f, struct pvfs_file_handle); if (f->handle == NULL) { return NT_STATUS_NO_MEMORY; } @@ -468,12 +468,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, flags = O_RDONLY; } - f = talloc_p(req, struct pvfs_file); + f = talloc(req, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; } - f->handle = talloc_p(f, struct pvfs_file_handle); + f->handle = talloc(f, struct pvfs_file_handle); if (f->handle == NULL) { return NT_STATUS_NO_MEMORY; } @@ -805,7 +805,7 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, } } - r = talloc_p(req, struct pvfs_open_retry); + r = talloc(req, struct pvfs_open_retry); if (r == NULL) { return NT_STATUS_NO_MEMORY; } @@ -962,12 +962,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } - f = talloc_p(req, struct pvfs_file); + f = talloc(req, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; } - f->handle = talloc_p(f, struct pvfs_file_handle); + f->handle = talloc(f, struct pvfs_file_handle); if (f->handle == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 463574c8cf..4b6afac00a 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -64,14 +64,14 @@ NTSTATUS pvfs_query_ea_list(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, { NTSTATUS status; int i; - struct xattr_DosEAs *ealist = talloc_p(mem_ctx, struct xattr_DosEAs); + struct xattr_DosEAs *ealist = talloc(mem_ctx, struct xattr_DosEAs); ZERO_STRUCTP(eas); status = pvfs_doseas_load(pvfs, name, fd, ealist); if (!NT_STATUS_IS_OK(status)) { return status; } - eas->eas = talloc_array_p(mem_ctx, struct ea_struct, num_names); + eas->eas = talloc_array(mem_ctx, struct ea_struct, num_names); if (eas->eas == NULL) { return NT_STATUS_NO_MEMORY; } @@ -101,14 +101,14 @@ static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, { NTSTATUS status; int i; - struct xattr_DosEAs *ealist = talloc_p(mem_ctx, struct xattr_DosEAs); + struct xattr_DosEAs *ealist = talloc(mem_ctx, struct xattr_DosEAs); ZERO_STRUCTP(eas); status = pvfs_doseas_load(pvfs, name, fd, ealist); if (!NT_STATUS_IS_OK(status)) { return status; } - eas->eas = talloc_array_p(mem_ctx, struct ea_struct, ealist->num_eas); + eas->eas = talloc_array(mem_ctx, struct ea_struct, ealist->num_eas); if (eas->eas == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index fc1576b955..fc899c5fbc 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -75,7 +75,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * } } - components = talloc_array_p(name, char *, num_components); + components = talloc_array(name, char *, num_components); p = name->full_name + strlen(pvfs->base_directory); *p++ = 0; @@ -345,7 +345,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t if (c == '\\') num_components++; } - components = talloc_array_p(s, char *, num_components+1); + components = talloc_array(s, char *, num_components+1); if (components == NULL) { talloc_free(s); return NT_STATUS_NO_MEMORY; @@ -450,7 +450,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, { NTSTATUS status; - *name = talloc_p(mem_ctx, struct pvfs_filename); + *name = talloc(mem_ctx, struct pvfs_filename); if (*name == NULL) { return NT_STATUS_NO_MEMORY; } @@ -511,7 +511,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, { NTSTATUS status; - *name = talloc_p(mem_ctx, struct pvfs_filename); + *name = talloc(mem_ctx, struct pvfs_filename); if (*name == NULL) { return NT_STATUS_NO_MEMORY; } @@ -591,7 +591,7 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, NTSTATUS status; char *p; - *name = talloc_p(mem_ctx, struct pvfs_filename); + *name = talloc(mem_ctx, struct pvfs_filename); if (*name == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 2106758784..76c1996ec7 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -244,7 +244,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, name = pvfs_list_next(dir, &search->current_index); if (name == NULL) break; - file = talloc_p(mem_ctx, union smb_search_data); + file = talloc(mem_ctx, union smb_search_data); if (!file) { return NT_STATUS_NO_MEMORY; } @@ -334,7 +334,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, /* we initially make search a child of the request, then if we need to keep it long term we steal it for the private structure */ - search = talloc_p(req, struct pvfs_search_state); + search = talloc(req, struct pvfs_search_state); if (!search) { return NT_STATUS_NO_MEMORY; } @@ -475,7 +475,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, /* we initially make search a child of the request, then if we need to keep it long term we steal it for the private structure */ - search = talloc_p(req, struct pvfs_search_state); + search = talloc(req, struct pvfs_search_state); if (!search) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 9934388461..9bc51d1ef4 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -174,7 +174,7 @@ NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, return NT_STATUS_NOT_SUPPORTED; } - ealist = talloc_p(name, struct xattr_DosEAs); + ealist = talloc(name, struct xattr_DosEAs); /* load the current list */ status = pvfs_doseas_load(pvfs, name, fd, ealist); @@ -194,7 +194,7 @@ NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, if (i==ealist->num_eas) { /* add it */ - ealist->eas = talloc_realloc_p(ealist, ealist->eas, + ealist->eas = talloc_realloc(ealist, ealist->eas, struct xattr_EA, ealist->num_eas+1); if (ealist->eas == NULL) { diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 98cd4a99f6..59a3d34640 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -497,7 +497,7 @@ static char *name_map(struct pvfs_mangle_context *ctx, /* find the hash for this prefix */ v = hash = mangle_hash(ctx, name, prefix_len); - new_name = talloc_array_p(ctx, char, 13); + new_name = talloc_array(ctx, char, 13); if (new_name == NULL) { return NULL; } @@ -608,7 +608,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) { struct pvfs_mangle_context *ctx; - ctx = talloc_p(pvfs, struct pvfs_mangle_context); + ctx = talloc(pvfs, struct pvfs_mangle_context); if (ctx == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index e92732b810..c9f2fcae29 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -38,7 +38,7 @@ NTSTATUS pvfs_stream_information(struct pvfs_state *pvfs, int i; NTSTATUS status; - streams = talloc_p(mem_ctx, struct xattr_DosStreams); + streams = talloc(mem_ctx, struct xattr_DosStreams); if (streams == NULL) { return NT_STATUS_NO_MEMORY; } @@ -49,7 +49,7 @@ NTSTATUS pvfs_stream_information(struct pvfs_state *pvfs, } info->num_streams = streams->num_streams+1; - info->streams = talloc_array_p(mem_ctx, struct stream_struct, info->num_streams); + info->streams = talloc_array(mem_ctx, struct stream_struct, info->num_streams); if (!info->streams) { return NT_STATUS_NO_MEMORY; } @@ -85,7 +85,7 @@ NTSTATUS pvfs_stream_info(struct pvfs_state *pvfs, struct pvfs_filename *name, i return NT_STATUS_OK; } - streams = talloc_p(name, struct xattr_DosStreams); + streams = talloc(name, struct xattr_DosStreams); if (streams == NULL) { return NT_STATUS_NO_MEMORY; } @@ -127,7 +127,7 @@ static NTSTATUS pvfs_stream_update_size(struct pvfs_state *pvfs, struct pvfs_fil int i; NTSTATUS status; - streams = talloc_p(name, struct xattr_DosStreams); + streams = talloc(name, struct xattr_DosStreams); if (streams == NULL) { return NT_STATUS_NO_MEMORY; } @@ -148,7 +148,7 @@ static NTSTATUS pvfs_stream_update_size(struct pvfs_state *pvfs, struct pvfs_fil if (i == streams->num_streams) { struct xattr_DosStream *s; - streams->streams = talloc_realloc_p(streams, streams->streams, + streams->streams = talloc_realloc(streams, streams->streams, struct xattr_DosStream, streams->num_streams+1); if (streams->streams == NULL) { @@ -204,7 +204,7 @@ NTSTATUS pvfs_stream_delete(struct pvfs_state *pvfs, return status; } - streams = talloc_p(name, struct xattr_DosStreams); + streams = talloc(name, struct xattr_DosStreams); if (streams == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index da36ac2239..c8d696f0fc 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -126,7 +126,7 @@ static int pvfs_wait_destructor(void *ptr) struct timed_event te; struct pvfs_wait *pwait; - pwait = talloc_p(pvfs, struct pvfs_wait); + pwait = talloc(pvfs, struct pvfs_wait); if (pwait == NULL) { return NULL; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 0b642adb01..314f9736a3 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -104,7 +104,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, char *base_directory; NTSTATUS status; - pvfs = talloc_zero_p(tcon, struct pvfs_state); + pvfs = talloc_zero(tcon, struct pvfs_state); if (pvfs == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index eebae38ab7..0184244aa8 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -59,7 +59,7 @@ static NTSTATUS xattr_tdb_add_list(struct pvfs_state *pvfs, const char *attr_nam len = strlen(attr_name) + 1; - blob.data = talloc_realloc_p(mem_ctx, blob.data, uint8_t, blob.length + len); + blob.data = talloc_realloc(mem_ctx, blob.data, uint8_t, blob.length + len); if (blob.data == NULL) { talloc_free(mem_ctx); return NT_STATUS_NO_MEMORY; @@ -94,7 +94,7 @@ static NTSTATUS get_ea_db_key(TALLOC_CTX *mem_ctx, } } - key->dptr = talloc_array_p(mem_ctx, char, 16 + len); + key->dptr = talloc_array(mem_ctx, char, 16 + len); if (key->dptr == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index cfe846a828..c44a527458 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -64,7 +64,7 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, uint_t allocated = 0; char *low_mask; - dir = talloc_p(mem_ctx, struct svfs_dir); + dir = talloc(mem_ctx, struct svfs_dir); if (!dir) { return NULL; } dir->count = 0; @@ -108,7 +108,7 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; - dir->files = talloc_realloc_p(dir, dir->files, struct svfs_dirfile, allocated); + dir->files = talloc_realloc(dir, dir->files, struct svfs_dirfile, allocated); if (!dir->files) { closedir(odir); return NULL; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 57d626465a..ace0ad896f 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -71,7 +71,7 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_tcon *tcon = req->tcon; struct svfs_private *private; - private = talloc_p(tcon, struct svfs_private); + private = talloc(tcon, struct svfs_private); private->next_search_handle = 0; private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service)); @@ -227,7 +227,7 @@ static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, info->generic.out.num_streams = 0; /* setup a single data stream */ info->generic.out.num_streams = 1 + (dir?dir->count:0); - info->generic.out.streams = talloc_array_p(req, + info->generic.out.streams = talloc_array(req, struct stream_struct, info->generic.out.num_streams); if (!info->generic.out.streams) { @@ -380,7 +380,7 @@ do_open: return map_nt_error_from_unix(errno); } - f = talloc_p(req->tcon, struct svfs_file); + f = talloc(req->tcon, struct svfs_file); f->fd = fd; f->name = talloc_strdup(req->tcon, unix_path); @@ -787,7 +787,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } - search = talloc_zero_p(private, struct search_state); + search = talloc_zero(private, struct search_state); if (!search) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index a1a5244453..9915660d9b 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -46,7 +46,7 @@ struct unix_sec_ctx { */ static struct unix_sec_ctx *save_unix_security(TALLOC_CTX *mem_ctx) { - struct unix_sec_ctx *sec = talloc_p(mem_ctx, struct unix_sec_ctx); + struct unix_sec_ctx *sec = talloc(mem_ctx, struct unix_sec_ctx); if (sec == NULL) { return NULL; } @@ -57,7 +57,7 @@ static struct unix_sec_ctx *save_unix_security(TALLOC_CTX *mem_ctx) talloc_free(sec); return NULL; } - sec->groups = talloc_array_p(sec, gid_t, sec->ngroups); + sec->groups = talloc_array(sec, gid_t, sec->ngroups); if (sec->groups == NULL) { talloc_free(sec); return NULL; @@ -101,7 +101,7 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, struct unixuid_private *private = ntvfs->private_data; int i; NTSTATUS status; - *sec = talloc_p(req, struct unix_sec_ctx); + *sec = talloc(req, struct unix_sec_ctx); /* we can't do unix security without a user and group */ if (token->num_sids < 2) { @@ -121,7 +121,7 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, } (*sec)->ngroups = token->num_sids - 2; - (*sec)->groups = talloc_array_p(*sec, gid_t, (*sec)->ngroups); + (*sec)->groups = talloc_array(*sec, gid_t, (*sec)->ngroups); if ((*sec)->groups == NULL) { return NT_STATUS_NO_MEMORY; } @@ -208,7 +208,7 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, struct unixuid_private *private; NTSTATUS status; - private = talloc_p(req->tcon, struct unixuid_private); + private = talloc(req->tcon, struct unixuid_private); if (!private) { return NT_STATUS_NO_MEMORY; } -- cgit From cc869963e8db57ac4048c3a4bc9f943582574c99 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jan 2005 23:22:12 +0000 Subject: r5050: make sure we translate the generic to the specific bits before doing a pvfs_access_check_unix(). Fixes a problem with the cifsfs filesystem (This used to be commit 8ebc61a2297176515d767ef0f67ec912293ab905) --- source4/ntvfs/posix/pvfs_acl.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index c2856ad292..258d4e5bcb 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -372,6 +372,10 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } + /* expand the generic access bits to file specific bits */ + *access_mask = pvfs_translate_mask(*access_mask); + *access_mask &= ~SEC_FILE_READ_ATTRIBUTE; + status = pvfs_acl_load(pvfs, name, -1, acl); if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { talloc_free(acl); @@ -389,11 +393,6 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, return NT_STATUS_INVALID_ACL; } - /* expand the generic access bits to file specific bits */ - *access_mask = pvfs_translate_mask(*access_mask); - - *access_mask &= ~SEC_FILE_READ_ATTRIBUTE; - /* check the acl against the required access mask */ status = sec_access_check(sd, token, *access_mask, access_mask); -- cgit From 55d4d36993293fee914a009f1d8f05810e347f2b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Jan 2005 00:54:57 +0000 Subject: r5102: This is a major simplification of the logic for controlling top level servers in smbd. The old code still contained a fairly bit of legacy from the time when smbd was only handling SMB connection. The new code gets rid of all of the smb_server specific code in smbd/, and creates a much simpler infrastructures for new server code. Major changes include: - simplified the process model code a lot. - got rid of the top level server and service structures completely. The top level context is now the event_context. This got rid of service.h and server.h completely (they were the most confusing parts of the old code) - added service_stream.[ch] for the helper functions that are specific to stream type services (services that handle streams, and use a logically separate process per connection) - got rid of the builtin idle_handler code in the service logic, as none of the servers were using it, and it can easily be handled by a server in future by adding its own timed_event to the event context. - fixed some major memory leaks in the rpc server code. - added registration of servers, rather than hard coding our list of possible servers. This allows for servers as modules in the future. - temporarily disabled the winbind code until I add the helper functions for that type of server - added error checking on service startup. If a configured server fails to startup then smbd doesn't startup. - cleaned up the command line handling in smbd, removing unused options (This used to be commit cf6a46c3cbde7b1eb1b86bd3882b953a2de3a42e) --- source4/ntvfs/cifs/vfs_cifs.c | 18 +----------------- source4/ntvfs/common/brlock.c | 6 +++--- source4/ntvfs/common/opendb.c | 6 +++--- source4/ntvfs/ipc/vfs_ipc.c | 7 +------ source4/ntvfs/posix/pvfs_wait.c | 5 +++-- source4/ntvfs/posix/vfs_posix.c | 9 +++++---- 6 files changed, 16 insertions(+), 35 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 7ac687dd46..13b11d8ba2 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -30,6 +30,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "smb_server/smb_server.h" +#include "smbd/service_stream.h" /* this is stored in ntvfs_private */ struct cvfs_private { @@ -48,22 +49,6 @@ struct async_info { #define SETUP_PID private->tree->session->pid = SVAL(req->in.hdr, HDR_PID) -/* - an idle function to cope with messages from the smbd client while - waiting for a reply from the server - this function won't be needed once all of the cifs backend - and the core of smbd is converted to use async calls -*/ -static void idle_func(struct smbcli_transport *transport, void *p_private) -{ - struct cvfs_private *private = p_private; - int fd = socket_get_fd(private->tcon->smb_conn->connection->socket); - - if (socket_pending(fd)) { - smbd_process_async(private->tcon->smb_conn); - } -} - /* a handler for oplock break events from the server - these need to be passed along to the client @@ -158,7 +143,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); - smbcli_transport_idle_handler(private->transport, idle_func, 50000, private); private->transport->socket->event.fde->handler = cifs_socket_handler; private->transport->socket->event.fde->private = private; diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index f51e3d0694..d521dc80d3 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -41,7 +41,7 @@ lock is the same as another lock */ struct lock_context { - servid_t server; + uint32_t server; uint16_t smbpid; uint16_t tid; }; @@ -60,7 +60,7 @@ struct lock_struct { struct brl_context { struct tdb_wrap *w; - servid_t server; + uint32_t server; uint16_t tid; struct messaging_context *messaging_ctx; struct lock_struct last_lock; @@ -72,7 +72,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, servid_t server, uint16_t tid, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, uint16_t tid, struct messaging_context *messaging_ctx) { char *path; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 0aa257073d..3c206528dd 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -44,7 +44,7 @@ struct odb_context { struct tdb_wrap *w; - servid_t server; + uint32_t server; struct messaging_context *messaging_ctx; }; @@ -53,7 +53,7 @@ struct odb_context { following form */ struct odb_entry { - servid_t server; + uint32_t server; void *file_handle; uint32_t stream_id; uint32_t share_access; @@ -78,7 +78,7 @@ struct odb_lock { talloc_free(). We need the messaging_ctx to allow for pending open notifications. */ -struct odb_context *odb_init(TALLOC_CTX *mem_ctx, servid_t server, +struct odb_context *odb_init(TALLOC_CTX *mem_ctx, uint32_t server, struct messaging_context *messaging_ctx) { char *path; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 402d1ead64..04a1a06db3 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -180,7 +180,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, struct dcerpc_binding ep_description; struct ipc_private *private = ntvfs->private_data; int fnum; - struct server_connection *srv_conn; + struct stream_connection *srv_conn = req->smb_conn->connection; if (!req->session || !req->session->session_info) { return NT_STATUS_ACCESS_DENIED; @@ -211,11 +211,6 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, ep_description.transport = NCACN_NP; ep_description.endpoint = p->pipe_name; - /* TOTO: pass in full server_connection in here */ - srv_conn = talloc_zero(p, struct server_connection); - NT_STATUS_HAVE_NO_MEMORY(srv_conn); - srv_conn->event.ctx = talloc_reference(srv_conn, req->smb_conn->connection->event.ctx); - /* The session info is refcount-increased in the * dcesrv_endpoint_search_connect() function */ diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index c8d696f0fc..276b1d4e9a 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -24,6 +24,7 @@ #include "events.h" #include "dlinklist.h" #include "vfs_posix.h" +#include "smbd/service_stream.h" /* the context for a single wait instance */ struct pvfs_wait { @@ -56,7 +57,7 @@ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, receive a completion message for a wait */ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uint32_t msg_type, - servid_t src, DATA_BLOB *data) + uint32_t src, DATA_BLOB *data) { struct pvfs_wait *pwait = private; struct smbsrv_request *req; @@ -133,7 +134,7 @@ static int pvfs_wait_destructor(void *ptr) pwait->private = private; pwait->handler = fn; - pwait->msg_ctx = pvfs->tcon->smb_conn->connection->messaging.ctx; + pwait->msg_ctx = pvfs->tcon->smb_conn->connection->msg_ctx; pwait->ev = req->tcon->smb_conn->connection->event.ctx; pwait->msg_type = msg_type; pwait->req = talloc_reference(pwait, req); diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 314f9736a3..0ed878c1f0 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -27,6 +27,7 @@ #include "includes.h" #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_security.h" +#include "smbd/service_stream.h" /* @@ -130,16 +131,16 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = pvfs; pvfs->brl_context = brl_init(pvfs, - pvfs->tcon->smb_conn->connection->connection.id, + pvfs->tcon->smb_conn->connection->server_id, pvfs->tcon->service, - pvfs->tcon->smb_conn->connection->messaging.ctx); + pvfs->tcon->smb_conn->connection->msg_ctx); if (pvfs->brl_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } pvfs->odb_context = odb_init(pvfs, - pvfs->tcon->smb_conn->connection->connection.id, - pvfs->tcon->smb_conn->connection->messaging.ctx); + pvfs->tcon->smb_conn->connection->server_id, + pvfs->tcon->smb_conn->connection->msg_ctx); if (pvfs->odb_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From 9a70f446fc4abc2bd1278772810c0e8132f4bea4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Jan 2005 08:30:44 +0000 Subject: r5126: the composite code is no longer client specific or smb specific, so rename the core structure to composite_context and the wait routine to composite_wait() (suggestion from metze) (This used to be commit cf11d05e35179c2c3e51c5ab370cd0a3fb15f24a) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 13b11d8ba2..c4ed9c172a 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -89,7 +89,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct cvfs_private *private; const char *host, *user, *pass, *domain, *remote_share; struct smb_composite_connect io; - struct smbcli_composite *creq; + struct composite_context *creq; /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. -- cgit From d8d3a5ffe3fb73d64869c133fe398efeb4e79d77 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 31 Jan 2005 16:06:21 +0000 Subject: r5137: fix types metze (This used to be commit add1c579375d08040f722946da31ee3862f9e7ac) --- source4/ntvfs/common/brlock.c | 2 +- source4/ntvfs/posix/pvfs_fileinfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d521dc80d3..d0385fbb0b 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -525,7 +525,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, NTSTATUS brl_locktest(struct brl_context *brl, DATA_BLOB *file_key, uint16_t fnum, - uint16 smbpid, + uint16_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) { diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index fc60aa6e89..027118e7d9 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -97,7 +97,7 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, /* return a set of unix file permissions for a new file or directory */ -mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32 attrib) +mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32_t attrib) { mode_t mode = S_IRUSR; -- cgit From 66170ef8b36b499aa5b44ef10c1bd362a50f2636 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 02:35:52 +0000 Subject: r5185: make all the events data structures private to events.c. This will make it possible to add optimisations to the events code such as keeping the next timed event in a sorted list, and using epoll for file descriptor events. I also removed the loop events code, as it wasn't being used anywhere, and changed timed events to always be one-shot (as adding a new timed event in the event handler is so easy to do if needed) (This used to be commit d7b4b6de51342a65bf46fce772d313f92f8d73d3) --- source4/ntvfs/cifs/vfs_cifs.c | 23 +++++++++++++++-------- source4/ntvfs/posix/pvfs_wait.c | 11 ++++------- 2 files changed, 19 insertions(+), 15 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c4ed9c172a..9d873722f9 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -65,14 +65,12 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin a handler for read events on a connection to a backend server */ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags) + struct timeval t, uint16_t flags, void *private) { - struct cvfs_private *private = fde->private; - struct smbsrv_tcon *tcon = private->tcon; + struct cvfs_private *cvfs = talloc_get_type(private, struct cvfs_private); + struct smbsrv_tcon *tcon = cvfs->tcon; - DEBUG(5,("cifs_socket_handler event on fd %d\n", fde->fd)); - - if (!smbcli_transport_process(private->transport)) { + if (!smbcli_transport_process(cvfs->transport)) { /* the connection to our server is dead */ talloc_free(tcon); } @@ -90,6 +88,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, const char *host, *user, *pass, *domain, *remote_share; struct smb_composite_connect io; struct composite_context *creq; + struct fd_event *fde; /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. @@ -144,8 +143,16 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); - private->transport->socket->event.fde->handler = cifs_socket_handler; - private->transport->socket->event.fde->private = private; + /* take over event handling for this socket */ + talloc_free(private->transport->socket->event.fde); + fde = event_add_fd(private->transport->socket->event.ctx, + private, + socket_get_fd(private->transport->socket->sock), + EVENT_FD_READ | EVENT_FD_WRITE, + cifs_socket_handler, + private); + private->transport->socket->event.fde = fde; + private->map_generic = lp_parm_bool(req->tcon->service, "cifs", "mapgeneric", False); diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 276b1d4e9a..7a8e6700c5 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -86,9 +86,9 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin receive a timeout on a message wait */ static void pvfs_wait_timeout(struct event_context *ev, - struct timed_event *te, struct timeval t) + struct timed_event *te, struct timeval t, void *private) { - struct pvfs_wait *pwait = te->private; + struct pvfs_wait *pwait = talloc_get_type(private, struct pvfs_wait); struct smbsrv_request *req = pwait->req; pwait->reason = PVFS_WAIT_TIMEOUT; @@ -124,7 +124,6 @@ static int pvfs_wait_destructor(void *ptr) void (*fn)(void *, enum pvfs_wait_notice), void *private) { - struct timed_event te; struct pvfs_wait *pwait; pwait = talloc(pvfs, struct pvfs_wait); @@ -141,10 +140,8 @@ static int pvfs_wait_destructor(void *ptr) pwait->pvfs = pvfs; /* setup a timer */ - te.next_event = end_time; - te.handler = pvfs_wait_timeout; - te.private = pwait; - pwait->te = event_add_timed(pwait->ev, &te, pwait); + pwait->te = event_add_timed(pwait->ev, pwait, end_time, + pvfs_wait_timeout, pwait); /* register with the messaging subsystem for this message type */ -- cgit From 0798d54b4fc28be881e2c4012663b1461bc85ba7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 11:25:52 +0000 Subject: r5195: most events don't need the time of the event, so save a gettimeofday() call and just use timeval_current() when its actually needed (This used to be commit 236403cc4dc2924ed6a898acae0bb44cc1688dcc) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9d873722f9..c64e4d3c84 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -65,7 +65,7 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin a handler for read events on a connection to a backend server */ static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, - struct timeval t, uint16_t flags, void *private) + uint16_t flags, void *private) { struct cvfs_private *cvfs = talloc_get_type(private, struct cvfs_private); struct smbsrv_tcon *tcon = cvfs->tcon; -- cgit From 131dc76d56df40b3511c47e54f15412a25b491f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 3 Feb 2005 11:56:03 +0000 Subject: r5197: moved events code to lib/events/ (suggestion from metze) (This used to be commit 7f54c8a339f36aa43c9340be70ab7f0067593ef2) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/posix/pvfs_wait.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c64e4d3c84..0bb47bab2a 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -26,7 +26,7 @@ */ #include "includes.h" -#include "events.h" +#include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" #include "smb_server/smb_server.h" diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 7a8e6700c5..e9c4a2f754 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -21,7 +21,7 @@ */ #include "includes.h" -#include "events.h" +#include "lib/events/events.h" #include "dlinklist.h" #include "vfs_posix.h" #include "smbd/service_stream.h" -- cgit From 632acd9bc7704ac3d326354808c3d12f4f0a9f8f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 9 Feb 2005 21:10:23 +0000 Subject: r5286: Some first steps in making the pidl code somewhat more generic for the various data types: Add ndr_flags argument to all ndr push/pull scalar functions (This used to be commit ab490c0c882bb13de190546c50a0631ecb8255ad) --- source4/ntvfs/ipc/ipc_rap.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index a61dbcb852..7ee7d26e35 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -109,7 +109,7 @@ static NTSTATUS rap_srv_pull_word(struct rap_call *call, uint16 *result) if (*call->paramdesc++ != 'W') return NT_STATUS_INVALID_PARAMETER; - return ndr_pull_uint16(call->ndr_pull_param, result); + return ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, result); } static NTSTATUS rap_srv_pull_dword(struct rap_call *call, uint32 *result) @@ -117,7 +117,7 @@ static NTSTATUS rap_srv_pull_dword(struct rap_call *call, uint32 *result) if (*call->paramdesc++ != 'D') return NT_STATUS_INVALID_PARAMETER; - return ndr_pull_uint32(call->ndr_pull_param, result); + return ndr_pull_uint32(call->ndr_pull_param, NDR_SCALARS, result); } static NTSTATUS rap_srv_pull_string(struct rap_call *call, const char **result) @@ -142,7 +142,7 @@ static NTSTATUS rap_srv_pull_bufsize(struct rap_call *call, uint16 *bufsize) if ( (*call->paramdesc++ != 'r') || (*call->paramdesc++ != 'L') ) return NT_STATUS_INVALID_PARAMETER; - result = ndr_pull_uint16(call->ndr_pull_param, bufsize); + result = ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, bufsize); if (!NT_STATUS_IS_OK(result)) return result; @@ -176,8 +176,8 @@ static NTSTATUS rap_push_string(struct ndr_push *data_push, heap->offset -= space; - NDR_CHECK(ndr_push_uint16(data_push, heap->offset)); - NDR_CHECK(ndr_push_uint16(data_push, 0)); + NDR_CHECK(ndr_push_uint16(data_push, NDR_SCALARS, heap->offset)); + NDR_CHECK(ndr_push_uint16(data_push, NDR_SCALARS, 0)); heap->strings = talloc_realloc(heap->mem_ctx, heap->strings, @@ -249,9 +249,9 @@ static NTSTATUS _rap_netshareenum(struct smbsrv_request *req, (const uint8_t *)r.out.info[i].info1.name, sizeof(r.out.info[i].info1.name))); NDR_OK(ndr_push_uint8(call->ndr_push_data, - r.out.info[i].info1.pad)); + NDR_SCALARS, r.out.info[i].info1.pad)); NDR_OK(ndr_push_uint16(call->ndr_push_data, - r.out.info[i].info1.type)); + NDR_SCALARS, r.out.info[i].info1.type)); NDR_OK(rap_push_string(call->ndr_push_data, call->heap, @@ -272,8 +272,8 @@ static NTSTATUS _rap_netshareenum(struct smbsrv_request *req, call->status = r.out.status; - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.count)); - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.available)); + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.count)); + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.available)); result = NT_STATUS_OK; @@ -332,11 +332,11 @@ static NTSTATUS _rap_netserverenum2(struct smbsrv_request *req, (const uint8_t *)r.out.info[i].info1.name, sizeof(r.out.info[i].info1.name))); NDR_OK(ndr_push_uint8(call->ndr_push_data, - r.out.info[i].info1.version_major)); + NDR_SCALARS, r.out.info[i].info1.version_major)); NDR_OK(ndr_push_uint8(call->ndr_push_data, - r.out.info[i].info1.version_minor)); + NDR_SCALARS, r.out.info[i].info1.version_minor)); NDR_OK(ndr_push_uint32(call->ndr_push_data, - r.out.info[i].info1.servertype)); + NDR_SCALARS, r.out.info[i].info1.servertype)); NDR_OK(rap_push_string(call->ndr_push_data, call->heap, @@ -357,8 +357,8 @@ static NTSTATUS _rap_netserverenum2(struct smbsrv_request *req, call->status = r.out.status; - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.count)); - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, r.out.available)); + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.count)); + NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.available)); result = NT_STATUS_OK; @@ -399,7 +399,7 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) if (call == NULL) return NT_STATUS_NO_MEMORY; - NDR_CHECK(ndr_pull_uint16(call->ndr_pull_param, &call->callno)); + NDR_CHECK(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &call->callno)); NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, &call->paramdesc)); NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, @@ -440,9 +440,9 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) final_param->flags = RAPNDR_FLAGS; final_data->flags = RAPNDR_FLAGS; - NDR_CHECK(ndr_push_uint16(final_param, call->status)); + NDR_CHECK(ndr_push_uint16(final_param, NDR_SCALARS, call->status)); NDR_CHECK(ndr_push_uint16(final_param, - call->heap->offset - result_data.length)); + NDR_SCALARS, call->heap->offset - result_data.length)); NDR_CHECK(ndr_push_bytes(final_param, result_param.data, result_param.length)); -- cgit From fedf0b0d91fdf2a6ae0ef47acd4047f662bd3374 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 03:48:43 +0000 Subject: r5296: - only include the tdb headers where they are needed - removed the u32 hack in events.c as I think this was only needed as tdb.h defines u32. Metze, can you check that this hack is indeed no longer needed on your suse system? (This used to be commit 6f79432fe656164d4770dbce114a30dda5e7bf9a) --- source4/ntvfs/common/brlock.c | 1 + source4/ntvfs/common/opendb.c | 1 + source4/ntvfs/posix/vfs_posix.c | 1 + source4/ntvfs/posix/xattr_tdb.c | 1 + 4 files changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d0385fbb0b..e88e9638a3 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -26,6 +26,7 @@ used. This allows us to provide the same semantics as NT */ #include "includes.h" +#include "lib/tdb/include/tdb.h" #include "messages.h" /* diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 3c206528dd..be6f356422 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -39,6 +39,7 @@ */ #include "includes.h" +#include "lib/tdb/include/tdb.h" #include "messages.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 0ed878c1f0..529ff7a98b 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -28,6 +28,7 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_security.h" #include "smbd/service_stream.h" +#include "lib/tdb/include/tdb.h" /* diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index 0184244aa8..29971ebeb5 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "lib/tdb/include/tdb.h" #define XATTR_LIST_ATTR ".xattr_list" -- cgit From e82aad1ce39a6b7a2e51b9e2cb494d74ec70e158 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 05:09:35 +0000 Subject: r5298: - got rid of pstring.h from includes.h. This at least makes it a bit less likely that anyone will use pstring for new code - got rid of winbind_client.h from includes.h. This one triggered a huge change, as winbind_client.h was including system/filesys.h and defining the old uint32 and uint16 types, as well as its own pstring and fstring. (This used to be commit 9db6c79e902ec538108d6b7d3324039aabe1704f) --- source4/ntvfs/common/brlock.c | 1 + source4/ntvfs/common/opendb.c | 1 + source4/ntvfs/common/sidmap.c | 2 ++ source4/ntvfs/ipc/ipc_rap.c | 14 +++++++------- source4/ntvfs/nbench/vfs_nbench.c | 1 + source4/ntvfs/posix/pvfs_acl.c | 1 - source4/ntvfs/posix/pvfs_open.c | 1 - source4/ntvfs/posix/pvfs_read.c | 1 - source4/ntvfs/posix/pvfs_search.c | 1 - source4/ntvfs/posix/pvfs_streams.c | 1 - source4/ntvfs/posix/vfs_posix.h | 1 + source4/ntvfs/posix/xattr_system.c | 1 - source4/ntvfs/simple/svfs_util.c | 1 + source4/ntvfs/simple/vfs_simple.c | 1 + source4/ntvfs/unixuid/vfs_unixuid.c | 2 ++ 15 files changed, 17 insertions(+), 13 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e88e9638a3..e693d57ca0 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -26,6 +26,7 @@ used. This allows us to provide the same semantics as NT */ #include "includes.h" +#include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messages.h" diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index be6f356422..231576b3d5 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -39,6 +39,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messages.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 46e02b5da1..8e040d5081 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -21,6 +21,8 @@ */ #include "includes.h" +#include "system/filesys.h" +#include "system/passwd.h" #include "librpc/gen_ndr/ndr_security.h" /* diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 7ee7d26e35..d93b67b715 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -53,14 +53,14 @@ static void rap_heap_restore(struct rap_string_heap *heap, struct rap_call { TALLOC_CTX *mem_ctx; - uint16 callno; + uint16_t callno; const char *paramdesc; const char *datadesc; - uint16 status; - uint16 convert; + uint16_t status; + uint16_t convert; - uint16 rcv_paramlen, rcv_datalen; + uint16_t rcv_paramlen, rcv_datalen; struct ndr_push *ndr_push_param; struct ndr_push *ndr_push_data; @@ -104,7 +104,7 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, return call; } -static NTSTATUS rap_srv_pull_word(struct rap_call *call, uint16 *result) +static NTSTATUS rap_srv_pull_word(struct rap_call *call, uint16_t *result) { if (*call->paramdesc++ != 'W') return NT_STATUS_INVALID_PARAMETER; @@ -112,7 +112,7 @@ static NTSTATUS rap_srv_pull_word(struct rap_call *call, uint16 *result) return ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, result); } -static NTSTATUS rap_srv_pull_dword(struct rap_call *call, uint32 *result) +static NTSTATUS rap_srv_pull_dword(struct rap_call *call, uint32_t *result) { if (*call->paramdesc++ != 'D') return NT_STATUS_INVALID_PARAMETER; @@ -135,7 +135,7 @@ static NTSTATUS rap_srv_pull_string(struct rap_call *call, const char **result) return ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, result); } -static NTSTATUS rap_srv_pull_bufsize(struct rap_call *call, uint16 *bufsize) +static NTSTATUS rap_srv_pull_bufsize(struct rap_call *call, uint16_t *bufsize) { NTSTATUS result; diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index a1f03da367..acfa6313d3 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -25,6 +25,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "smb_server/smb_server.h" /* this is stored in ntvfs_private */ diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 258d4e5bcb..7e4b07a941 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -22,7 +22,6 @@ #include "includes.h" #include "auth/auth.h" -#include "system/filesys.h" #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index ae8841e7b5..e68670f7cc 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -23,7 +23,6 @@ #include "includes.h" #include "vfs_posix.h" #include "system/time.h" -#include "system/filesys.h" #include "dlinklist.h" #include "messages.h" #include "librpc/gen_ndr/ndr_xattr.h" diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index db597d7097..fb656470b8 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -22,7 +22,6 @@ #include "includes.h" #include "vfs_posix.h" -#include "system/filesys.h" #include "librpc/gen_ndr/ndr_security.h" /* diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 76c1996ec7..69ca6ef997 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -23,7 +23,6 @@ #include "includes.h" #include "vfs_posix.h" #include "system/time.h" -#include "system/filesys.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index c9f2fcae29..2ee5034736 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "system/filesys.h" #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 28f1aab94f..f779936bf9 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -23,6 +23,7 @@ #ifndef _VFS_POSIX_H_ #define _VFS_POSIX_H_ +#include "system/filesys.h" #include "smb_server/smb_server.h" /* this is the private structure for the posix vfs backend. It is used diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index f19177f44c..3b8becf6fe 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "system/filesys.h" #include "vfs_posix.h" /* diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index c44a527458..3f6e205e71 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -24,6 +24,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "svfs.h" #include "system/time.h" #include "system/dir.h" diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index ace0ad896f..6f634efd53 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -27,6 +27,7 @@ */ #include "includes.h" +#include "system/filesys.h" #include "svfs.h" #include "system/time.h" #include "dlinklist.h" diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 9915660d9b..d724e7ceb2 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -22,6 +22,8 @@ */ #include "includes.h" +#include "system/filesys.h" +#include "system/passwd.h" #include "auth/auth.h" #include "libcli/security/security.h" #include "smb_server/smb_server.h" -- cgit From 35537c1255e9508b77fd9d9def1ac96e423bee46 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 06:36:30 +0000 Subject: r5302: fixed a compilation problem on solaris caused by the recent include changes (This used to be commit e7e015f79b10c353848a17f31c91a0593790a560) --- source4/ntvfs/simple/svfs_util.c | 10 ---------- source4/ntvfs/simple/vfs_simple.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 3f6e205e71..ac5cf69e9a 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -182,13 +182,3 @@ uint16_t svfs_unix_to_dos_attrib(mode_t mode) return ret; } -/* - build a file_id from a stat struct -*/ -uint64_t svfs_file_id(struct stat *st) -{ - uint64_t ret = st->st_ino; - ret <<= 32; - ret |= st->st_dev; - return ret; -} diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 6f634efd53..cebf7a5c32 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -172,6 +172,17 @@ static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + build a file_id from a stat struct +*/ +static uint64_t svfs_file_id(struct stat *st) +{ + uint64_t ret = st->st_ino; + ret <<= 32; + ret |= st->st_dev; + return ret; +} + /* approximately map a struct stat to a generic fileinfo struct */ -- cgit From a5bd1ccadab723c531963c219a1ac2b6b0c8b845 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:22:25 +0000 Subject: r5307: removed db_wrap.h from includes.h (This used to be commit 826baec7b348814a7bbdcdbec8c8526514f25da1) --- source4/ntvfs/common/brlock.c | 1 + source4/ntvfs/common/opendb.c | 1 + source4/ntvfs/posix/xattr_tdb.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e693d57ca0..5e404768e0 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -29,6 +29,7 @@ #include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messages.h" +#include "db_wrap.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 231576b3d5..4109992bc0 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -43,6 +43,7 @@ #include "lib/tdb/include/tdb.h" #include "messages.h" #include "librpc/gen_ndr/ndr_security.h" +#include "db_wrap.h" struct odb_context { struct tdb_wrap *w; diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index 29971ebeb5..f488569ca5 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -23,6 +23,7 @@ #include "includes.h" #include "vfs_posix.h" #include "lib/tdb/include/tdb.h" +#include "db_wrap.h" #define XATTR_LIST_ATTR ".xattr_list" -- cgit From a0e6f6c05b438765c8bbb6f8e7f7e6478dc67293 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2005 07:43:39 +0000 Subject: r5309: removed ads.h from includes.h (This used to be commit 196c45b834c39f293b9533cec5cfe5a77382d4e2) --- source4/ntvfs/common/sidmap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 8e040d5081..2a530c4a6b 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -24,6 +24,7 @@ #include "system/filesys.h" #include "system/passwd.h" #include "librpc/gen_ndr/ndr_security.h" +#include "ads.h" /* these are used for the fallback local uid/gid to sid mapping -- cgit From 90428a44a91d0a97769ba6c2d8459c35a9e96b12 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Feb 2005 11:33:33 +0000 Subject: r5500: ntvfs modules that are the final backend needs to set the dev and fs types this prevents the main smbsrv code from crashing when someone does a tree connect on a print share metze (This used to be commit e8b081d5d10ef617eaed88fd05990e7753a85b99) --- source4/ntvfs/print/vfs_print.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index c62357c949..c04cf76f33 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -34,6 +34,14 @@ static NTSTATUS print_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) { + struct smbsrv_tcon *tcon = req->tcon; + + tcon->fs_type = talloc_strdup(tcon, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(tcon->fs_type); + + tcon->dev_type = talloc_strdup(tcon, "LPT1:"); + NT_STATUS_HAVE_NO_MEMORY(tcon->dev_type); + return NT_STATUS_OK; } -- cgit From 218f289ed75e9e10feadb92fbbb41e69025ab010 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 Feb 2005 11:35:38 +0000 Subject: r5501: check the return of talloc with the NT_STATUS_HAVE_NO_MEMORY() macro... metze (This used to be commit 9ec6c0e97765e60ef195296f17d6a27b5d0dcca9) --- source4/ntvfs/ipc/vfs_ipc.c | 3 +++ source4/ntvfs/posix/vfs_posix.c | 24 +++++++++--------------- 2 files changed, 12 insertions(+), 15 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 04a1a06db3..abb4c51f65 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -80,7 +80,10 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, struct ipc_private *private; tcon->fs_type = talloc_strdup(tcon, "IPC"); + NT_STATUS_HAVE_NO_MEMORY(tcon->fs_type); + tcon->dev_type = talloc_strdup(tcon, "IPC"); + NT_STATUS_HAVE_NO_MEMORY(tcon->dev_type); /* prepare the private state for this connection */ private = talloc(tcon, struct ipc_private); diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 529ff7a98b..ec8db07d01 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -107,12 +107,11 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, NTSTATUS status; pvfs = talloc_zero(tcon, struct pvfs_state); - if (pvfs == NULL) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(pvfs); /* for simplicity of path construction, remove any trailing slash now */ base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); + NT_STATUS_HAVE_NO_MEMORY(base_directory); trim_string(base_directory, NULL, "/"); pvfs->tcon = tcon; @@ -127,7 +126,10 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, } tcon->fs_type = talloc_strdup(tcon, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(tcon->fs_type); + tcon->dev_type = talloc_strdup(tcon, "A:"); + NT_STATUS_HAVE_NO_MEMORY(tcon->dev_type); ntvfs->private_data = pvfs; @@ -153,20 +155,14 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, /* allocate the fnum id -> ptr tree */ pvfs->idtree_fnum = idr_init(pvfs); - if (pvfs->idtree_fnum == NULL) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(pvfs->idtree_fnum); /* allocate the search handle -> ptr tree */ pvfs->idtree_search = idr_init(pvfs); - if (pvfs->idtree_search == NULL) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(pvfs->idtree_search); status = pvfs_mangle_init(pvfs); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NT_STATUS_NOT_OK_RETURN(status); pvfs_setup_options(pvfs); @@ -200,9 +196,7 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs, /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NT_STATUS_NOT_OK_RETURN(status); if (!name->exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; -- cgit From a52a6f1c425335a4154fcd0d8f1c45f6e387ce53 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Mar 2005 22:50:13 +0000 Subject: r5666: winxp will use a NTTIME of -1 to mean "don't change" in setfileinfo basic_info. Add null_nttime() as the equivalent of the existing null_time() call for cheecking for valid NTTIME values (This used to be commit 439ce2efbf7d2ba9b17d6b4bfaf651e781140715) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 16 ++++++++-------- source4/ntvfs/posix/pvfs_xattr.c | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 9bc51d1ef4..31a60fac18 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -301,18 +301,18 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: - if (info->basic_info.in.create_time) { + if (!null_nttime(info->basic_info.in.create_time)) { newstats.dos.create_time = info->basic_info.in.create_time; } - if (info->basic_info.in.access_time) { + if (!null_nttime(info->basic_info.in.access_time)) { newstats.dos.access_time = info->basic_info.in.access_time; } - if (info->basic_info.in.write_time) { + if (!null_nttime(info->basic_info.in.write_time)) { newstats.dos.write_time = info->basic_info.in.write_time; newstats.dos.flags |= XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; h->sticky_write_time = True; } - if (info->basic_info.in.change_time) { + if (!null_nttime(info->basic_info.in.change_time)) { newstats.dos.change_time = info->basic_info.in.change_time; } if (info->basic_info.in.attrib != 0) { @@ -490,16 +490,16 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_BASIC_INFO: case RAW_SFILEINFO_BASIC_INFORMATION: - if (info->basic_info.in.create_time) { + if (!null_nttime(info->basic_info.in.create_time)) { newstats.dos.create_time = info->basic_info.in.create_time; } - if (info->basic_info.in.access_time) { + if (!null_nttime(info->basic_info.in.access_time)) { newstats.dos.access_time = info->basic_info.in.access_time; } - if (info->basic_info.in.write_time) { + if (!null_nttime(info->basic_info.in.write_time)) { newstats.dos.write_time = info->basic_info.in.write_time; } - if (info->basic_info.in.change_time) { + if (!null_nttime(info->basic_info.in.change_time)) { newstats.dos.change_time = info->basic_info.in.change_time; } if (info->basic_info.in.attrib != 0) { diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index c930fcbd68..c2af2e10bd 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -190,10 +190,10 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name name->dos.alloc_size = pvfs_round_alloc_size(pvfs, info1->alloc_size); } - if (info1->create_time != 0) { + if (!null_nttime(info1->create_time)) { name->dos.create_time = info1->create_time; } - if (info1->change_time != 0) { + if (!null_nttime(info1->change_time)) { name->dos.change_time = info1->change_time; } name->dos.flags = 0; @@ -207,10 +207,10 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name name->dos.alloc_size = pvfs_round_alloc_size(pvfs, info2->alloc_size); } - if (info2->create_time != 0) { + if (!null_nttime(info2->create_time)) { name->dos.create_time = info2->create_time; } - if (info2->change_time != 0) { + if (!null_nttime(info2->change_time)) { name->dos.change_time = info2->change_time; } name->dos.flags = info2->flags; -- cgit From df643022136a4b229aca817f5b57f7302a97f852 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Mar 2005 08:34:43 +0000 Subject: r5902: A rather large change... I wanted to add a simple 'workstation' argument to the DCERPC authenticated binding calls, but this patch kind of grew from there. With SCHANNEL, the 'workstation' name (the netbios name of the client) matters, as this is what ties the session between the NETLOGON ops and the SCHANNEL bind. This changes a lot of files, and these will again be changed when jelmer does the credentials work. I also correct some schannel IDL to distinguish between workstation names and account names. The distinction matters for domain trust accounts. Issues in handling this (issues with lifetime of talloc pointers) caused me to change the 'creds_CredentialsState' and 'struct dcerpc_binding' pointers to always be talloc()ed pointers. In the schannel DB, we now store both the domain and computername, and query on both. This should ensure we fault correctly when the domain is specified incorrectly in the SCHANNEL bind. In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out, where the comment claimed we re-used a connection, but in fact we made a new connection. This was achived by breaking apart some of the dcerpc_secondary_connection() logic. The addition of workstation handling was also propogated to NTLMSSP and GENSEC, for completeness. The RPC-SAMSYNC test has been cleaned up a little, using a loop over usernames/passwords rather than manually expanded tests. This will be expanded further (the code in #if 0 in this patch) to use a newly created user account for testing. In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO server, caused by the removal of [ref] and the assoicated pointer from the IDL. This has been re-added, until the underlying pidl issues are solved. (This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9) --- source4/ntvfs/ipc/vfs_ipc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index abb4c51f65..68c59b7502 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -180,7 +180,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, { struct pipe_state *p; NTSTATUS status; - struct dcerpc_binding ep_description; + struct dcerpc_binding *ep_description; struct ipc_private *private = ntvfs->private_data; int fnum; struct stream_connection *srv_conn = req->smb_conn->connection; @@ -192,6 +192,9 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p = talloc(req, struct pipe_state); NT_STATUS_HAVE_NO_MEMORY(p); + ep_description = talloc(req, struct dcerpc_binding); + NT_STATUS_HAVE_NO_MEMORY(ep_description); + while (fname[0] == '\\') fname++; p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); @@ -211,15 +214,15 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, know what interface the user actually wants, just that they want one of the interfaces attached to this pipe endpoint. */ - ep_description.transport = NCACN_NP; - ep_description.endpoint = p->pipe_name; + ep_description->transport = NCACN_NP; + ep_description->endpoint = talloc_reference(ep_description, p->pipe_name); /* The session info is refcount-increased in the * dcesrv_endpoint_search_connect() function */ status = dcesrv_endpoint_search_connect(private->dcesrv, p, - &ep_description, + ep_description, req->session->session_info, srv_conn, &p->dce_conn); -- cgit From 79f6bcd5ae1711075ce0e75392ce83a72766698e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Mar 2005 01:30:43 +0000 Subject: r5988: Fix the -P option (use machine account credentials) to use the Samba4 secrets system, and not the old system from Samba3. This allowed the code from auth_domain to be shared - we now only lookup the secrets.ldb in lib/credentials.c. In order to link the resultant binary, samdb_search() has been moved from deep inside rpc_server into lib/gendb.c, along with the existing gendb_search_v(). The vast majority of this patch is the simple rename that followed, (Depending on the whole SAMDB for just this function seemed pointless, and brought in futher dependencies, such as smbencrypt.c). Andrew Bartlett (This used to be commit e13c671619bd290a8b3cae8555cb281a9a185ee0) --- source4/ntvfs/common/sidmap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 2a530c4a6b..a39ee2f0eb 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -102,7 +102,7 @@ static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap, int ret; struct ldb_message **res; - ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "(&(objectClass=domain)(name=%s))", lp_workgroup()); if (ret != 1) { talloc_free(ctx); @@ -148,7 +148,7 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, return NT_STATUS_NO_MEMORY; } - ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); if (ret != 1) { goto allocated_sid; @@ -247,7 +247,7 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, return NT_STATUS_NO_MEMORY; } - ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "objectSid=%s", sidstr); if (ret != 1) { goto allocated_sid; @@ -360,7 +360,7 @@ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, given uid */ - ret = samdb_search(sidmap->samctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "unixID=%u", (unsigned int)uid); for (i=0;isamctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "(|(unixName=%s)(sAMAccountName=%s))", pwd->pw_name, pwd->pw_name); for (i=0;isamctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "unixID=%u", (unsigned int)gid); for (i=0;isamctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "(|(unixName=%s)(sAMAccountName=%s))", grp->gr_name, grp->gr_name); for (i=0;i Date: Thu, 24 Mar 2005 04:14:06 +0000 Subject: r6028: A MAJOR update to intergrate the new credentails system fully with GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'. GENSEC now no longer has it's own handling of 'set username' etc, instead it uses cli_credentials calls. In order to link the credentails code right though Samba, a lot of interfaces have changed to remove 'username, domain, password' arguments, and these have been replaced with a single 'struct cli_credentials'. In the session setup code, a new parameter 'workgroup' contains the client/server current workgroup, which seems unrelated to the authentication exchange (it was being filled in from the auth info). This allows in particular kerberos to only call back for passwords when it actually needs to perform the kinit. The kerberos code has been modified not to use the SPNEGO provided 'principal name' (in the mechListMIC), but to instead use the name the host was connected to as. This better matches Microsoft behaviour, is more secure and allows better use of standard kerberos functions. To achieve this, I made changes to our socket code so that the hostname (before name resolution) is now recorded on the socket. In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now in libcli/auth/schannel.c, and it looks much more like a standard GENSEC module. The actual sign/seal code moved to libcli/auth/schannel_sign.c in a previous commit. The schannel credentails structure is now merged with the rest of the credentails, as many of the values (username, workstation, domain) where already present there. This makes handling this in a generic manner much easier, as there is no longer a custom entry-point. The auth_domain module continues to be developed, but is now just as functional as auth_winbind. The changes here are consequential to the schannel changes. The only removed function at this point is the RPC-LOGIN test (simulating the load of a WinXP login), which needs much more work to clean it up (it contains copies of too much code from all over the torture suite, and I havn't been able to penetrate its 'structure'). Andrew Bartlett (This used to be commit 2301a4b38a21aa60917973451687063d83d18d66) --- source4/ntvfs/cifs/vfs_cifs.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 0bb47bab2a..e283e12f24 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -90,6 +90,8 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct composite_context *creq; struct fd_event *fde; + struct cli_credentials *credentials; + /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. @@ -116,16 +118,20 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; + credentials = cli_credentials_init(private); + cli_credentials_set_username(credentials, user, CRED_SPECIFIED); + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); + cli_credentials_set_workstation(credentials, "vfs_cifs", CRED_SPECIFIED); + /* connect to the server, using the smbd event context */ io.in.dest_host = host; io.in.port = 0; io.in.called_name = host; - io.in.calling_name = "vfs_cifs"; + io.in.credentials = credentials; + io.in.workgroup = lp_workgroup(); io.in.service = remote_share; io.in.service_type = "?????"; - io.in.domain = domain; - io.in.user = user; - io.in.password = pass; creq = smb_composite_connect_send(&io, tcon->smb_conn->connection->event.ctx); status = smb_composite_connect_recv(creq, private); -- cgit From 66a3750b142cbf54bfb7318ac4e1831f3d491793 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 5 Apr 2005 19:53:07 +0000 Subject: r6219: This change allows us to fall back to authenticating without DCERPC_SCHANNEL_128 if we fail. Thus, it allows us to work with Windows NT DCs ... (This used to be commit 3034b226705c4736d57c9bf4e9470c4d44c72e8e) --- source4/ntvfs/posix/pvfs_search.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 69ca6ef997..965e9ac266 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -266,7 +266,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, talloc_free(file); } - pvfs_list_hibernate(dir); + /*pvfs_list_hibernate(dir);*/ return NT_STATUS_OK; } -- cgit From c46c6e23ba7b962e20f49eeff3c3842ce905ec4a Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 6 Apr 2005 23:22:52 +0000 Subject: r6229: Back out these changes ... (This used to be commit 321fbae51267153102e47845736f2c3a5abfe0be) --- source4/ntvfs/posix/pvfs_search.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 965e9ac266..69ca6ef997 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -266,7 +266,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, talloc_free(file); } - /*pvfs_list_hibernate(dir);*/ + pvfs_list_hibernate(dir); return NT_STATUS_OK; } -- cgit From d9c15b0f280621fca844c0e8482b5e95f4ad2d11 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Apr 2005 13:19:40 +0000 Subject: r6342: fixed a bad union assumption that caused ACLs to fail on 64 bit machines Thanks to lars and agruen for finding this (This used to be commit 2acc06918574b1178eecf3d61026f84f85bb40e1) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 7e4b07a941..33756bc8bc 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -309,7 +309,7 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, return NT_STATUS_INVALID_ACL; } - normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags); + normalise_sd_flags(sd, info->query_secdesc.secinfo_flags); info->query_secdesc.out.sd = sd; -- cgit From 3716deee4cd487a040db5616b76d500c9bf051be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 May 2005 15:58:54 +0000 Subject: r6579: improved the handling of lock timeouts and cancels in the pvfs locking code. On lock cancel don't retry the lock. (This used to be commit dffeb3c3d44d1b837a6036c47eb809ce1bd53b22) --- source4/ntvfs/posix/pvfs_lock.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 6ad654f505..8015fc46c4 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -104,7 +104,6 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas int i; BOOL timed_out; - /* we consider a cancel to be a timeout */ timed_out = (reason != PVFS_WAIT_EVENT); locks = lck->lockx.in.locks + lck->lockx.in.ulock_cnt; @@ -117,16 +116,21 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas DLIST_REMOVE(f->pending_list, pending); - status = brl_lock(pvfs->brl_context, - &f->handle->brl_locking_key, - req->smbpid, - f->fnum, - locks[pending->pending_lock].offset, - locks[pending->pending_lock].count, - rw, NULL); - + /* we don't retry on a cancel */ + if (reason == PVFS_WAIT_CANCEL) { + status = NT_STATUS_CANCELLED; + } else { + status = brl_lock(pvfs->brl_context, + &f->handle->brl_locking_key, + req->smbpid, + f->fnum, + locks[pending->pending_lock].offset, + locks[pending->pending_lock].count, + rw, NULL); + } if (NT_STATUS_IS_OK(status)) { f->lock_count++; + timed_out = False; } /* if we have failed and timed out, or succeeded, then we @@ -153,14 +157,10 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas } /* if we haven't timed out yet, then we can do more pending locks */ - if (timed_out) { - pending = NULL; + if (rw == READ_LOCK) { + rw = PENDING_READ_LOCK; } else { - if (rw == READ_LOCK) { - rw = PENDING_READ_LOCK; - } else { - rw = PENDING_WRITE_LOCK; - } + rw = PENDING_WRITE_LOCK; } /* we've now got the pending lock. try and get the rest, which might -- cgit From 289bc557ebbad8c3ad8b24a37eb48a5d4de43ee2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 May 2005 15:59:34 +0000 Subject: r6580: fixed the bug that caused the truncation of the main file on a stream open with openx and the 'truncate if exists' flag (This used to be commit aa82b105d5871b3ca693a0757bb48cc589d88824) --- source4/ntvfs/posix/pvfs_open.c | 26 ++++++++++++++++++++------ source4/ntvfs/posix/xattr_system.c | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index e68670f7cc..4a2c8ea247 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -856,7 +856,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t create_options; uint32_t share_access; uint32_t access_mask; - BOOL stream_existed; + BOOL stream_existed, stream_truncate=False; /* use the generic mapping code to avoid implementing all the different open calls. */ @@ -892,13 +892,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } + flags = 0; + switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: - flags = O_TRUNC; - break; - case NTCREATEX_DISP_OVERWRITE_IF: - flags = O_TRUNC; + if (name->stream_name == NULL) { + flags = O_TRUNC; + } else { + stream_truncate = True; + } break; case NTCREATEX_DISP_OPEN: @@ -912,7 +915,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - flags = O_TRUNC; + if (name->stream_name == NULL) { + flags = O_TRUNC; + } else { + stream_truncate = True; + } break; case NTCREATEX_DISP_CREATE: @@ -1075,6 +1082,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_free(lck); return status; } + if (stream_truncate) { + status = pvfs_stream_truncate(pvfs, f->handle->name, fd, 0); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } + } } /* re-resolve the open fd */ diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 3b8becf6fe..4101b69ed7 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -37,7 +37,7 @@ NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs, #if HAVE_XATTR_SUPPORT int ret; - *blob = data_blob_talloc(mem_ctx, NULL, estimated_size); + *blob = data_blob_talloc(mem_ctx, NULL, estimated_size+16); if (blob->data == NULL) { return NT_STATUS_NO_MEMORY; } -- cgit From 1199f5f561c44fb3075742b6795ac9f64d079742 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 3 May 2005 09:57:34 +0000 Subject: r6597: Make use of libblkid (part of e2fsprogs) for reporting volume GUID, if possible. Implement smbclient's 'fsinfo' comand family which allows you to query file system information in all known levels. (This used to be commit 660d6e3915d0539dd78c77df6707ea84edb4d509) --- source4/ntvfs/posix/config.m4 | 7 +++++++ source4/ntvfs/posix/pvfs_fsinfo.c | 28 ++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 0fcc948a5b..7625f8ee81 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -31,3 +31,10 @@ AC_CHECK_FUNCS(flistxattr) if test x"$ac_cv_func_flistxattr" = x"yes"; then AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) fi + +AC_CHECK_HEADERS(blkid/blkid.h) +AC_SEARCH_LIBS(blkid_get_cache, [blkid]) +AC_CHECK_FUNCS(blkid_get_cache) +if test x"$ac_cv_func_blkid_get_cache" = x"yes"; then + AC_DEFINE(HAVE_LIBBLKID,1,[Whether we have blkid support (e2fsprogs)]) +fi diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 6d92713ac7..6046ecb6f8 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -22,7 +22,12 @@ #include "includes.h" #include "vfs_posix.h" +#include "librpc/gen_ndr/ndr_xattr.h" +/* We use libblkid out of e2fsprogs to identify UUID of a volume */ +#ifdef HAVE_LIBBLKID +#include +#endif /* return filesystem space info @@ -136,8 +141,27 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; case RAW_QFS_OBJECTID_INFORMATION: - ZERO_STRUCT(fs->objectid_information.out); - return NT_STATUS_OK; + { +#ifdef HAVE_LIBBLKID + NTSTATUS status; + blkid_cache blk_cache = NULL; + const char *uuid_value; + const char *blkid_devname; + +#endif + ZERO_STRUCT(fs->objectid_information.out); +#ifdef HAVE_LIBBLKID + blkid_devname = blkid_devno_to_devname(st.st_dev); + if (!blk_cache && blkid_get_cache(&blk_cache,NULL) < 0 ) { + return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + } + if ((uuid_value = blkid_get_tag_value(blk_cache, "UUID", blkid_devname))) { + GUID_from_string(uuid_value, &fs->objectid_information.out.guid); + free(uuid_value); + } +#endif + return NT_STATUS_OK; + } } return NT_STATUS_INVALID_LEVEL; -- cgit From 46727924a0ca1c255311121e8f0e2ecf7a66db1a Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 3 May 2005 13:02:14 +0000 Subject: r6599: Fix formating using 'linux' C style Fix memory handling for blkid caches which need to be cleared when session is done. (This used to be commit c623cc60541f747f0a801eb77d97bb0a3bb6956f) --- source4/ntvfs/posix/pvfs_fsinfo.c | 54 +++++++++++++++++++++++++-------------- source4/ntvfs/posix/vfs_posix.c | 3 +++ source4/ntvfs/posix/vfs_posix.h | 14 ++++++++++ 3 files changed, 52 insertions(+), 19 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 6046ecb6f8..3a95ed3ff5 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -26,9 +26,13 @@ /* We use libblkid out of e2fsprogs to identify UUID of a volume */ #ifdef HAVE_LIBBLKID -#include +static int blkid_cache_destructor(void * cache_wrap) { + blkid_cache_wrap_t * cache = (blkid_cache_wrap_t *)cache_wrap; + blkid_put_cache(cache->cache); + if(cache->devname) free((void *)cache->devname); + return 0; +} #endif - /* return filesystem space info */ @@ -141,28 +145,40 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; case RAW_QFS_OBJECTID_INFORMATION: - { + { #ifdef HAVE_LIBBLKID - NTSTATUS status; - blkid_cache blk_cache = NULL; - const char *uuid_value; - const char *blkid_devname; - + NTSTATUS status; + const char *uuid_value; #endif - ZERO_STRUCT(fs->objectid_information.out); + ZERO_STRUCT(fs->objectid_information.out); #ifdef HAVE_LIBBLKID - blkid_devname = blkid_devno_to_devname(st.st_dev); - if (!blk_cache && blkid_get_cache(&blk_cache,NULL) < 0 ) { - return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + if (!pvfs->blkid_cache) { + pvfs->blkid_cache = talloc(ntvfs, blkid_cache_wrap_t); + + if (!pvfs->blkid_cache) { + return NT_STATUS_NO_MEMORY; } - if ((uuid_value = blkid_get_tag_value(blk_cache, "UUID", blkid_devname))) { - GUID_from_string(uuid_value, &fs->objectid_information.out.guid); - free(uuid_value); - } -#endif - return NT_STATUS_OK; + + pvfs->blkid_cache->cache = NULL; + pvfs->blkid_cache->devname = blkid_devno_to_devname(st.st_dev); + + talloc_set_destructor(pvfs->blkid_cache, blkid_cache_destructor); + + if (blkid_get_cache(&pvfs->blkid_cache->cache,NULL) < 0 ) { + return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + } + } + + if ((uuid_value = blkid_get_tag_value(pvfs->blkid_cache->cache, + "UUID", pvfs->blkid_cache->devname))) { + GUID_from_string(uuid_value, &fs->objectid_information.out.guid); + free((void*)uuid_value); } +#endif + return NT_STATUS_OK; + } + default: + break; } - return NT_STATUS_INVALID_LEVEL; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ec8db07d01..1d3979aabf 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -88,6 +88,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->sid_cache.creator_owner = dom_sid_parse_talloc(pvfs, SID_CREATOR_OWNER); pvfs->sid_cache.creator_group = dom_sid_parse_talloc(pvfs, SID_CREATOR_GROUP); +#ifdef HAVE_BLKID + pvfs->blkid_cache = NULL; +#endif } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index f779936bf9..a55674d69a 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -26,6 +26,16 @@ #include "system/filesys.h" #include "smb_server/smb_server.h" +/* We use libblkid out of e2fsprogs to identify UUID of a volume */ +#ifdef HAVE_LIBBLKID +#include + +typedef struct { + blkid_cache cache; + const char *devname; +} blkid_cache_wrap_t; +#endif + /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ struct pvfs_state { @@ -67,6 +77,10 @@ struct pvfs_state { const struct dom_sid *creator_owner; const struct dom_sid *creator_group; } sid_cache; + +#ifdef HAVE_LIBBLKID + blkid_cache_wrap_t *blkid_cache; +#endif }; /* this is the basic information needed about a file from the filesystem */ -- cgit From bf1ffa283caef6a3c98b5cc7f5bc8205c2818b06 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 5 Jun 2005 06:53:07 +0000 Subject: r7294: implemented the irpc messaging system. This is the core of the management system I proposed on samba-technical a couple of days ago. Essentially it is a very lightweight way for any code in Samba to make IDL based rpc calls to anywhere else in the code, without the client or server having to go to the trouble of setting up a full rpc service. It can be used with any of our existing IDL, but I expect it will mostly be used for a new set of Samba specific management calls. The LOCAL-IRPC torture test demonstrates how it can be used by calling the echo_AddOne() call over this transport. (This used to be commit 3d589a09954eb8b318f567e1150b0c27412fb942) --- source4/ntvfs/common/brlock.c | 1 + source4/ntvfs/common/opendb.c | 1 + source4/ntvfs/posix/pvfs_wait.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 5e404768e0..e06cb0602e 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -30,6 +30,7 @@ #include "lib/tdb/include/tdb.h" #include "messages.h" #include "db_wrap.h" +#include "lib/messaging/irpc.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 4109992bc0..008f15d078 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -44,6 +44,7 @@ #include "messages.h" #include "librpc/gen_ndr/ndr_security.h" #include "db_wrap.h" +#include "lib/messaging/irpc.h" struct odb_context { struct tdb_wrap *w; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index e9c4a2f754..3574a30583 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -25,6 +25,7 @@ #include "dlinklist.h" #include "vfs_posix.h" #include "smbd/service_stream.h" +#include "lib/messaging/irpc.h" /* the context for a single wait instance */ struct pvfs_wait { -- cgit From 6a70164fe0c12ee8e914ddb934d7ef7e9ff232aa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 7 Jun 2005 12:15:10 +0000 Subject: r7361: fixed the 'file becomes a directory' bug that marc kapland found. Thanks Marc! (This used to be commit d1c5eb3693b77b3eb7527dc2758a6ea75a100376) --- source4/ntvfs/posix/pvfs_util.c | 7 ++++++- source4/ntvfs/posix/pvfs_xattr.c | 8 +++++--- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index eb0f04728c..7eedc38cf9 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -68,11 +68,16 @@ NTSTATUS pvfs_match_attrib(struct pvfs_state *pvfs, struct pvfs_filename *name, /* normalise a file attribute */ -uint32_t pvfs_attrib_normalise(uint32_t attrib) +uint32_t pvfs_attrib_normalise(uint32_t attrib, mode_t mode) { if (attrib != FILE_ATTRIBUTE_NORMAL) { attrib &= ~FILE_ATTRIBUTE_NORMAL; } + if (S_ISDIR(mode)) { + attrib |= FILE_ATTRIBUTE_DIRECTORY; + } else { + attrib &= ~FILE_ATTRIBUTE_DIRECTORY; + } return attrib; } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index c2af2e10bd..7c4fa317d6 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -184,7 +184,8 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name switch (attrib.version) { case 1: info1 = &attrib.info.info1; - name->dos.attrib = pvfs_attrib_normalise(info1->attrib); + name->dos.attrib = pvfs_attrib_normalise(info1->attrib, + name->st.st_mode); name->dos.ea_size = info1->ea_size; if (name->st.st_size == info1->size) { name->dos.alloc_size = @@ -201,7 +202,8 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name case 2: info2 = &attrib.info.info2; - name->dos.attrib = pvfs_attrib_normalise(info2->attrib); + name->dos.attrib = pvfs_attrib_normalise(info2->attrib, + name->st.st_mode); name->dos.ea_size = info2->ea_size; if (name->st.st_size == info2->size) { name->dos.alloc_size = @@ -248,7 +250,7 @@ NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name attrib.version = 2; info2 = &attrib.info.info2; - name->dos.attrib = pvfs_attrib_normalise(name->dos.attrib); + name->dos.attrib = pvfs_attrib_normalise(name->dos.attrib, name->st.st_mode); info2->attrib = name->dos.attrib; info2->ea_size = name->dos.ea_size; -- cgit From 0f8d452ca020ece761872721e19e62ae0fc21582 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Jun 2005 08:24:34 +0000 Subject: r7458: don't look at components[-1] :-) we now survive the RAW-UNLINK test without crashing metze (This used to be commit c2149963911bf95892e732b744f244fd76ff88c8) --- source4/ntvfs/posix/pvfs_resolve.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index fc899c5fbc..355e82c301 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -392,12 +392,14 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t memmove(&components[i], &components[i+1], sizeof(char *)*(num_components-i)); i--; + continue; } if (strcmp(components[i], "..") == 0) { if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; memmove(&components[i-1], &components[i+1], sizeof(char *)*(num_components-(i+1))); i -= 2; + continue; } } -- cgit From 70656780add642ae390c5be48255bd99af915445 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 10 Jun 2005 08:52:26 +0000 Subject: r7459: fixed pvfs for the RAW-MUX test when you cancel a lock, w2k3 gives NT_STATUS_FILE_LOCK_CONFLICT not NT_STATUS_CANCELLED. Strange. (This used to be commit a4f17fcd9218f16b6cc166b2f797e8889d6f63f4) --- source4/ntvfs/posix/pvfs_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 8015fc46c4..e803ce3d41 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -118,7 +118,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas /* we don't retry on a cancel */ if (reason == PVFS_WAIT_CANCEL) { - status = NT_STATUS_CANCELLED; + status = NT_STATUS_FILE_LOCK_CONFLICT; } else { status = brl_lock(pvfs->brl_context, &f->handle->brl_locking_key, -- cgit From bda75f7e90f1d092be87c6ab9a6f209ce5d45138 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 11 Jun 2005 07:46:50 +0000 Subject: r7488: update the mode in the struct too, that fixes the RAW-RENAME test metze (This used to be commit e27c1ab89b21726d3c9e7f8f7af22d1ff38f2413) --- source4/ntvfs/posix/pvfs_util.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 7eedc38cf9..d716834fed 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -149,7 +149,8 @@ NTSTATUS pvfs_copy_file(struct pvfs_state *pvfs, unlink(name2->full_name); return status; } - + + name2->st.st_mode = mode; name2->dos = name1->dos; status = pvfs_dosattrib_save(pvfs, name2, fd2); -- cgit From f29b9278bb782b48c4f31dd7d42dc530ce598969 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Jun 2005 01:11:24 +0000 Subject: r7557: trigger a probe at tconx time to see if xattrs are really supported by the filesystem (This used to be commit 71e281ae2fe2ce169aeb09f72376a60d28845808) --- source4/ntvfs/posix/pvfs_xattr.c | 14 ++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 5 +++++ 2 files changed, 19 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 7c4fa317d6..e67253e657 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -458,3 +458,17 @@ NTSTATUS pvfs_xattr_save(struct pvfs_state *pvfs, return status; } + +/* + probe for system support for xattrs +*/ +void pvfs_xattr_probe(struct pvfs_state *pvfs) +{ + TALLOC_CTX *tmp_ctx = talloc_new(pvfs); + DATA_BLOB blob; + pull_xattr_blob(pvfs, tmp_ctx, "user.XattrProbe", pvfs->base_directory, + -1, 1, &blob); + pull_xattr_blob(pvfs, tmp_ctx, "security.XattrProbe", pvfs->base_directory, + -1, 1, &blob); + talloc_free(tmp_ctx); +} diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 1d3979aabf..846ba61a86 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -91,6 +91,11 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) #ifdef HAVE_BLKID pvfs->blkid_cache = NULL; #endif + + /* check if the system really supports xattrs */ + if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { + pvfs_xattr_probe(pvfs); + } } -- cgit From 9105bf4054b8ebac0c73b504bf38d49f81661176 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 15 Jun 2005 21:03:43 +0000 Subject: r7621: Trivial reformatting while trying to understand share modes. Still survives smbtorture *DENY* . Volker (This used to be commit da78ed1a4d1f7966d8013278436a710d258879e1) --- source4/ntvfs/common/opendb.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 008f15d078..72e9fff1c6 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -156,8 +156,6 @@ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, */ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) { -#define CHECK_MASK(am, sa, right, share) if (((am) & (right)) && !((sa) & (share))) return True - if (e1->pending || e2->pending) return False; /* if either open involves no read.write or delete access then @@ -184,26 +182,23 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) return False; } - CHECK_MASK(e1->access_mask, e2->share_access, - SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, - NTCREATEX_SHARE_ACCESS_WRITE); - CHECK_MASK(e2->access_mask, e1->share_access, - SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, - NTCREATEX_SHARE_ACCESS_WRITE); +#define CHECK_MASK(am, right, sa, share) \ + if (((am) & (right)) && !((sa) & (share))) return True + + CHECK_MASK(e1->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, + e2->share_access, NTCREATEX_SHARE_ACCESS_WRITE); + CHECK_MASK(e2->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, + e1->share_access, NTCREATEX_SHARE_ACCESS_WRITE); - CHECK_MASK(e1->access_mask, e2->share_access, - SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, - NTCREATEX_SHARE_ACCESS_READ); - CHECK_MASK(e2->access_mask, e1->share_access, - SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, - NTCREATEX_SHARE_ACCESS_READ); - - CHECK_MASK(e1->access_mask, e2->share_access, - SEC_STD_DELETE, - NTCREATEX_SHARE_ACCESS_DELETE); - CHECK_MASK(e2->access_mask, e1->share_access, - SEC_STD_DELETE, - NTCREATEX_SHARE_ACCESS_DELETE); + CHECK_MASK(e1->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, + e2->share_access, NTCREATEX_SHARE_ACCESS_READ); + CHECK_MASK(e2->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, + e1->share_access, NTCREATEX_SHARE_ACCESS_READ); + + CHECK_MASK(e1->access_mask, SEC_STD_DELETE, + e2->share_access, NTCREATEX_SHARE_ACCESS_DELETE); + CHECK_MASK(e2->access_mask, SEC_STD_DELETE, + e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE); /* if a delete is pending then a second open is not allowed */ if ((e1->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) || -- cgit From 51b1451cbaf7b27af1d5f1a5f5a42430afe99234 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Jun 2005 04:23:05 +0000 Subject: r7792: make the allocation size rounding in pvfs configurable (This used to be commit 1f35642bed1129d0834906b3e94e8868992d6eb9) --- source4/ntvfs/posix/pvfs_util.c | 5 ++--- source4/ntvfs/posix/vfs_posix.c | 3 +++ source4/ntvfs/posix/vfs_posix.h | 3 +++ 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index d716834fed..f286dfdc48 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -198,7 +198,6 @@ uint32_t pvfs_name_hash(const char *key, size_t length) */ uint64_t pvfs_round_alloc_size(struct pvfs_state *pvfs, uint64_t size) { - const uint64_t round_value = 511; - if (size == 0) return 0; - return (size + round_value) & ~round_value; + const uint32_t round_value = pvfs->alloc_size_rounding; + return round_value * ((size + round_value - 1)/round_value); } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 846ba61a86..906428fc6d 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -51,6 +51,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; } + /* this must be a power of 2 */ + pvfs->alloc_size_rounding = lp_parm_int(-1, "posix", "allocationrounding", 512); + #if HAVE_XATTR_SUPPORT if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index a55674d69a..b5b0e2b28d 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -72,6 +72,9 @@ struct pvfs_state { /* if posix:eadb is set, then this gets setup */ struct tdb_wrap *ea_db; + /* the allocation size rounding */ + uint32_t alloc_size_rounding; + /* used to accelerate acl mapping */ struct { const struct dom_sid *creator_owner; -- cgit From 5e40d0187b86f758b0fa744365e657ec6ee40ff5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Jun 2005 04:33:24 +0000 Subject: r7795: use a share specific allocation rounding (This used to be commit 9adacb0d1620d4cfadd515239b853977cf03a719) --- source4/ntvfs/posix/vfs_posix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 906428fc6d..ac12f3853f 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -52,7 +52,8 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) } /* this must be a power of 2 */ - pvfs->alloc_size_rounding = lp_parm_int(-1, "posix", "allocationrounding", 512); + pvfs->alloc_size_rounding = lp_parm_int(snum, + "posix", "allocationrounding", 512); #if HAVE_XATTR_SUPPORT if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; -- cgit From 66a52992ff6a9f2f926249ac428d6fad72303637 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Jun 2005 22:30:26 +0000 Subject: r7850: Support mkdir() with just one parameter. Patch from Steven Edwards . I've moved the Win32-specific tests to win32.m4 so it does not make any of the POSIX configure stuff more complicated. (This used to be commit bf85fdd01552f75b745fdf3159a7a87cd6521ed2) --- source4/ntvfs/posix/pvfs_mkdir.c | 1 + source4/ntvfs/posix/pvfs_open.c | 1 + source4/ntvfs/simple/vfs_simple.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 03bc16cdbe..591ec7ca84 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "system/dir.h" #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_security.h" diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 4a2c8ea247..8dd9689863 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "system/dir.h" #include "system/time.h" #include "dlinklist.h" #include "messages.h" diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index cebf7a5c32..86ffab66ba 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -27,6 +27,7 @@ */ #include "includes.h" +#include "system/dir.h" #include "system/filesys.h" #include "svfs.h" #include "system/time.h" -- cgit From bdee131f30e1bef31498b08bb648ddee35ea4892 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Jun 2005 00:18:20 +0000 Subject: r7860: switch our ldb storage format to use a NDR encoded objectSid. This is quite a large change as we had lots of code that assumed that objectSid was a string in S- format. metze and simo tried to convince me to use NDR format months ago, but I didn't listen, so its fair that I have the pain of fixing all the code now :-) This builds on the ldb_register_samba_handlers() and ldif handlers code I did earlier this week. There are still three parts of this conversion I have not finished: - the ltdb index records need to use the string form of the objectSid (to keep the DNs sane). Until that it done I have disabled indexing on objectSid, which is a big performance hit, but allows us to pass all our tests while I rejig the indexing system to use a externally supplied conversion function - I haven't yet put in place the code that allows client to use the "S-xxx-yyy" form for objectSid in ldap search expressions. w2k3 supports this, presumably by looking for the "S-" prefix to determine what type of objectSid form is being used by the client. I have been working on ways to handle this, but am not happy with them yet so they aren't part of this patch - I need to change pidl to generate push functions that take a "const void *" instead of a "void*" for the data pointer. That will fix the couple of new warnings this code generates. Luckily it many places the conversion to NDR formatted records actually simplified the code, as it means we no longer need as many calls to dom_sid_parse_talloc(). In some places it got more complex, but not many. (This used to be commit d40bc2fa8ddd43560315688eebdbe98bdd02756c) --- source4/ntvfs/common/sidmap.c | 97 ++++++++++++------------------------------- 1 file changed, 26 insertions(+), 71 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index a39ee2f0eb..b29f197b34 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -97,26 +97,18 @@ static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap, TALLOC_CTX *mem_ctx, struct dom_sid **sid) { const char *attrs[] = { "objectSid", NULL }; - void *ctx = talloc_new(mem_ctx); - const char *sidstr; int ret; - struct ldb_message **res; + struct ldb_message **res = NULL; - ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, mem_ctx, NULL, &res, attrs, "(&(objectClass=domain)(name=%s))", lp_workgroup()); if (ret != 1) { - talloc_free(ctx); + talloc_free(res); return NT_STATUS_NO_SUCH_DOMAIN; } - sidstr = samdb_result_string(res[0], "objectSid", NULL); - if (sidstr == NULL) { - talloc_free(ctx); - return NT_STATUS_NO_SUCH_DOMAIN; - } - - *sid = dom_sid_parse_talloc(mem_ctx, sidstr); - talloc_free(ctx); + *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); + talloc_free(res); if (*sid == NULL) { return NT_STATUS_NO_MEMORY; } @@ -137,26 +129,21 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, const char *s; void *ctx; struct ldb_message **res; - const char *sidstr; struct dom_sid *domain_sid; NTSTATUS status; ctx = talloc_new(sidmap); - sidstr = dom_sid_string(ctx, sid); - if (sidstr == NULL) { - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, - "objectSid=%s", sidstr); + "objectSid=%s", ldap_encode_ndr_dom_sid(ctx, sid)); if (ret != 1) { goto allocated_sid; } /* make sure its a user, not a group */ if (!is_user_account(res[0])) { - DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", sidstr)); + DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", + dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_INVALID_SID; } @@ -174,7 +161,7 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, if (s != NULL) { struct passwd *pwd = getpwnam(s); if (!pwd) { - DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, sidstr)); + DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_NO_SUCH_USER; } @@ -188,7 +175,8 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, if (s != NULL) { struct passwd *pwd = getpwnam(s); if (!pwd) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", s, sidstr)); + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", + s, dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_NO_SUCH_USER; } @@ -217,7 +205,7 @@ allocated_sid: DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", - sidstr)); + dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_INVALID_SID; @@ -236,26 +224,21 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, const char *s; void *ctx; struct ldb_message **res; - const char *sidstr; NTSTATUS status; struct dom_sid *domain_sid; ctx = talloc_new(sidmap); - sidstr = dom_sid_string(ctx, sid); - if (sidstr == NULL) { - talloc_free(ctx); - return NT_STATUS_NO_MEMORY; - } ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, - "objectSid=%s", sidstr); + "objectSid=%s", ldap_encode_ndr_dom_sid(ctx, sid)); if (ret != 1) { goto allocated_sid; } /* make sure its not a user */ if (!is_group_account(res[0])) { - DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", sidstr)); + DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", + dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_INVALID_SID; } @@ -274,7 +257,7 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, struct group *grp = getgrnam(s); if (!grp) { DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", - s, sidstr)); + s, dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_NO_SUCH_USER; } @@ -288,7 +271,7 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, if (s != NULL) { struct group *grp = getgrnam(s); if (!grp) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, sidstr)); + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_NO_SUCH_USER; } @@ -314,7 +297,7 @@ allocated_sid: } DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", - sidstr)); + dom_sid_string(ctx, sid))); talloc_free(ctx); return NT_STATUS_INVALID_SID; @@ -363,18 +346,11 @@ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, "unixID=%u", (unsigned int)uid); for (i=0;ipw_name, pwd->pw_name); for (i=0;isamctx, ctx, NULL, &res, attrs, "unixID=%u", (unsigned int)gid); for (i=0;igr_name, grp->gr_name); for (i=0;i Date: Sun, 26 Jun 2005 11:34:34 +0000 Subject: r7931: fixed a bug in the cifs backend found with the new test code (This used to be commit 447d5fcc1bdbdeaf2d96dbcace36b480b5a18c73) --- source4/ntvfs/cifs/vfs_cifs.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index e283e12f24..f263299cd7 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -547,6 +547,17 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, ASYNC_RECV_TAIL(wr, async_write); } +/* + a handler for async seek replies + */ +static void async_seek(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct smbsrv_request *req = async->req; + req->async_states->status = smb_raw_seek_recv(c_req, async->parms); + req->async_states->send_fn(req); +} + /* seek in a file */ @@ -564,7 +575,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, c_req = smb_raw_seek_send(private->tree, io); - SIMPLE_ASYNC_TAIL; + ASYNC_RECV_TAIL(io, async_seek); } /* -- cgit From 8a300c9248cc956d2aaed59e89efc2535a9f60f5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Jun 2005 17:10:03 +0000 Subject: r8021: we only need to return STATUS_BUFFER_OVERFLOW for the ipc_trans replies and not for the ipc_read() replies as here the client explicit says how much data it wants the write_fn() in dcesrv_output() now returns NTSTATUS and the ipc specific implementations are moved to the ntvfs_ipc module metze (This used to be commit fe483dcd874b7243d61e9623840c672b4ea06b2c) --- source4/ntvfs/ipc/vfs_ipc.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 68c59b7502..2c148fbd0c 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -350,6 +350,18 @@ static NTSTATUS ipc_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } +static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) +{ + DATA_BLOB *blob = private_data; + + if (out->length < blob->length) { + blob->length = out->length; + } + memcpy(blob->data, out->data, blob->length); + *nwritten = blob->length; + return NT_STATUS_OK; +} + /* read from a file */ @@ -380,7 +392,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, } if (data.length != 0) { - status = dcesrv_output_blob(p->dce_conn, &data); + status = dcesrv_output(p->dce_conn, &data, ipc_readx_dcesrv_output); if (NT_STATUS_IS_ERR(status)) { return status; } @@ -604,6 +616,22 @@ static NTSTATUS ipc_search_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } +static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) +{ + NTSTATUS status = NT_STATUS_OK; + DATA_BLOB *blob = private_data; + + if (out->length > blob->length) { + status = STATUS_BUFFER_OVERFLOW; + } + + if (out->length < blob->length) { + blob->length = out->length; + } + memcpy(blob->data, out->data, blob->length); + *nwritten = blob->length; + return status; +} /* SMBtrans - handle a DCERPC command */ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, @@ -638,7 +666,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, async calls. Again, we only expect NT_STATUS_OK. If the call fails then the error is encoded at the dcerpc level */ - status = dcesrv_output_blob(p->dce_conn, &trans->out.data); + status = dcesrv_output(p->dce_conn, &trans->out.data, ipc_trans_dcesrv_output); if (NT_STATUS_IS_ERR(status)) { return status; } -- cgit From 4e2ac8b458181b0eaf858a30e98aa7109e80d9d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Jun 2005 19:25:55 +0000 Subject: r8024: avoid one memcpy in the ipc_trans dcesrv_output() callback we now can reference the DATA_BLOB that is used inside the dcesrv subsystem metze (This used to be commit 078f42bc3f74c66b69c7f76005812b221d691f7a) --- source4/ntvfs/ipc/vfs_ipc.c | 71 ++++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 30 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2c148fbd0c..1be877d7ec 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -350,14 +350,14 @@ static NTSTATUS ipc_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) +static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *output, size_t *nwritten) { DATA_BLOB *blob = private_data; - if (out->length < blob->length) { - blob->length = out->length; + if (output->length < blob->length) { + blob->length = output->length; } - memcpy(blob->data, out->data, blob->length); + memcpy(blob->data, output->data, blob->length); *nwritten = blob->length; return NT_STATUS_OK; } @@ -616,20 +616,33 @@ static NTSTATUS ipc_search_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) +struct ipctp_dcesrv_output { + struct smbsrv_request *req; + struct smb_trans2 *trans; +}; +static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *_output, size_t *nwritten) { NTSTATUS status = NT_STATUS_OK; - DATA_BLOB *blob = private_data; + DATA_BLOB *output; + struct ipctp_dcesrv_output *ipctp = private_data; + + /* + * do it the fast way without doing an extra memcpy() + * + * we need to reference the the DATA_BLOB itself, + * because out->data isn't always a valid talloc pointer + */ + output = talloc_reference(ipctp->req, _output); + NT_STATUS_HAVE_NO_MEMORY(output); - if (out->length > blob->length) { + if (output->length > ipctp->trans->in.max_data) { status = STATUS_BUFFER_OVERFLOW; } - if (out->length < blob->length) { - blob->length = out->length; - } - memcpy(blob->data, out->data, blob->length); - *nwritten = blob->length; + ipctp->trans->out.data.data = output->data; + ipctp->trans->out.data.length = MIN(ipctp->trans->in.max_data, output->length); + + *nwritten = ipctp->trans->out.data.length; return status; } @@ -638,38 +651,36 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans) { struct pipe_state *p; - struct ipc_private *private = ntvfs->private_data; + struct ipc_private *ipcp = ntvfs->private_data; + struct ipctp_dcesrv_output ipctp; NTSTATUS status; /* the fnum is in setup[1] */ - p = pipe_state_find(private, trans->in.setup[1]); - if (!p) { - return NT_STATUS_INVALID_HANDLE; - } + p = pipe_state_find(ipcp, trans->in.setup[1]); + if (!p) return NT_STATUS_INVALID_HANDLE; - trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data); - if (!trans->out.data.data) { - return NT_STATUS_NO_MEMORY; - } + /* + * just to be sure we doesn't have something uninitialized + * the real work is done in the dcesrv_output() callback + */ + trans->out.data = data_blob(NULL, 0); /* pass the data to the dcerpc server. Note that we don't expect this to fail, and things like NDR faults are not reported at this stage. Those sorts of errors happen in the dcesrv_output stage */ status = dcesrv_input(p->dce_conn, &trans->in.data); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NT_STATUS_NOT_OK_RETURN(status); /* now ask the dcerpc system for some output. This doesn't yet handle - async calls. Again, we only expect NT_STATUS_OK. If the call fails then - the error is encoded at the dcerpc level + async calls. Again, we only expect NT_STATUS_OK or STATUS_BUFFER_OVERFLOW. + If the call fails then the error is encoded at the dcerpc level */ - status = dcesrv_output(p->dce_conn, &trans->out.data, ipc_trans_dcesrv_output); - if (NT_STATUS_IS_ERR(status)) { - return status; - } + ipctp.req = req; + ipctp.trans = trans; + status = dcesrv_output(p->dce_conn, &ipctp, ipc_trans_dcesrv_output); + NT_STATUS_IS_ERR_RETURN(status); trans->out.setup_count = 0; trans->out.setup = NULL; -- cgit From 8ab3f59a10d00357cb129a2051fd0f694b5c8081 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 1 Jul 2005 06:05:49 +0000 Subject: r8036: revert rev 8023/8024 as they have a bugs. metze (This used to be commit 66d6b1d5783cba98f2f8e1c8eed1bdc26a5bad4f) --- source4/ntvfs/ipc/vfs_ipc.c | 71 +++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 41 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 1be877d7ec..2c148fbd0c 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -350,14 +350,14 @@ static NTSTATUS ipc_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *output, size_t *nwritten) +static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) { DATA_BLOB *blob = private_data; - if (output->length < blob->length) { - blob->length = output->length; + if (out->length < blob->length) { + blob->length = out->length; } - memcpy(blob->data, output->data, blob->length); + memcpy(blob->data, out->data, blob->length); *nwritten = blob->length; return NT_STATUS_OK; } @@ -616,33 +616,20 @@ static NTSTATUS ipc_search_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -struct ipctp_dcesrv_output { - struct smbsrv_request *req; - struct smb_trans2 *trans; -}; -static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *_output, size_t *nwritten) +static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) { NTSTATUS status = NT_STATUS_OK; - DATA_BLOB *output; - struct ipctp_dcesrv_output *ipctp = private_data; - - /* - * do it the fast way without doing an extra memcpy() - * - * we need to reference the the DATA_BLOB itself, - * because out->data isn't always a valid talloc pointer - */ - output = talloc_reference(ipctp->req, _output); - NT_STATUS_HAVE_NO_MEMORY(output); + DATA_BLOB *blob = private_data; - if (output->length > ipctp->trans->in.max_data) { + if (out->length > blob->length) { status = STATUS_BUFFER_OVERFLOW; } - ipctp->trans->out.data.data = output->data; - ipctp->trans->out.data.length = MIN(ipctp->trans->in.max_data, output->length); - - *nwritten = ipctp->trans->out.data.length; + if (out->length < blob->length) { + blob->length = out->length; + } + memcpy(blob->data, out->data, blob->length); + *nwritten = blob->length; return status; } @@ -651,36 +638,38 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans) { struct pipe_state *p; - struct ipc_private *ipcp = ntvfs->private_data; - struct ipctp_dcesrv_output ipctp; + struct ipc_private *private = ntvfs->private_data; NTSTATUS status; /* the fnum is in setup[1] */ - p = pipe_state_find(ipcp, trans->in.setup[1]); - if (!p) return NT_STATUS_INVALID_HANDLE; + p = pipe_state_find(private, trans->in.setup[1]); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } - /* - * just to be sure we doesn't have something uninitialized - * the real work is done in the dcesrv_output() callback - */ - trans->out.data = data_blob(NULL, 0); + trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data); + if (!trans->out.data.data) { + return NT_STATUS_NO_MEMORY; + } /* pass the data to the dcerpc server. Note that we don't expect this to fail, and things like NDR faults are not reported at this stage. Those sorts of errors happen in the dcesrv_output stage */ status = dcesrv_input(p->dce_conn, &trans->in.data); - NT_STATUS_NOT_OK_RETURN(status); + if (!NT_STATUS_IS_OK(status)) { + return status; + } /* now ask the dcerpc system for some output. This doesn't yet handle - async calls. Again, we only expect NT_STATUS_OK or STATUS_BUFFER_OVERFLOW. - If the call fails then the error is encoded at the dcerpc level + async calls. Again, we only expect NT_STATUS_OK. If the call fails then + the error is encoded at the dcerpc level */ - ipctp.req = req; - ipctp.trans = trans; - status = dcesrv_output(p->dce_conn, &ipctp, ipc_trans_dcesrv_output); - NT_STATUS_IS_ERR_RETURN(status); + status = dcesrv_output(p->dce_conn, &trans->out.data, ipc_trans_dcesrv_output); + if (NT_STATUS_IS_ERR(status)) { + return status; + } trans->out.setup_count = 0; trans->out.setup = NULL; -- cgit From 95a9d9aabf1af1faada43ecdfffc68b04f917e4c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 1 Jul 2005 12:59:23 +0000 Subject: r8059: fixed handling of delete on close fir directories (This used to be commit 14f51a99bccffac0ca284d1315ab6d4b10f3711f) --- source4/ntvfs/posix/pvfs_open.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 8dd9689863..f58cc60f9a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1243,6 +1243,11 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, return NT_STATUS_CANNOT_DELETE; } + if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + f->handle->create_options = create_options; + return NT_STATUS_OK; + } + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); if (lck == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; -- cgit From 74942e1a11501dd75085b29f16ac66cd2185fe2b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 01:57:53 +0000 Subject: r8107: now that we properly separate DOS and NT status codes all the places that relied on the mapping need to be fixed. The first thing is to get all the torture tests working against w2k3 again with nt status codes enabled. The 2nd step will be to make them pass with nt status disabled. This starts on the first task, fixing the assumption that NT_STATUS_INVALID_LOCK_SEQUENCE is a valid substitute for ERRDOS:ERRbadaccess (This used to be commit 87cdd117081193d215c5a9e3603438e058ad777b) --- source4/ntvfs/ntvfs_generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 9b6c75e5c6..024a48bf7a 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -272,7 +272,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, SEC_RIGHTS_FILE_WRITE; break; default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; + return NT_STATUS_DOS(ERRDOS, ERRbadaccess); } switch (open_mode & OPENX_MODE_DENY_MASK) { @@ -311,7 +311,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; break; default: - return NT_STATUS_INVALID_LOCK_SEQUENCE; + return NT_STATUS_DOS(ERRDOS, ERRbadaccess); } switch (open_func) { @@ -336,7 +336,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE; break; } - return NT_STATUS_INVALID_LOCK_SEQUENCE; + return NT_STATUS_DOS(ERRDOS, ERRbadaccess); } return NT_STATUS_OK; -- cgit From afe376bfc71f7dc157791643497792afee33f05d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 05:08:27 +0000 Subject: r8120: added in the newly found DOS locking error codes into the pvfs backend (This used to be commit d77b3820d16f60fb9119ac6eb70007363990b20d) --- source4/ntvfs/posix/pvfs_lock.c | 4 ++-- source4/ntvfs/posix/pvfs_wait.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index e803ce3d41..a0832723b6 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -263,7 +263,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct smbsrv_request } } - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } @@ -324,7 +324,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, if (lck->lockx.in.mode & LOCKING_ANDX_CHANGE_LOCKTYPE) { /* this seems to not be supported by any windows server, or used by any clients */ - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks); } if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) { diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 3574a30583..c363388408 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -181,5 +181,5 @@ NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request * } } - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_DOS(ERRDOS, ERRcancelviolation); } -- cgit From a703329908431b473483fe0e70a121fff1e5fbf6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jul 2005 05:24:39 +0000 Subject: r8122: more fixes from testing dos error code handling against w2k3 (This used to be commit b71fbcf5e2c627d918aef555b8cc8dd4591d8fe7) --- source4/ntvfs/posix/pvfs_ioctl.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 45d29b530d..abf575aa3d 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -30,7 +30,7 @@ static NTSTATUS pvfs_ioctl_old(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_ioctl *io) { - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_DOS(ERRSRV, ERRerror); } /* diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index f58cc60f9a..327f096e7c 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1156,7 +1156,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, struct utimbuf unix_times; if (io->generic.level == RAW_CLOSE_SPLCLOSE) { - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_DOS(ERRSRV, ERRerror); } if (io->generic.level != RAW_CLOSE_CLOSE) { -- cgit From bb8362986571b931c7a69fa0d4d97354ff5bba4f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 9 Jul 2005 11:06:33 +0000 Subject: r8258: Release the opendb lock in pvfs_change_create_options. Volker (This used to be commit 2c4fd3ff99a4ade613030b3eb47d0ed527a95be3) --- source4/ntvfs/posix/pvfs_open.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 327f096e7c..d0e7d82117 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1258,6 +1258,8 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, f->handle->create_options = create_options; } + talloc_free(lck); + return status; } -- cgit From 61edb97bdfabf1ab313fbec5f47f5e6c8a79da1a Mon Sep 17 00:00:00 2001 From: Love Hörnquist Ã…strand Date: Tue, 12 Jul 2005 22:22:59 +0000 Subject: r8394: Make sure the argument to ctype is*(3) macros are unsigned char as required by ISO C99. (This used to be commit 56fd21c806e816cf4c3d23881f26474f858b45e2) --- source4/ntvfs/posix/pvfs_shortname.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 59a3d34640..eb797dc7aa 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -469,7 +469,7 @@ static char *name_map(struct pvfs_mangle_context *ctx, if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) { lead_chars[i] = '_'; } - lead_chars[i] = toupper(lead_chars[i]); + lead_chars[i] = toupper((unsigned char)lead_chars[i]); } for (;imangle_prefix;i++) { lead_chars[i] = '_'; @@ -487,7 +487,7 @@ static char *name_map(struct pvfs_mangle_context *ctx, extension_length = 0; if (dot_p) { for (i=1; extension_length < 3 && dot_p[i]; i++) { - char c = dot_p[i]; + unsigned char c = dot_p[i]; if (FLAG_CHECK(c, FLAG_ASCII)) { extension[extension_length++] = toupper(c); } -- cgit From b37e82567d28626d39ce02c392d09a815cce497f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Jul 2005 03:35:52 +0000 Subject: r8535: no longer rely on seekdir working after a closedir. Instead, keep directories open, but close search states based on an inactivity timer, with a default of a 5 minute timeout (This used to be commit 2e8d154e7dfb9b320a1344e957a39e96e1eefadd) --- source4/ntvfs/posix/pvfs_dirlist.c | 52 +------------------------------------- source4/ntvfs/posix/pvfs_search.c | 39 ++++++++++++++++++++-------- source4/ntvfs/posix/vfs_posix.c | 3 +++ source4/ntvfs/posix/vfs_posix.h | 3 +++ 4 files changed, 35 insertions(+), 62 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 1b60f17462..328d07f71b 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -194,58 +194,16 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) if (e->name) talloc_free(e->name); - e->name = talloc_strdup(dir, de->d_name); + e->name = talloc_strdup(dir->name_cache, de->d_name); e->offset = dir->offset; return e->name; } dir->end_of_search = True; - pvfs_list_hibernate(dir); return NULL; } -/* - put the directory to sleep. Used between search calls to give the - right directory change semantics -*/ -void pvfs_list_hibernate(struct pvfs_dir *dir) -{ - if (dir->dir) { - closedir(dir->dir); - dir->dir = NULL; - } -} - - -/* - wake up the directory search -*/ -NTSTATUS pvfs_list_wakeup(struct pvfs_dir *dir, uint_t *ofs) -{ - if (dir->no_wildcard || - dir->dir != NULL) { - return NT_STATUS_OK; - } - - dir->dir = opendir(dir->unix_path); - if (dir->dir == NULL) { - dir->end_of_search = True; - return pvfs_map_errno(dir->pvfs, errno); - } - - seekdir(dir->dir, *ofs); - dir->offset = telldir(dir->dir); - if (dir->offset != *ofs) { - DEBUG(0,("pvfs_list_wakeup: search offset changed %u -> %u\n", - *ofs, (unsigned)dir->offset)); - } - - return NT_STATUS_OK; -} - - - /* return unix directory of an open search */ @@ -268,14 +226,8 @@ BOOL pvfs_list_eos(struct pvfs_dir *dir, uint_t ofs) NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) { struct dirent *de; - NTSTATUS status; int i; - status = pvfs_list_wakeup(dir, ofs); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - for (i=dir->name_cache_index;i>=0;i--) { struct name_cache_entry *e = &dir->name_cache[i]; if (e->name && StrCaseCmp(name, e->name) == 0) { @@ -303,7 +255,5 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) dir->end_of_search = True; - pvfs_list_hibernate(dir); - return NT_STATUS_OBJECT_NAME_NOT_FOUND; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 69ca6ef997..db197c7b62 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -24,6 +24,8 @@ #include "vfs_posix.h" #include "system/time.h" #include "librpc/gen_ndr/ndr_security.h" +#include "smbd/service_stream.h" +#include "lib/events/events.h" /* the state of a search started with pvfs_search_first() */ @@ -37,6 +39,7 @@ struct pvfs_search_state { time_t last_used; uint_t num_ea_names; struct ea_name *ea_names; + struct timed_event *te; }; @@ -54,6 +57,28 @@ static int pvfs_search_destructor(void *ptr) return 0; } +/* + called when a search timer goes off +*/ +static void pvfs_search_timer(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct pvfs_search_state *search = talloc_get_type(ptr, struct pvfs_search_state); + talloc_free(search); +} + +/* + setup a timer to destroy a open search after a inactivity period +*/ +static void pvfs_search_setup_timer(struct pvfs_search_state *search) +{ + struct event_context *ev = search->pvfs->tcon->smb_conn->connection->event.ctx; + talloc_free(search->te); + search->te = event_add_timed(ev, search, + timeval_current_ofs(search->pvfs->search_inactivity_time, 0), + pvfs_search_timer, search); +} + /* fill in a single search result for a given info level */ @@ -266,7 +291,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, talloc_free(file); } - pvfs_list_hibernate(dir); + pvfs_search_setup_timer(search); return NT_STATUS_OK; } @@ -362,6 +387,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, search->search_attrib = search_attrib & 0xFF; search->must_attrib = (search_attrib>>8) & 0xFF; search->last_used = time(NULL); + search->te = NULL; talloc_set_destructor(search, pvfs_search_destructor); @@ -409,11 +435,6 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, search->last_used = time(NULL); dir = search->dir; - status = pvfs_list_wakeup(dir, &search->current_index); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { @@ -499,6 +520,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, search->last_used = 0; search->num_ea_names = io->t2ffirst.in.num_names; search->ea_names = io->t2ffirst.in.ea_names; + search->te = NULL; talloc_set_destructor(search, pvfs_search_destructor); @@ -573,11 +595,6 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, search->current_index = io->t2fnext.in.resume_key; } - status = pvfs_list_wakeup(dir, &search->current_index); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - search->num_ea_names = io->t2fnext.in.num_names; search->ea_names = io->t2fnext.in.ea_names; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ac12f3853f..a4b15e3c57 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -55,6 +55,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->alloc_size_rounding = lp_parm_int(snum, "posix", "allocationrounding", 512); + pvfs->search_inactivity_time = lp_parm_int(snum, + "posix", "searchinactivity", 300); + #if HAVE_XATTR_SUPPORT if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index b5b0e2b28d..f18864197d 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -74,6 +74,9 @@ struct pvfs_state { /* the allocation size rounding */ uint32_t alloc_size_rounding; + + /* how long to keep inactive searches around for */ + uint_t search_inactivity_time; /* used to accelerate acl mapping */ struct { -- cgit From 8a94055debbf494b047ea1c05fc4b984b0b1cfa1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Jul 2005 10:40:17 +0000 Subject: r8753: fixed directory handling on systems that do not return . and .. as the first two entries in a directory. This is what caused the FC3 system shelob in the build farm to fail the RAW-UNLINK and RAW-SEARCH tests. (This used to be commit f48abaaaca301c025ebd381f62345b3869809917) --- source4/ntvfs/posix/pvfs_dirlist.c | 87 ++++++++++++++++++++++++++++++-------- 1 file changed, 70 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 328d07f71b..a5d394d2aa 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -45,6 +45,11 @@ struct pvfs_dir { uint32_t name_cache_index; }; +#define DIR_OFFSET_DOT 0 +#define DIR_OFFSET_DOTDOT 1 +#define DIR_OFFSET_BASE 2 + + /* a special directory listing case where the pattern has no wildcard. We can just do a single stat() thus avoiding the more expensive directory scan @@ -150,12 +155,29 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, return NT_STATUS_OK; } +/* + add an entry to the local cache +*/ +static void dcache_add(struct pvfs_dir *dir, const char *name) +{ + struct name_cache_entry *e; + + dir->name_cache_index = (dir->name_cache_index+1) % NAME_CACHE_SIZE; + e = &dir->name_cache[dir->name_cache_index]; + + if (e->name) talloc_free(e->name); + + e->name = talloc_strdup(dir->name_cache, name); + e->offset = dir->offset; +} + /* return the next entry */ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) { struct dirent *de; + enum protocol_types protocol = dir->pvfs->tcon->smb_conn->negotiate.protocol; /* non-wildcard searches are easy */ if (dir->no_wildcard) { @@ -165,39 +187,58 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) return dir->single_name; } - if (*ofs != dir->offset) { - seekdir(dir->dir, *ofs); + /* . and .. are handled separately as some unix systems will + not return them first in a directory, but windows client + may assume that these entries always appear first */ + if (*ofs == DIR_OFFSET_DOT) { + (*ofs)++; dir->offset = *ofs; + if (ms_fnmatch(dir->pattern, ".", protocol) == 0) { + dcache_add(dir, "."); + return "."; + } } + + if (*ofs == DIR_OFFSET_DOTDOT) { + (*ofs)++; + dir->offset = *ofs; + if (ms_fnmatch(dir->pattern, "..", protocol) == 0) { + dcache_add(dir, ".."); + return ".."; + } + } + + if (*ofs == DIR_OFFSET_BASE) { + rewinddir(dir->dir); + } else if (*ofs != dir->offset) { + seekdir(dir->dir, (*ofs) - DIR_OFFSET_BASE); + } + dir->offset = *ofs; while ((de = readdir(dir->dir))) { const char *dname = de->d_name; - struct name_cache_entry *e; - if (ms_fnmatch(dir->pattern, dname, - dir->pvfs->tcon->smb_conn->negotiate.protocol) != 0) { + if (strcmp(dname, ".") == 0 || + strcmp(dname, "..") == 0) { + continue; + } + + if (ms_fnmatch(dir->pattern, dname, protocol) != 0) { char *short_name = pvfs_short_name_component(dir->pvfs, dname); if (short_name == NULL || - ms_fnmatch(dir->pattern, short_name, - dir->pvfs->tcon->smb_conn->negotiate.protocol) != 0) { + ms_fnmatch(dir->pattern, short_name, protocol) != 0) { talloc_free(short_name); continue; } talloc_free(short_name); } - dir->offset = telldir(dir->dir); + dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE; (*ofs) = dir->offset; - dir->name_cache_index = (dir->name_cache_index+1) % NAME_CACHE_SIZE; - e = &dir->name_cache[dir->name_cache_index]; + dcache_add(dir, dname); - if (e->name) talloc_free(e->name); - - e->name = talloc_strdup(dir->name_cache, de->d_name); - e->offset = dir->offset; - - return e->name; + return dname; } dir->end_of_search = True; @@ -228,6 +269,18 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) struct dirent *de; int i; + if (strcmp(name, ".") == 0) { + dir->offset = DIR_OFFSET_DOTDOT; + *ofs = dir->offset; + return NT_STATUS_OK; + } + + if (strcmp(name, "..") == 0) { + dir->offset = DIR_OFFSET_BASE; + *ofs = dir->offset; + return NT_STATUS_OK; + } + for (i=dir->name_cache_index;i>=0;i--) { struct name_cache_entry *e = &dir->name_cache[i]; if (e->name && StrCaseCmp(name, e->name) == 0) { @@ -247,7 +300,7 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) while ((de = readdir(dir->dir))) { if (StrCaseCmp(name, de->d_name) == 0) { - dir->offset = telldir(dir->dir); + dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE; *ofs = dir->offset; return NT_STATUS_OK; } -- cgit From 5ef83290bc4db2ac409b0de32f459aef3c52faeb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Aug 2005 17:22:33 +0000 Subject: r9007: fixed error code for setting delete on close on a non-empty directory (This used to be commit 320ab3c93b05a79b77dbbb85e9b038bb07848ba5) --- source4/ntvfs/posix/pvfs_dirlist.c | 24 ++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_open.c | 3 +++ 2 files changed, 27 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index a5d394d2aa..a055773b51 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -310,3 +310,27 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + + +/* + see if a directory is empty +*/ +BOOL pvfs_directory_empty(struct pvfs_state *pvfs, struct pvfs_filename *name) +{ + struct dirent *de; + DIR *dir = opendir(name->full_name); + if (dir == NULL) { + return True; + } + + while ((de = readdir(dir))) { + if (strcmp(de->d_name, ".") != 0 && + strcmp(de->d_name, "..") != 0) { + closedir(dir); + return False; + } + } + + closedir(dir); + return True; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index d0e7d82117..3ae8e2150f 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1244,6 +1244,9 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, } if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + if (!pvfs_directory_empty(pvfs, f->handle->name)) { + return NT_STATUS_DIRECTORY_NOT_EMPTY; + } f->handle->create_options = create_options; return NT_STATUS_OK; } -- cgit From 6eb9567c3f68869f691e29d5daffe3ea28858a46 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Aug 2005 17:52:33 +0000 Subject: r9009: directory not empty is not an error on failure to delete directory in delete on close (This used to be commit dada509f5e374872cded9035611c9d4fd9f4c4c7) --- source4/ntvfs/posix/pvfs_open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3ae8e2150f..d3b9681b58 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -75,7 +75,7 @@ static int pvfs_dir_handle_destructor(void *p) DEBUG(0,("Warning: xattr rmdir hook failed for '%s' - %s\n", h->name->full_name, nt_errstr(status))); } - if (rmdir(h->name->full_name) != 0) { + if (rmdir(h->name->full_name) != 0 && errno != ENOTEMPTY) { DEBUG(0,("pvfs_close: failed to rmdir '%s' - %s\n", h->name->full_name, strerror(errno))); } -- cgit From 8e26f094338b4528ec82dda8b69f61f22c27258e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 4 Aug 2005 01:43:25 +0000 Subject: r9031: don't use the global $LIBS variables for posix specific stuff metze (This used to be commit 51ab751c619bfa05a736853723f1aeda901a0b33) --- source4/ntvfs/posix/config.m4 | 11 ++++++----- source4/ntvfs/posix/config.mk | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 7625f8ee81..75ab531375 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -25,16 +25,17 @@ dnl ############################################ dnl use flistxattr as the key function for having dnl sufficient xattr support for posix xattr backend AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) -AC_SEARCH_LIBS(flistxattr, [attr]) -AC_CHECK_FUNCS(flistxattr) - +AC_SEARCH_LIBS_EXT(flistxattr, [attr], XATTR_LIBS) +AC_CHECK_FUNC_EXT(flistxattr, $XATTR_LIBS) +SMB_EXT_LIB(XATTR,[${XATTR_LIBS}],[${XATTR_CFLAGS}],[${XATTR_CPPFLAGS}],[${XATTR_LDFLAGS}]) if test x"$ac_cv_func_flistxattr" = x"yes"; then AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) fi AC_CHECK_HEADERS(blkid/blkid.h) -AC_SEARCH_LIBS(blkid_get_cache, [blkid]) -AC_CHECK_FUNCS(blkid_get_cache) +AC_SEARCH_LIBS_EXT(blkid_get_cache, [blkid], BLKID_LIBS) +AC_CHECK_FUNC_EXT(blkid_get_cache, $BLKID_LIBS) +SMB_EXT_LIB(BLKID,[${BLKID_LIBS}],[${BLKID_CFLAGS}],[${BLKID_CPPFLAGS}],[${BLKID_LDFLAGS}]) if test x"$ac_cv_func_blkid_get_cache" = x"yes"; then AC_DEFINE(HAVE_LIBBLKID,1,[Whether we have blkid support (e2fsprogs)]) fi diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index f2f7207773..9be3723056 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -31,6 +31,6 @@ ADD_OBJ_FILES = \ ntvfs/posix/pvfs_acl.o \ ntvfs/posix/xattr_system.o \ ntvfs/posix/xattr_tdb.o -REQUIRED_SUBSYSTEMS = NDR_XATTR ntvfs_common +REQUIRED_SUBSYSTEMS = NDR_XATTR ntvfs_common EXT_LIB_XATTR EXT_LIB_BLKID # End MODULE ntvfs_posix ################################################ -- cgit From ba205b314390474ecf263a9b6094330d6bc37a80 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Aug 2005 06:14:34 +0000 Subject: r9054: removed incorrect paranoia check on opening streams (this caused RAW-STREAMS to fail) (This used to be commit c164ee5b19f6880b7b5df8d8fb96704350432862) --- source4/ntvfs/posix/pvfs_open.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index d3b9681b58..94749600e1 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1075,9 +1075,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* if this was a stream create then create the stream as well */ if (!name->stream_exists) { - if (!(access_mask & SEC_FILE_WRITE_ATTRIBUTE)) { - return NT_STATUS_ACCESS_DENIED; - } status = pvfs_stream_create(pvfs, f->handle->name, fd); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); -- cgit From 94efb6f70efd7d3f2f5740cf0998f23bb9624546 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 Aug 2005 21:00:38 +0000 Subject: r9074: cope with a null ntvfs context in disconnect, so the destructor that runs on a failed ntvfs init works (This used to be commit dac0be64c7cef18f6740053b3e6fe9a25df40c88) --- source4/ntvfs/ntvfs_interface.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 6ab5aad790..6a711bc3bd 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -35,7 +35,11 @@ NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) NTSTATUS ntvfs_disconnect(struct smbsrv_tcon *tcon) { - struct ntvfs_module_context *ntvfs = tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs; + if (tcon->ntvfs_ctx == NULL) { + return NT_STATUS_INVALID_CONNECTION; + } + ntvfs = tcon->ntvfs_ctx->modules; if (!ntvfs->ops->disconnect) { return NT_STATUS_NOT_IMPLEMENTED; } -- cgit From 3be75a4c6d4b9d86f1b85c75fb2f41c6c0eeec94 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 11 Aug 2005 13:12:45 +0000 Subject: r9240: - move struct security_token to the idl file, with this we can the ndr_pull/push/print functions for it in the ntacl-lsm module - fix compiler warnings in the ldap_encode_ndr_* code metze (This used to be commit 83d65d0d7ed9c240ad44aa2c881c1f07212bfda4) --- source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index d724e7ceb2..41b1d7965d 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -25,7 +25,7 @@ #include "system/filesys.h" #include "system/passwd.h" #include "auth/auth.h" -#include "libcli/security/security.h" +#include "librpc/gen_ndr/ndr_security.h" #include "smb_server/smb_server.h" struct unixuid_private { -- cgit From ad9022e304ec07e56d2af1aaeb99a6f1faea62aa Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 16 Aug 2005 10:57:21 +0000 Subject: r9320: Fix premature dereference bug found by Coverty and also get rid of non-used memory context (This used to be commit 127e06492a545940443c93e9aec66eebefa26dc2) --- source4/ntvfs/unixuid/vfs_unixuid.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 41b1d7965d..928ff8241b 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -146,8 +146,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct unix_sec_ctx **sec) { struct unixuid_private *private = ntvfs->private_data; - struct security_token *token = req->session->session_info->security_token; - void *ctx = talloc_new(req); + struct security_token *token; struct unix_sec_ctx *newsec; NTSTATUS status; @@ -155,6 +154,8 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } + token = req->session->session_info->security_token; + *sec = save_unix_security(req); if (*sec == NULL) { return NT_STATUS_NO_MEMORY; @@ -165,7 +166,6 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, } else { status = nt_token_to_unix_security(ntvfs, req, token, &newsec); if (!NT_STATUS_IS_OK(status)) { - talloc_free(ctx); return status; } if (private->last_sec_ctx) { @@ -178,12 +178,9 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, status = set_unix_security(newsec); if (!NT_STATUS_IS_OK(status)) { - talloc_free(ctx); return status; } - talloc_free(ctx); - return NT_STATUS_OK; } -- cgit From 5d899b8a35c9ef1e3688fc56495be1c37477e726 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Aug 2005 00:20:40 +0000 Subject: r9369: an attempt to fix the build on HPUX. This is based on work by Don McCall, but takes a slightly different approach that I hope will be more generic (This used to be commit e8260a81cf99be2ccae64135ca0572c8a6ae62ad) --- source4/ntvfs/unixuid/config.m4 | 57 ----------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 source4/ntvfs/unixuid/config.m4 (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/config.m4 b/source4/ntvfs/unixuid/config.m4 deleted file mode 100644 index 2c6777f68e..0000000000 --- a/source4/ntvfs/unixuid/config.m4 +++ /dev/null @@ -1,57 +0,0 @@ - - -################################################ -# look for a method of setting the effective uid -seteuid=no; -if test $seteuid = no; then -AC_CACHE_CHECK([for setresuid],samba_cv_USE_SETRESUID,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETRESUID 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETRESUID=yes,samba_cv_USE_SETRESUID=no,samba_cv_USE_SETRESUID=cross)]) -if test x"$samba_cv_USE_SETRESUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETRESUID,1,[Whether setresuid() is available]) -fi -fi - - -if test $seteuid = no; then -AC_CACHE_CHECK([for setreuid],samba_cv_USE_SETREUID,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETREUID 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETREUID=yes,samba_cv_USE_SETREUID=no,samba_cv_USE_SETREUID=cross)]) -if test x"$samba_cv_USE_SETREUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETREUID,1,[Whether setreuid() is available]) -fi -fi - -if test $seteuid = no; then -AC_CACHE_CHECK([for seteuid],samba_cv_USE_SETEUID,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETEUID 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETEUID=yes,samba_cv_USE_SETEUID=no,samba_cv_USE_SETEUID=cross)]) -if test x"$samba_cv_USE_SETEUID" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETEUID,1,[Whether seteuid() is available]) -fi -fi - -if test $seteuid = no; then -AC_CACHE_CHECK([for setuidx],samba_cv_USE_SETUIDX,[ -AC_TRY_RUN([ -#define AUTOCONF_TEST 1 -#define USE_SETUIDX 1 -#include "confdefs.h" -#include "${srcdir-.}/lib/util_sec.c"], - samba_cv_USE_SETUIDX=yes,samba_cv_USE_SETUIDX=no,samba_cv_USE_SETUIDX=cross)]) -if test x"$samba_cv_USE_SETUIDX" = x"yes"; then - seteuid=yes;AC_DEFINE(USE_SETUIDX,1,[Whether setuidx() is available]) -fi -fi -- cgit From 20f7f49d7fa96969a62cdb570ac048027db14787 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 22 Aug 2005 16:01:01 +0000 Subject: r9478: Fix NTVFS POSIX module to work with EA and blkid after build system changes (This used to be commit 4b89d7c7296dd7abd2d8bcd3f7b702de7314d9ff) --- source4/ntvfs/posix/config.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 75ab531375..7cc4f8e3df 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -28,7 +28,7 @@ AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) AC_SEARCH_LIBS_EXT(flistxattr, [attr], XATTR_LIBS) AC_CHECK_FUNC_EXT(flistxattr, $XATTR_LIBS) SMB_EXT_LIB(XATTR,[${XATTR_LIBS}],[${XATTR_CFLAGS}],[${XATTR_CPPFLAGS}],[${XATTR_LDFLAGS}]) -if test x"$ac_cv_func_flistxattr" = x"yes"; then +if test x"$ac_cv_func_ext_flistxattr" = x"yes"; then AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) fi @@ -36,6 +36,6 @@ AC_CHECK_HEADERS(blkid/blkid.h) AC_SEARCH_LIBS_EXT(blkid_get_cache, [blkid], BLKID_LIBS) AC_CHECK_FUNC_EXT(blkid_get_cache, $BLKID_LIBS) SMB_EXT_LIB(BLKID,[${BLKID_LIBS}],[${BLKID_CFLAGS}],[${BLKID_CPPFLAGS}],[${BLKID_LDFLAGS}]) -if test x"$ac_cv_func_blkid_get_cache" = x"yes"; then +if test x"$ac_cv_func_ext_blkid_get_cache" = x"yes"; then AC_DEFINE(HAVE_LIBBLKID,1,[Whether we have blkid support (e2fsprogs)]) fi -- cgit From e987658582b4c726c461bfb0230ec2db53a032d2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 23 Aug 2005 13:03:39 +0000 Subject: r9517: fix compiler warning: status.v initialized variable used in line 375 tridge: what should be the correct error code? see rev 3239! metze (This used to be commit 27ec849718b97df2d6f30e2fbacaa0423e918862) --- source4/ntvfs/ipc/vfs_ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2c148fbd0c..aa0909ceb6 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -372,7 +372,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, DATA_BLOB data; uint16_t fnum; struct pipe_state *p; - NTSTATUS status; + NTSTATUS status = NT_STATUS_FOOBAR; if (rd->generic.level != RAW_READ_GENERIC) { return ntvfs_map_read(req, rd, ntvfs); -- cgit From b674411eb46c9e45f2740a1f9bac365e9a347e9c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 30 Aug 2005 11:55:05 +0000 Subject: r9792: Rename StrCaseCmp -> strcasecmp_m. All these years I was thinking StrCaseCmp was sys_strcasecmp, while it is in fact strcasecmp_m! (This used to be commit 200a8f6652cb2de7a8037a7a4c2a204b50aee2b1) --- source4/ntvfs/posix/pvfs_dirlist.c | 6 +++--- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_resolve.c | 6 +++--- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_streams.c | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index a055773b51..9838072080 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -283,14 +283,14 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) for (i=dir->name_cache_index;i>=0;i--) { struct name_cache_entry *e = &dir->name_cache[i]; - if (e->name && StrCaseCmp(name, e->name) == 0) { + if (e->name && strcasecmp_m(name, e->name) == 0) { *ofs = e->offset; return NT_STATUS_OK; } } for (i=NAME_CACHE_SIZE-1;i>dir->name_cache_index;i--) { struct name_cache_entry *e = &dir->name_cache[i]; - if (e->name && StrCaseCmp(name, e->name) == 0) { + if (e->name && strcasecmp_m(name, e->name) == 0) { *ofs = e->offset; return NT_STATUS_OK; } @@ -299,7 +299,7 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) rewinddir(dir->dir); while ((de = readdir(dir->dir))) { - if (StrCaseCmp(name, de->d_name) == 0) { + if (strcasecmp_m(name, de->d_name) == 0) { dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE; *ofs = dir->offset; return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 94749600e1..0e2a85bab1 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -734,7 +734,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && (f2->access_mask & SEC_FILE_WRITE_DATA) && - StrCaseCmp(f2->handle->name->original_name, + strcasecmp_m(f2->handle->name->original_name, io->generic.in.fname)==0) { break; } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 4b6afac00a..1f2f86e953 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -82,7 +82,7 @@ NTSTATUS pvfs_query_ea_list(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, eas->eas[i].name.s = names[i].name.s; eas->eas[i].value = data_blob(NULL, 0); for (j=0;jnum_eas;j++) { - if (StrCaseCmp(eas->eas[i].name.s, + if (strcasecmp_m(eas->eas[i].name.s, ealist->eas[j].name) == 0) { eas->eas[i].value = ealist->eas[j].value; break; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 355e82c301..b8e55c85bf 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -38,12 +38,12 @@ static int component_compare(struct pvfs_state *pvfs, const char *comp, const ch { int ret; - ret = StrCaseCmp(comp, name); + ret = strcasecmp_m(comp, name); if (ret != 0) { char *shortname = pvfs_short_name_component(pvfs, name); if (shortname) { - ret = StrCaseCmp(comp, shortname); + ret = strcasecmp_m(comp, shortname); talloc_free(shortname); } } @@ -197,7 +197,7 @@ static NTSTATUS parse_stream_name(struct pvfs_filename *name, const char *s) strlen(name->stream_name)); return NT_STATUS_OK; } - if (StrCaseCmp(p, ":$DATA") != 0) { + if (strcasecmp_m(p, ":$DATA") != 0) { return NT_STATUS_OBJECT_NAME_INVALID; } *p = 0; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 31a60fac18..0753ccb40b 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -186,7 +186,7 @@ NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, struct ea_struct *ea = &eas[j]; /* see if its already there */ for (i=0;inum_eas;i++) { - if (StrCaseCmp(ealist->eas[i].name, ea->name.s) == 0) { + if (strcasecmp_m(ealist->eas[i].name, ea->name.s) == 0) { ealist->eas[i].value = ea->value; break; } diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 2ee5034736..3910baadd0 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -97,7 +97,7 @@ NTSTATUS pvfs_stream_info(struct pvfs_state *pvfs, struct pvfs_filename *name, i for (i=0;inum_streams;i++) { struct xattr_DosStream *s = &streams->streams[i]; - if (StrCaseCmp(s->name, name->stream_name) == 0) { + if (strcasecmp_m(s->name, name->stream_name) == 0) { name->dos.alloc_size = pvfs_round_alloc_size(pvfs, s->alloc_size); name->st.st_size = s->size; name->stream_exists = True; @@ -138,7 +138,7 @@ static NTSTATUS pvfs_stream_update_size(struct pvfs_state *pvfs, struct pvfs_fil for (i=0;inum_streams;i++) { struct xattr_DosStream *s = &streams->streams[i]; - if (StrCaseCmp(s->name, name->stream_name) == 0) { + if (strcasecmp_m(s->name, name->stream_name) == 0) { s->size = size; s->alloc_size = pvfs_round_alloc_size(pvfs, size); break; @@ -216,7 +216,7 @@ NTSTATUS pvfs_stream_delete(struct pvfs_state *pvfs, for (i=0;inum_streams;i++) { struct xattr_DosStream *s = &streams->streams[i]; - if (StrCaseCmp(s->name, name->stream_name) == 0) { + if (strcasecmp_m(s->name, name->stream_name) == 0) { memmove(s, s+1, (streams->num_streams - (i+1)) * sizeof(*s)); streams->num_streams--; break; -- cgit From 89e550ba34d1f00b576aae3d4683ca9ca36afe80 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Aug 2005 12:51:05 +0000 Subject: r9794: r11627@blu: tridge | 2005-08-30 22:55:27 +1000 fill in correct error code for zero length and too large IPC reads (This used to be commit bf6558b8971ccda080d463753ddae977967e7093) --- source4/ntvfs/ipc/vfs_ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index aa0909ceb6..3f91323fe5 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -372,7 +372,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, DATA_BLOB data; uint16_t fnum; struct pipe_state *p; - NTSTATUS status = NT_STATUS_FOOBAR; + NTSTATUS status = NT_STATUS_OK; if (rd->generic.level != RAW_READ_GENERIC) { return ntvfs_map_read(req, rd, ntvfs); @@ -388,7 +388,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, data.length = rd->readx.in.maxcnt; data.data = rd->readx.out.data; if (data.length > UINT16_MAX) { - data.length = 0; + data.length = UINT16_MAX; } if (data.length != 0) { -- cgit From 5fd875ae74b86d7ea532714d47aa74eb2f009ec9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 10 Sep 2005 02:21:44 +0000 Subject: r10138: Fix the mapping table (as tested in smbtorture). EXEC_ACCESS should map to SEC_RIGHTS_FILE_READ, not READ|WRITE. Jeremy. (This used to be commit 26f63973e6207e3b5c3123f1326027ceac38966f) --- source4/ntvfs/ntvfs_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 024a48bf7a..8d2809cf6b 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -259,6 +259,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, switch (open_mode & OPENX_MODE_ACCESS_MASK) { case OPENX_MODE_ACCESS_READ: + case OPENX_MODE_ACCESS_EXEC: io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ; break; case OPENX_MODE_ACCESS_WRITE: @@ -266,7 +267,6 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, break; case OPENX_MODE_ACCESS_RDWR: case OPENX_MODE_ACCESS_FCB: - case OPENX_MODE_ACCESS_EXEC: io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE; -- cgit From 00d69bdf238eeeb38ad7781b5841820796c07d6a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Sep 2005 22:13:50 +0000 Subject: r10148: Use samdb_base_dn() to find the local domain. Andrew Bartlett (This used to be commit 4969f86ac29aa1c4371a5cd01551f45c7fdb4cb2) --- source4/ntvfs/common/sidmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index b29f197b34..95d2b756d9 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -100,8 +100,8 @@ static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap, int ret; struct ldb_message **res = NULL; - ret = gendb_search(sidmap->samctx, mem_ctx, NULL, &res, attrs, - "(&(objectClass=domain)(name=%s))", lp_workgroup()); + ret = gendb_search_dn(sidmap->samctx, mem_ctx, samdb_base_dn(mem_ctx), + &res, attrs); if (ret != 1) { talloc_free(res); return NT_STATUS_NO_SUCH_DOMAIN; -- cgit From 6812c73534001d2dd05a9a74358d2b6d0029f1a7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 20 Sep 2005 11:59:03 +0000 Subject: r10348: Add scons scripts for remaining subsystems. Most subsystems build now, but final linking still fails (as does generating files asn1, et, idl and proto files) (This used to be commit 4f0d7f75b99c7f4388d8acb0838577d86baf68b5) --- source4/ntvfs/SConscript | 11 +++++++++++ source4/ntvfs/posix/SConscript | 10 ++++++++++ source4/ntvfs/unixuid/SConscript | 3 +++ 3 files changed, 24 insertions(+) create mode 100644 source4/ntvfs/SConscript create mode 100644 source4/ntvfs/posix/SConscript create mode 100644 source4/ntvfs/unixuid/SConscript (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/SConscript b/source4/ntvfs/SConscript new file mode 100644 index 0000000000..16047eb4ae --- /dev/null +++ b/source4/ntvfs/SConscript @@ -0,0 +1,11 @@ +Import('hostenv') + +hostenv.StaticLibrary('ntvfs_cifs',['cifs/vfs_cifs.c']) +hostenv.StaticLibrary('ntvfs_simple',['simple/vfs_simple.c','simple/svfs_util.c']) +hostenv.StaticLibrary('ntvfs_print',['print/vfs_print.c']) +hostenv.StaticLibrary('ntvfs_ipc',['ipc/vfs_ipc.c','ipc/ipc_rap.c','ipc/rap_server.c']) +hostenv.StaticLibrary('ntvfs_nbench',['nbench/vfs_nbench.c']) +hostenv.StaticLibrary('ntvfs_common',['common/brlock.c','common/opendb.c','common/sidmap.c']) +hostenv.StaticLibrary('ntvfs',['ntvfs_base.c','ntvfs_generic.c','ntvfs_interface.c','ntvfs_util.c']) + +SConscript(dirs=['unixuid','posix'],exports='hostenv') diff --git a/source4/ntvfs/posix/SConscript b/source4/ntvfs/posix/SConscript new file mode 100644 index 0000000000..a781fe26ea --- /dev/null +++ b/source4/ntvfs/posix/SConscript @@ -0,0 +1,10 @@ +Import('hostenv') + +hostenv.StaticLibrary('ntvfs_posix', + ['vfs_posix.c', 'pvfs_util.c', 'pvfs_search.c', 'pvfs_dirlist.c', + 'pvfs_fileinfo.c', 'pvfs_unlink.c', 'pvfs_mkdir.c', 'pvfs_open.c', + 'pvfs_read.c', 'pvfs_flush.c', 'pvfs_write.c', 'pvfs_fsinfo.c', + 'pvfs_qfileinfo.c', 'pvfs_setfileinfo.c', 'pvfs_rename.c', + 'pvfs_resolve.c', 'pvfs_shortname.c', 'pvfs_lock.c', 'pvfs_wait.c', + 'pvfs_seek.c', 'pvfs_ioctl.c', 'pvfs_xattr.c', 'pvfs_streams.c', + 'pvfs_acl.c', 'xattr_system.c', 'xattr_tdb.c']) diff --git a/source4/ntvfs/unixuid/SConscript b/source4/ntvfs/unixuid/SConscript new file mode 100644 index 0000000000..7e1b304c3f --- /dev/null +++ b/source4/ntvfs/unixuid/SConscript @@ -0,0 +1,3 @@ +Import('hostenv') + +hostenv.StaticLibrary('ntvfs_unixuid',['vfs_unixuid.c']) -- cgit From 4be0ae794e4af2354d678fddd7bf1e822ffa9148 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 Sep 2005 16:32:52 +0000 Subject: r10456: More SCons fixes: - Add framework for fallback generating code - Move pread / pwrite replacement functions to libreplace - Support pidl builds correctly - Support asn1 builds correctly - Move OS-specific checks to lib/replace/SConscript (This used to be commit fbbfad0a1f7dedbf48e835a864f8285f283d72f3) --- source4/ntvfs/simple/vfs_simple.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 86ffab66ba..e9063c38c5 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -40,26 +40,6 @@ #define CHECK_READ_ONLY(req) do { if (lp_readonly(req->tcon->service)) return NT_STATUS_ACCESS_DENIED; } while (0) -#ifndef HAVE_PREAD -static ssize_t pread(int __fd, void *__buf, size_t __nbytes, off_t __offset) -{ - if (lseek(__fd, __offset, SEEK_SET) != __offset) { - return -1; - } - return read(__fd, __buf, __nbytes); -} -#endif - -#ifndef HAVE_PWRITE -static ssize_t pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) -{ - if (lseek(__fd, __offset, SEEK_SET) != __offset) { - return -1; - } - return write(__fd, __buf, __nbytes); -} -#endif - /* connect to a share - used when a tree_connect operation comes in. For a disk based backend we needs to ensure that the base -- cgit From ab4d635b92b116b02b88843b4ec4f5b7517bab1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 26 Sep 2005 11:47:55 +0000 Subject: r10504: - seperate implementation specific stuff, from the generic composite stuff. - don't use SMBCLI_REQUEST_* state's in the genreic composite stuff - move monitor_fn to libnet. NOTE: I have maybe found some bugs, in code that is dirrectly in DONE or ERROR state in the _send() function. I haven't fixed this bugs in this commit! We may need some composite_trigger_*() functions or so. And maybe some other generic helper functions... metze (This used to be commit 4527815a0a9b96e460f301cb1f0c0b3964c166fc) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index f263299cd7..789f24259a 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -29,6 +29,7 @@ #include "lib/events/events.h" #include "libcli/raw/libcliraw.h" #include "libcli/composite/composite.h" +#include "libcli/smb_composite/smb_composite.h" #include "smb_server/smb_server.h" #include "smbd/service_stream.h" -- cgit From f801ad359290c51d3216c755fb2a8344babb484f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Sep 2005 15:59:43 +0000 Subject: r10510: Decrease the amount of data included by includes.h a bit (This used to be commit 03647e1321cf6c9bd6ced3945265f635e9468973) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 789f24259a..04ed1fd7d9 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,6 +32,7 @@ #include "libcli/smb_composite/smb_composite.h" #include "smb_server/smb_server.h" #include "smbd/service_stream.h" +#include "credentials.h" /* this is stored in ntvfs_private */ struct cvfs_private { -- cgit From 42b81d7c3e8ac9ad4c35d5377decbdd5ab18ffbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Sep 2005 10:00:27 +0000 Subject: r10528: Add credentials.h back into includes.h as some compilers don't seem to be able to handle incomplete enum types. (This used to be commit 540155fad3c8e3d79fb631bb3f14273f82130a73) --- source4/ntvfs/cifs/vfs_cifs.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 04ed1fd7d9..789f24259a 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,7 +32,6 @@ #include "libcli/smb_composite/smb_composite.h" #include "smb_server/smb_server.h" #include "smbd/service_stream.h" -#include "credentials.h" /* this is stored in ntvfs_private */ struct cvfs_private { -- cgit From 5058f4b9e82ca8b9f2405930db3a46b8c37f06ed Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Sep 2005 18:18:09 +0000 Subject: r10586: Add MergedObject() builder. Default to Library() rather then StaticLibrary() (This used to be commit b53313dc517986c69a4e4cb8fe3885b696f8faa1) --- source4/ntvfs/SConscript | 14 +++++++------- source4/ntvfs/posix/SConscript | 2 +- source4/ntvfs/unixuid/SConscript | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/SConscript b/source4/ntvfs/SConscript index 16047eb4ae..362eb8df2f 100644 --- a/source4/ntvfs/SConscript +++ b/source4/ntvfs/SConscript @@ -1,11 +1,11 @@ Import('hostenv') -hostenv.StaticLibrary('ntvfs_cifs',['cifs/vfs_cifs.c']) -hostenv.StaticLibrary('ntvfs_simple',['simple/vfs_simple.c','simple/svfs_util.c']) -hostenv.StaticLibrary('ntvfs_print',['print/vfs_print.c']) -hostenv.StaticLibrary('ntvfs_ipc',['ipc/vfs_ipc.c','ipc/ipc_rap.c','ipc/rap_server.c']) -hostenv.StaticLibrary('ntvfs_nbench',['nbench/vfs_nbench.c']) -hostenv.StaticLibrary('ntvfs_common',['common/brlock.c','common/opendb.c','common/sidmap.c']) -hostenv.StaticLibrary('ntvfs',['ntvfs_base.c','ntvfs_generic.c','ntvfs_interface.c','ntvfs_util.c']) +hostenv.Library('ntvfs_cifs',['cifs/vfs_cifs.c']) +hostenv.Library('ntvfs_simple',['simple/vfs_simple.c','simple/svfs_util.c']) +hostenv.Library('ntvfs_print',['print/vfs_print.c']) +hostenv.Library('ntvfs_ipc',['ipc/vfs_ipc.c','ipc/ipc_rap.c','ipc/rap_server.c']) +hostenv.Library('ntvfs_nbench',['nbench/vfs_nbench.c']) +hostenv.Library('ntvfs_common',['common/brlock.c','common/opendb.c','common/sidmap.c']) +hostenv.Library('ntvfs',['ntvfs_base.c','ntvfs_generic.c','ntvfs_interface.c','ntvfs_util.c']) SConscript(dirs=['unixuid','posix'],exports='hostenv') diff --git a/source4/ntvfs/posix/SConscript b/source4/ntvfs/posix/SConscript index a781fe26ea..fc89530fcc 100644 --- a/source4/ntvfs/posix/SConscript +++ b/source4/ntvfs/posix/SConscript @@ -1,6 +1,6 @@ Import('hostenv') -hostenv.StaticLibrary('ntvfs_posix', +hostenv.Library('ntvfs_posix', ['vfs_posix.c', 'pvfs_util.c', 'pvfs_search.c', 'pvfs_dirlist.c', 'pvfs_fileinfo.c', 'pvfs_unlink.c', 'pvfs_mkdir.c', 'pvfs_open.c', 'pvfs_read.c', 'pvfs_flush.c', 'pvfs_write.c', 'pvfs_fsinfo.c', diff --git a/source4/ntvfs/unixuid/SConscript b/source4/ntvfs/unixuid/SConscript index 7e1b304c3f..d3134c3183 100644 --- a/source4/ntvfs/unixuid/SConscript +++ b/source4/ntvfs/unixuid/SConscript @@ -1,3 +1,3 @@ Import('hostenv') -hostenv.StaticLibrary('ntvfs_unixuid',['vfs_unixuid.c']) +hostenv.Library('ntvfs_unixuid',['vfs_unixuid.c']) -- cgit From 68c70ef396f84077dd08f97bf700f0c2963c8676 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 2 Oct 2005 10:02:35 +0000 Subject: r10677: Add smb_composite_connectmulti: Send out multiple SYN packets at once, use the first one that replies correctly. Add a talloc context to smb_composite_connect() Volker (This used to be commit 6b88de182e40cb00a833c085f801fd47c92bbe94) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 789f24259a..0ad0425415 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -134,7 +134,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.service = remote_share; io.in.service_type = "?????"; - creq = smb_composite_connect_send(&io, tcon->smb_conn->connection->event.ctx); + creq = smb_composite_connect_send(&io, private, tcon->smb_conn->connection->event.ctx); status = smb_composite_connect_recv(creq, private); NT_STATUS_NOT_OK_RETURN(status); -- cgit From 1377cca5f4beb43cf67fcc65eed79f14178d6349 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Oct 2005 11:31:45 +0000 Subject: r10810: This adds the hooks required to communicate the current user from the authenticated session down into LDB. This associates a session info structure with the open LDB, allowing a future ldb_ntacl module to allow/deny operations on that basis. Along the way, I cleaned up a few things, and added new helper functions to assist. In particular the LSA pipe uses simpler queries for some of the setup. In ldap_server, I have removed the 'ldasrv:hacked' module, which hasn't been worked on (other than making it continue to compile) since January, and I think the features of this module are being put into ldb anyway. I have also changed the partitions in ldap_server to be initialised after the connection, with the private pointer used to associate the ldb with the incoming session. Andrew Bartlett (This used to be commit fd7203789a2c0929eecea8125b57b833a67fed71) --- source4/ntvfs/common/sidmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 95d2b756d9..f3ee938d84 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -52,7 +52,7 @@ struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx) if (sidmap == NULL) { return NULL; } - sidmap->samctx = samdb_connect(sidmap); + sidmap->samctx = samdb_connect(sidmap, system_session(sidmap)); if (sidmap->samctx == NULL) { talloc_free(sidmap); return NULL; -- cgit From d617556ef50863d6a03c81a04f0f6b05848a250e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Oct 2005 19:57:55 +0000 Subject: r10878: Reply to some comments by tridge and metze: * rename the composite helper functions from comp_* to composite_* * Move the lsa initialization to wb_connect_lsa.c * Equip smb_composite_connect with a fallback_to_anonymous The latter two simplify wb_init_domain.c quite a bit. Volker (This used to be commit deb127e04ea01ae93394da5ebffb39d81caeb6d9) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 0ad0425415..cb6fbb3880 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -130,6 +130,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.port = 0; io.in.called_name = host; io.in.credentials = credentials; + io.in.fallback_to_anonymous = False; io.in.workgroup = lp_workgroup(); io.in.service = remote_share; io.in.service_type = "?????"; -- cgit From f4d590662effeb80c2b55ae5ad869b4b7810cf08 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Oct 2005 10:04:57 +0000 Subject: r11214: Remove scons files (see http://lists.samba.org/archive/samba-technical/2005-October/043443.html) (This used to be commit 7fffc5c9178158249be632ac0ca179c13bd1f98f) --- source4/ntvfs/SConscript | 11 ----------- source4/ntvfs/posix/SConscript | 10 ---------- source4/ntvfs/unixuid/SConscript | 3 --- 3 files changed, 24 deletions(-) delete mode 100644 source4/ntvfs/SConscript delete mode 100644 source4/ntvfs/posix/SConscript delete mode 100644 source4/ntvfs/unixuid/SConscript (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/SConscript b/source4/ntvfs/SConscript deleted file mode 100644 index 362eb8df2f..0000000000 --- a/source4/ntvfs/SConscript +++ /dev/null @@ -1,11 +0,0 @@ -Import('hostenv') - -hostenv.Library('ntvfs_cifs',['cifs/vfs_cifs.c']) -hostenv.Library('ntvfs_simple',['simple/vfs_simple.c','simple/svfs_util.c']) -hostenv.Library('ntvfs_print',['print/vfs_print.c']) -hostenv.Library('ntvfs_ipc',['ipc/vfs_ipc.c','ipc/ipc_rap.c','ipc/rap_server.c']) -hostenv.Library('ntvfs_nbench',['nbench/vfs_nbench.c']) -hostenv.Library('ntvfs_common',['common/brlock.c','common/opendb.c','common/sidmap.c']) -hostenv.Library('ntvfs',['ntvfs_base.c','ntvfs_generic.c','ntvfs_interface.c','ntvfs_util.c']) - -SConscript(dirs=['unixuid','posix'],exports='hostenv') diff --git a/source4/ntvfs/posix/SConscript b/source4/ntvfs/posix/SConscript deleted file mode 100644 index fc89530fcc..0000000000 --- a/source4/ntvfs/posix/SConscript +++ /dev/null @@ -1,10 +0,0 @@ -Import('hostenv') - -hostenv.Library('ntvfs_posix', - ['vfs_posix.c', 'pvfs_util.c', 'pvfs_search.c', 'pvfs_dirlist.c', - 'pvfs_fileinfo.c', 'pvfs_unlink.c', 'pvfs_mkdir.c', 'pvfs_open.c', - 'pvfs_read.c', 'pvfs_flush.c', 'pvfs_write.c', 'pvfs_fsinfo.c', - 'pvfs_qfileinfo.c', 'pvfs_setfileinfo.c', 'pvfs_rename.c', - 'pvfs_resolve.c', 'pvfs_shortname.c', 'pvfs_lock.c', 'pvfs_wait.c', - 'pvfs_seek.c', 'pvfs_ioctl.c', 'pvfs_xattr.c', 'pvfs_streams.c', - 'pvfs_acl.c', 'xattr_system.c', 'xattr_tdb.c']) diff --git a/source4/ntvfs/unixuid/SConscript b/source4/ntvfs/unixuid/SConscript deleted file mode 100644 index d3134c3183..0000000000 --- a/source4/ntvfs/unixuid/SConscript +++ /dev/null @@ -1,3 +0,0 @@ -Import('hostenv') - -hostenv.Library('ntvfs_unixuid',['vfs_unixuid.c']) -- cgit From 4c5a4a7e0288e9ac0b2f795befd5684059e4c429 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Oct 2005 16:29:54 +0000 Subject: r11244: Relative path names in .mk files (This used to be commit 24e10300906c380919d2d631bfb3b8fd6b3f54ba) --- source4/ntvfs/config.mk | 32 +++++++++++++------------ source4/ntvfs/posix/config.mk | 52 ++++++++++++++++++++--------------------- source4/ntvfs/unixuid/config.mk | 2 +- 3 files changed, 44 insertions(+), 42 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 55f8270de2..a61c84770d 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -1,4 +1,6 @@ # NTVFS Server subsystem +include posix/config.mk +include unixuid/config.mk ################################################ # Start MODULE ntvfs_cifs @@ -6,7 +8,7 @@ INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ - ntvfs/cifs/vfs_cifs.o + cifs/vfs_cifs.o REQUIRED_SUBSYSTEMS = \ LIBCLI # End MODULE ntvfs_cifs @@ -18,9 +20,9 @@ REQUIRED_SUBSYSTEMS = \ INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ - ntvfs/simple/vfs_simple.o + simple/vfs_simple.o ADD_OBJ_FILES = \ - ntvfs/simple/svfs_util.o + simple/svfs_util.o # End MODULE ntvfs_cifs ################################################ @@ -30,7 +32,7 @@ ADD_OBJ_FILES = \ INIT_FUNCTION = ntvfs_print_init SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ - ntvfs/print/vfs_print.o + print/vfs_print.o # End MODULE ntvfs_print ################################################ @@ -40,9 +42,9 @@ INIT_OBJ_FILES = \ SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_ipc_init INIT_OBJ_FILES = \ - ntvfs/ipc/vfs_ipc.o \ - ntvfs/ipc/ipc_rap.o \ - ntvfs/ipc/rap_server.o + ipc/vfs_ipc.o \ + ipc/ipc_rap.o \ + ipc/rap_server.o # End MODULE ntvfs_ipc ################################################ @@ -54,7 +56,7 @@ INIT_OBJ_FILES = \ SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_nbench_init INIT_OBJ_FILES = \ - ntvfs/nbench/vfs_nbench.o + nbench/vfs_nbench.o # End MODULE ntvfs_nbench ################################################ @@ -62,9 +64,9 @@ INIT_OBJ_FILES = \ # Start SUBSYSTEM ntvfs_common [SUBSYSTEM::ntvfs_common] ADD_OBJ_FILES = \ - ntvfs/common/brlock.o \ - ntvfs/common/opendb.o \ - ntvfs/common/sidmap.o + common/brlock.o \ + common/opendb.o \ + common/sidmap.o # End SUBSYSTEM ntvfs_common ################################################ @@ -73,11 +75,11 @@ ADD_OBJ_FILES = \ # Start SUBSYSTEM NTVFS [SUBSYSTEM::NTVFS] INIT_OBJ_FILES = \ - ntvfs/ntvfs_base.o + ntvfs_base.o ADD_OBJ_FILES = \ - ntvfs/ntvfs_generic.o \ - ntvfs/ntvfs_interface.o \ - ntvfs/ntvfs_util.o + ntvfs_generic.o \ + ntvfs_interface.o \ + ntvfs_util.o # # End SUBSYSTEM NTVFS ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 9be3723056..cf406890c9 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -4,33 +4,33 @@ SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_posix_init INIT_OBJ_FILES = \ - ntvfs/posix/vfs_posix.o + vfs_posix.o ADD_OBJ_FILES = \ - ntvfs/posix/pvfs_util.o \ - ntvfs/posix/pvfs_search.o \ - ntvfs/posix/pvfs_dirlist.o \ - ntvfs/posix/pvfs_fileinfo.o \ - ntvfs/posix/pvfs_unlink.o \ - ntvfs/posix/pvfs_mkdir.o \ - ntvfs/posix/pvfs_open.o \ - ntvfs/posix/pvfs_read.o \ - ntvfs/posix/pvfs_flush.o \ - ntvfs/posix/pvfs_write.o \ - ntvfs/posix/pvfs_fsinfo.o \ - ntvfs/posix/pvfs_qfileinfo.o \ - ntvfs/posix/pvfs_setfileinfo.o \ - ntvfs/posix/pvfs_rename.o \ - ntvfs/posix/pvfs_resolve.o \ - ntvfs/posix/pvfs_shortname.o \ - ntvfs/posix/pvfs_lock.o \ - ntvfs/posix/pvfs_wait.o \ - ntvfs/posix/pvfs_seek.o \ - ntvfs/posix/pvfs_ioctl.o \ - ntvfs/posix/pvfs_xattr.o \ - ntvfs/posix/pvfs_streams.o \ - ntvfs/posix/pvfs_acl.o \ - ntvfs/posix/xattr_system.o \ - ntvfs/posix/xattr_tdb.o + pvfs_util.o \ + pvfs_search.o \ + pvfs_dirlist.o \ + pvfs_fileinfo.o \ + pvfs_unlink.o \ + pvfs_mkdir.o \ + pvfs_open.o \ + pvfs_read.o \ + pvfs_flush.o \ + pvfs_write.o \ + pvfs_fsinfo.o \ + pvfs_qfileinfo.o \ + pvfs_setfileinfo.o \ + pvfs_rename.o \ + pvfs_resolve.o \ + pvfs_shortname.o \ + pvfs_lock.o \ + pvfs_wait.o \ + pvfs_seek.o \ + pvfs_ioctl.o \ + pvfs_xattr.o \ + pvfs_streams.o \ + pvfs_acl.o \ + xattr_system.o \ + xattr_tdb.o REQUIRED_SUBSYSTEMS = NDR_XATTR ntvfs_common EXT_LIB_XATTR EXT_LIB_BLKID # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 34c8f0c2b4..b9c8000384 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -4,7 +4,7 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = NTVFS INIT_OBJ_FILES = \ - ntvfs/unixuid/vfs_unixuid.o + vfs_unixuid.o REQUIRED_SUBSYSTEMS = \ ntvfs_common # End MODULE ntvfs_unixuid -- cgit From 3b2a6997b43dcfe37adf67c84e564a4fbff5b108 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Nov 2005 00:31:22 +0000 Subject: r11452: Update Heimdal to current lorikeet, including removing the ccache side of the gsskrb5_acquire_cred hack. Add support for delegated credentials into the auth and credentials subsystem, and specifically into gensec_gssapi. Add the CIFS NTVFS handler as a consumer of delegated credentials, when no user/domain/password is specified. Andrew Bartlett (This used to be commit 55b89899adb692d90e63873ccdf80b9f94a6b448) --- source4/ntvfs/cifs/vfs_cifs.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index cb6fbb3880..5d0576e8f9 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,6 +32,7 @@ #include "libcli/smb_composite/smb_composite.h" #include "smb_server/smb_server.h" #include "smbd/service_stream.h" +#include "auth/auth.h" /* this is stored in ntvfs_private */ struct cvfs_private { @@ -106,11 +107,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, remote_share = sharename; } - if (!host || !user || !pass || !domain) { - DEBUG(1,("CIFS backend: You must supply server, user, password and domain\n")); - return NT_STATUS_INVALID_PARAMETER; - } - private = talloc(req->tcon, struct cvfs_private); if (!private) { return NT_STATUS_NO_MEMORY; @@ -119,11 +115,23 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; - credentials = cli_credentials_init(private); - cli_credentials_set_username(credentials, user, CRED_SPECIFIED); - cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); - cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); - cli_credentials_set_workstation(credentials, "vfs_cifs", CRED_SPECIFIED); + if (!host) { + DEBUG(1,("CIFS backend: You must supply server\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (user && pass && domain) { + credentials = cli_credentials_init(private); + cli_credentials_set_username(credentials, user, CRED_SPECIFIED); + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); + cli_credentials_set_workstation(credentials, "vfs_cifs", CRED_SPECIFIED); + } else if (req->session->session_info->credentials) { + credentials = req->session->session_info->credentials; + } else { + DEBUG(1,("CIFS backend: You must supply server, user, password and domain or have delegated credentials\n")); + return NT_STATUS_INVALID_PARAMETER; + } /* connect to the server, using the smbd event context */ io.in.dest_host = host; -- cgit From e3b42c55ebd7e16853ceb7da73e8d4ccf74e3a13 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Nov 2005 04:24:04 +0000 Subject: r11471: Describe how kerberos forwarding works with the ntvfs. Andrew Bartlett (This used to be commit 66d7a51394b26bf9e8737477af965d08d9efde6d) --- source4/ntvfs/cifs/README | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/README b/source4/ntvfs/cifs/README index c6232fe2db..31720612c2 100644 --- a/source4/ntvfs/cifs/README +++ b/source4/ntvfs/cifs/README @@ -3,8 +3,13 @@ backend that talks to a remote CIFS server. The primary aim of this backend is for debugging and development, although some poeple may find it useful as a CIFS gateway. +There are two modes of operation: Password specified and delegated +credentials. -Here is a typical config: +Password specified: +------------------- + +This uses a static username/password in the config file, example: [myshare] ntvfs handler = cifs @@ -14,3 +19,22 @@ Here is a typical config: cifs:domain = TESTDOM cifs:share = test + +Delegated credentials: +---------------------- + +If your incoming user is authenticated with Kerberos, and the machine +account for this Samba4 proxy server is 'trusted for delegation', then +the Samba4 proxy can forward the client's credentials to the target. + +You must be joined to the domain (net join member). + +To set 'trusted for delegation' with MMC, see the checkbox in the +Computer account property page under Users and Computers. + +[myshare] + ntvfs handler = cifs + cifs:server = myserver + cifs:share = test + + -- cgit From 79cb46c1af526635c31b03612cd9f0d9ea97a5be Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Nov 2005 06:36:42 +0000 Subject: r11513: Add the ability to use the local machine account instead of a static password or delegation. Add the ability to delegate for RPC pipes on the RPC proxy backend (the backend itself seems be having problems however). Andrew Bartlett (This used to be commit a7e946bc37e4acfbe2c483b4f1ead0341f9b3d19) --- source4/ntvfs/cifs/vfs_cifs.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 5d0576e8f9..44c31d91ad 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -93,6 +93,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct fd_event *fde; struct cli_credentials *credentials; + BOOL machine_account; /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. @@ -107,6 +108,8 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, remote_share = sharename; } + machine_account = lp_parm_bool(req->tcon->service, "cifs", "use_machine_account", False); + private = talloc(req->tcon, struct cvfs_private); if (!private) { return NT_STATUS_NO_MEMORY; @@ -120,16 +123,34 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - if (user && pass && domain) { + if (user && pass) { + DEBUG(5, ("CIFS backend: Using specified password\n")); credentials = cli_credentials_init(private); + if (!credentials) { + return NT_STATUS_NO_MEMORY; + } + cli_credentials_set_conf(credentials); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); - cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + if (domain) { + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + } cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); - cli_credentials_set_workstation(credentials, "vfs_cifs", CRED_SPECIFIED); + } else if (machine_account) { + DEBUG(5, ("CIFS backend: Using machine account\n")); + credentials = cli_credentials_init(private); + cli_credentials_set_conf(credentials); + if (domain) { + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + } + status = cli_credentials_set_machine_account(credentials); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } else if (req->session->session_info->credentials) { + DEBUG(5, ("CIFS backend: Using delegated credentials\n")); credentials = req->session->session_info->credentials; } else { - DEBUG(1,("CIFS backend: You must supply server, user, password and domain or have delegated credentials\n")); + DEBUG(1,("CIFS backend: You must supply server, user and password and or have delegated credentials\n")); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 72c28b3c1e522773fd160c1f977e464a05016035 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 6 Nov 2005 13:21:22 +0000 Subject: r11534: Consider ntvfs as a library (This used to be commit f9bbc83f5316773520ce06c267ac9c0f1eb189e6) --- source4/ntvfs/config.mk | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index a61c84770d..2ab484610e 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -73,7 +73,11 @@ ADD_OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS -[SUBSYSTEM::NTVFS] +[LIBRARY::NTVFS] +PUBLIC_HEADERS = ntvfs.h +MAJOR_VERSION = 0 +MINOR_VERSION = 0 +RELEASE_VERSION = 1 INIT_OBJ_FILES = \ ntvfs_base.o ADD_OBJ_FILES = \ -- cgit From 1c07c25322802eef7b57dda3975baca6c9114c83 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 9 Nov 2005 08:13:41 +0000 Subject: r11596: switched the libcli/raw/ code over to using the lib/stream/ generic packet parsing code. This simplifies the logic in the raw client library a fair bit (This used to be commit f8d43f1f67876360e1295d85a3c3702d1d60ed7b) --- source4/ntvfs/cifs/vfs_cifs.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 44c31d91ad..b0d0d06552 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -63,21 +63,6 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin return req_send_oplock_break(private->tcon, fnum, level); } - /* - a handler for read events on a connection to a backend server -*/ -static void cifs_socket_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) -{ - struct cvfs_private *cvfs = talloc_get_type(private, struct cvfs_private); - struct smbsrv_tcon *tcon = cvfs->tcon; - - if (!smbcli_transport_process(cvfs->transport)) { - /* the connection to our server is dead */ - talloc_free(tcon); - } -} - /* connect to a share - used when a tree_connect operation comes in. */ @@ -90,7 +75,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, const char *host, *user, *pass, *domain, *remote_share; struct smb_composite_connect io; struct composite_context *creq; - struct fd_event *fde; struct cli_credentials *credentials; BOOL machine_account; @@ -180,17 +164,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); - /* take over event handling for this socket */ - talloc_free(private->transport->socket->event.fde); - fde = event_add_fd(private->transport->socket->event.ctx, - private, - socket_get_fd(private->transport->socket->sock), - EVENT_FD_READ | EVENT_FD_WRITE, - cifs_socket_handler, - private); - private->transport->socket->event.fde = fde; - - private->map_generic = lp_parm_bool(req->tcon->service, "cifs", "mapgeneric", False); -- cgit From 3c016355e44afbb10ee02b9ba09e107355b27f7a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Dec 2005 14:53:56 +0000 Subject: r12019: - let us only reference libblkid stuff in one file - and make it it bit simpler, by caching the GUID struct instead of the device name - and this also removes all compiler warnings... metze (This used to be commit f4f0d626e00116e85a91962bf8534c1fbb69334c) --- source4/ntvfs/posix/pvfs_fsinfo.c | 94 ++++++++++++++++++++++++--------------- source4/ntvfs/posix/vfs_posix.c | 3 -- source4/ntvfs/posix/vfs_posix.h | 15 +------ 3 files changed, 58 insertions(+), 54 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 3a95ed3ff5..be87599b87 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -26,19 +26,62 @@ /* We use libblkid out of e2fsprogs to identify UUID of a volume */ #ifdef HAVE_LIBBLKID -static int blkid_cache_destructor(void * cache_wrap) { - blkid_cache_wrap_t * cache = (blkid_cache_wrap_t *)cache_wrap; - blkid_put_cache(cache->cache); - if(cache->devname) free((void *)cache->devname); - return 0; -} +#include +#endif + +static NTSTATUS pvfs_blkid_fs_uuid(struct pvfs_state *pvfs, struct stat *st, struct GUID *uuid) +{ +#ifdef HAVE_LIBBLKID + NTSTATUS status; + char *uuid_value = NULL; + char *devname = NULL; + + devname = blkid_devno_to_devname(st->st_dev); + if (!devname) { + return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + } + + uuid_value = blkid_get_tag_value(NULL, "UUID", devname); + free(devname); + if (!uuid_value) { + return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + } + + status = GUID_from_string(uuid_value, uuid); + free(uuid_value); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + } + return NT_STATUS_OK; +#else + ZERO_STRUCTP(uuid); + return NT_STATUS_OK; #endif +} + +static NTSTATUS pvfs_cache_base_fs_uuid(struct pvfs_state *pvfs, struct stat *st) +{ + NTSTATUS status; + struct GUID uuid; + + if (pvfs->base_fs_uuid) return NT_STATUS_OK; + + status = pvfs_blkid_fs_uuid(pvfs, st, &uuid); + NT_STATUS_NOT_OK_RETURN(status); + + pvfs->base_fs_uuid = talloc(pvfs, struct GUID); + NT_STATUS_HAVE_NO_MEMORY(pvfs->base_fs_uuid); + *pvfs->base_fs_uuid = uuid; + + return NT_STATUS_OK; +} /* return filesystem space info */ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, union smb_fsinfo *fs) { + NTSTATUS status; struct pvfs_state *pvfs = ntvfs->private_data; uint64_t blocks_free, blocks_total; uint_t bpunit; @@ -145,38 +188,15 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; case RAW_QFS_OBJECTID_INFORMATION: - { -#ifdef HAVE_LIBBLKID - NTSTATUS status; - const char *uuid_value; -#endif - ZERO_STRUCT(fs->objectid_information.out); -#ifdef HAVE_LIBBLKID - if (!pvfs->blkid_cache) { - pvfs->blkid_cache = talloc(ntvfs, blkid_cache_wrap_t); - - if (!pvfs->blkid_cache) { - return NT_STATUS_NO_MEMORY; - } - - pvfs->blkid_cache->cache = NULL; - pvfs->blkid_cache->devname = blkid_devno_to_devname(st.st_dev); - - talloc_set_destructor(pvfs->blkid_cache, blkid_cache_destructor); - - if (blkid_get_cache(&pvfs->blkid_cache->cache,NULL) < 0 ) { - return NT_STATUS_DEVICE_CONFIGURATION_ERROR; - } - } - - if ((uuid_value = blkid_get_tag_value(pvfs->blkid_cache->cache, - "UUID", pvfs->blkid_cache->devname))) { - GUID_from_string(uuid_value, &fs->objectid_information.out.guid); - free((void*)uuid_value); - } -#endif + ZERO_STRUCT(fs->objectid_information.out.guid); + ZERO_STRUCT(fs->objectid_information.out.unknown); + + status = pvfs_cache_base_fs_uuid(pvfs, &st); + NT_STATUS_NOT_OK_RETURN(status); + + fs->objectid_information.out.guid = *pvfs->base_fs_uuid; return NT_STATUS_OK; - } + default: break; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index a4b15e3c57..bedc81389c 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -95,9 +95,6 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->sid_cache.creator_owner = dom_sid_parse_talloc(pvfs, SID_CREATOR_OWNER); pvfs->sid_cache.creator_group = dom_sid_parse_talloc(pvfs, SID_CREATOR_GROUP); -#ifdef HAVE_BLKID - pvfs->blkid_cache = NULL; -#endif /* check if the system really supports xattrs */ if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index f18864197d..9eec368157 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -26,21 +26,12 @@ #include "system/filesys.h" #include "smb_server/smb_server.h" -/* We use libblkid out of e2fsprogs to identify UUID of a volume */ -#ifdef HAVE_LIBBLKID -#include - -typedef struct { - blkid_cache cache; - const char *devname; -} blkid_cache_wrap_t; -#endif - /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ struct pvfs_state { struct smbsrv_tcon *tcon; const char *base_directory; + struct GUID *base_fs_uuid; const char *share_name; uint_t flags; @@ -83,10 +74,6 @@ struct pvfs_state { const struct dom_sid *creator_owner; const struct dom_sid *creator_group; } sid_cache; - -#ifdef HAVE_LIBBLKID - blkid_cache_wrap_t *blkid_cache; -#endif }; /* this is the basic information needed about a file from the filesystem */ -- cgit From ab31a4421688142690a7903388abeb0786e7f4f9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 15 Dec 2005 16:32:08 +0000 Subject: r12254: Add some (hopefully correct) descriptions for libraries that are installed. Install pkg-config files. (This used to be commit a86abe84e2cae7c6188c094a92c6b62aace02fdf) --- source4/ntvfs/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 2ab484610e..95f0886d06 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -77,6 +77,7 @@ ADD_OBJ_FILES = \ PUBLIC_HEADERS = ntvfs.h MAJOR_VERSION = 0 MINOR_VERSION = 0 +DESCRIPTION = Virtual File System with NTFS semantics RELEASE_VERSION = 1 INIT_OBJ_FILES = \ ntvfs_base.o -- cgit From 448483199fb436309735f5203b3282fca2c517ec Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 16:46:55 +0000 Subject: r12494: Support loading modules from .so files for most subsystems. We now use a different system for initializing the modules for a subsystem. Most subsystems now have an init function that looks something like this: init_module_fn static_init[] = STATIC_AUTH_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "auth"); run_init_functions(static_init); run_init_functions(shared_init); talloc_free(shared_init); I hope to eliminate the other init functions later on (the init_programname_subsystems; defines). (This used to be commit b6d2ad4ce0a91c4be790dd258820c492ff1787ea) --- source4/ntvfs/config.mk | 1 + source4/ntvfs/ntvfs_base.c | 13 +++++++++++++ 2 files changed, 14 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 95f0886d06..a600a9a9a0 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -77,6 +77,7 @@ ADD_OBJ_FILES = \ PUBLIC_HEADERS = ntvfs.h MAJOR_VERSION = 0 MINOR_VERSION = 0 +INIT_FUNCTION = ntvfs_init DESCRIPTION = Virtual File System with NTFS semantics RELEASE_VERSION = 1 INIT_OBJ_FILES = \ diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index b8aeed419c..9cb8293cbc 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -158,3 +158,16 @@ NTSTATUS ntvfs_init_connection(struct smbsrv_request *req, enum ntvfs_type type) return NT_STATUS_OK; } + +NTSTATUS ntvfs_init(void) +{ + init_module_fn static_init[] = STATIC_NTVFS_MODULES; + init_module_fn *shared_init = load_samba_modules(NULL, "ntvfs"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); + + return NT_STATUS_OK; +} -- cgit From d8e35f882879e189f55b3bca818dd44cc5f0c6fa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 18:03:50 +0000 Subject: r12498: Eliminate INIT_OBJ_FILES and ADD_OBJ_FILES. We were not using the difference between these at all, and in the future the fact that INIT_OBJ_FILES include smb_build.h will be sufficient to have recompiles at the right time. (This used to be commit b24f2583edee38abafa58578d8b5c4b43e517def) --- source4/ntvfs/config.mk | 20 +++++++++----------- source4/ntvfs/posix/config.mk | 5 ++--- source4/ntvfs/unixuid/config.mk | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index a600a9a9a0..1c37a608bf 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -7,7 +7,7 @@ include unixuid/config.mk [MODULE::ntvfs_cifs] INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = NTVFS -INIT_OBJ_FILES = \ +OBJ_FILES = \ cifs/vfs_cifs.o REQUIRED_SUBSYSTEMS = \ LIBCLI @@ -19,9 +19,8 @@ REQUIRED_SUBSYSTEMS = \ [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = NTVFS -INIT_OBJ_FILES = \ - simple/vfs_simple.o -ADD_OBJ_FILES = \ +OBJ_FILES = \ + simple/vfs_simple.o \ simple/svfs_util.o # End MODULE ntvfs_cifs ################################################ @@ -31,7 +30,7 @@ ADD_OBJ_FILES = \ [MODULE::ntvfs_print] INIT_FUNCTION = ntvfs_print_init SUBSYSTEM = NTVFS -INIT_OBJ_FILES = \ +OBJ_FILES = \ print/vfs_print.o # End MODULE ntvfs_print ################################################ @@ -41,7 +40,7 @@ INIT_OBJ_FILES = \ [MODULE::ntvfs_ipc] SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_ipc_init -INIT_OBJ_FILES = \ +OBJ_FILES = \ ipc/vfs_ipc.o \ ipc/ipc_rap.o \ ipc/rap_server.o @@ -55,7 +54,7 @@ INIT_OBJ_FILES = \ [MODULE::ntvfs_nbench] SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_nbench_init -INIT_OBJ_FILES = \ +OBJ_FILES = \ nbench/vfs_nbench.o # End MODULE ntvfs_nbench ################################################ @@ -63,7 +62,7 @@ INIT_OBJ_FILES = \ ################################################ # Start SUBSYSTEM ntvfs_common [SUBSYSTEM::ntvfs_common] -ADD_OBJ_FILES = \ +OBJ_FILES = \ common/brlock.o \ common/opendb.o \ common/sidmap.o @@ -80,9 +79,8 @@ MINOR_VERSION = 0 INIT_FUNCTION = ntvfs_init DESCRIPTION = Virtual File System with NTFS semantics RELEASE_VERSION = 1 -INIT_OBJ_FILES = \ - ntvfs_base.o -ADD_OBJ_FILES = \ +OBJ_FILES = \ + ntvfs_base.o \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index cf406890c9..53c51cf805 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -3,9 +3,8 @@ [MODULE::ntvfs_posix] SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_posix_init -INIT_OBJ_FILES = \ - vfs_posix.o -ADD_OBJ_FILES = \ +OBJ_FILES = \ + vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ pvfs_dirlist.o \ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index b9c8000384..d99229729c 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -3,7 +3,7 @@ [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = NTVFS -INIT_OBJ_FILES = \ +OBJ_FILES = \ vfs_unixuid.o REQUIRED_SUBSYSTEMS = \ ntvfs_common -- cgit From 6aafed9600a3fa05932668c70fc0e20f3724dab6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 18:48:23 +0000 Subject: r12499: Move smb_build.h out of includes.h (This used to be commit c92ace494f92084ddf178626cdf392d151043bc7) --- source4/ntvfs/ntvfs_base.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 9cb8293cbc..1b021527de 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -26,8 +26,7 @@ #include "includes.h" #include "dlinklist.h" #include "smb_server/smb_server.h" - - +#include "smb_build.h" /* the list of currently registered NTVFS backends, note that there * can be more than one backend with the same name, as long as they -- cgit From 09c44f6cae89621871d2e5475b0c0f99c25804b4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 Dec 2005 21:58:31 +0000 Subject: r12500: Use init functions explicitly in a few more places. 'gensec' and 'librpc' are the only two subsystems left to convert. (This used to be commit f6bbc72996aeee8607fc583140fd60be0e06e969) --- source4/ntvfs/config.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 1c37a608bf..bc39d82156 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -76,7 +76,6 @@ OBJ_FILES = \ PUBLIC_HEADERS = ntvfs.h MAJOR_VERSION = 0 MINOR_VERSION = 0 -INIT_FUNCTION = ntvfs_init DESCRIPTION = Virtual File System with NTFS semantics RELEASE_VERSION = 1 OBJ_FILES = \ -- cgit From 0a3c167f6bcf08b2204ca49831ca49eef73dcbf4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Dec 2005 22:51:30 +0000 Subject: r12528: Add seperate proto headers for ntvfs, tdr, smb_server and nbt_server. (This used to be commit 87f665a1d5ba74289974bf9d8f9441c162e6f1b1) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + source4/ntvfs/config.mk | 1 + source4/ntvfs/ipc/vfs_ipc.c | 1 + source4/ntvfs/nbench/vfs_nbench.c | 1 + source4/ntvfs/ntvfs.h | 2 ++ source4/ntvfs/ntvfs_base.c | 1 + source4/ntvfs/ntvfs_generic.c | 1 + source4/ntvfs/ntvfs_interface.c | 2 +- source4/ntvfs/ntvfs_util.c | 1 + source4/ntvfs/posix/vfs_posix.h | 1 + source4/ntvfs/print/vfs_print.c | 1 + source4/ntvfs/simple/svfs_util.c | 1 + source4/ntvfs/simple/vfs_simple.c | 1 + source4/ntvfs/unixuid/vfs_unixuid.c | 1 + 14 files changed, 15 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index b0d0d06552..16a472104b 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -33,6 +33,7 @@ #include "smb_server/smb_server.h" #include "smbd/service_stream.h" #include "auth/auth.h" +#include "ntvfs/ntvfs.h" /* this is stored in ntvfs_private */ struct cvfs_private { diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index bc39d82156..74b62809f7 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -77,6 +77,7 @@ PUBLIC_HEADERS = ntvfs.h MAJOR_VERSION = 0 MINOR_VERSION = 0 DESCRIPTION = Virtual File System with NTFS semantics +PRIVATE_PROTO_HEADER = ntvfs_proto.h RELEASE_VERSION = 1 OBJ_FILES = \ ntvfs_base.o \ diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 3f91323fe5..3a643d7145 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -29,6 +29,7 @@ #include "system/filesys.h" #include "dlinklist.h" #include "smb_server/smb_server.h" +#include "ntvfs/ntvfs.h" #define IPC_BASE_FNUM 0x400 diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index acfa6313d3..3c95621694 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -27,6 +27,7 @@ #include "includes.h" #include "system/filesys.h" #include "smb_server/smb_server.h" +#include "ntvfs/ntvfs.h" /* this is stored in ntvfs_private */ struct nbench_private { diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 3a6a78c032..4ec8926ebc 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -180,3 +180,5 @@ struct ntvfs_critical_sizes { int sizeof_smbsrv_tcon; int sizeof_smbsrv_request; }; + +#include "ntvfs/ntvfs_proto.h" diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 1b021527de..d20904737f 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -27,6 +27,7 @@ #include "dlinklist.h" #include "smb_server/smb_server.h" #include "smb_build.h" +#include "ntvfs/ntvfs.h" /* the list of currently registered NTVFS backends, note that there * can be more than one backend with the same name, as long as they diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 8d2809cf6b..dc638ade5f 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -34,6 +34,7 @@ #include "includes.h" #include "smb_server/smb_server.h" #include "librpc/gen_ndr/ndr_security.h" +#include "ntvfs/ntvfs.h" /* a second stage function converts from the out parameters of the generic call onto the out parameters of the specific call made */ diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 6a711bc3bd..788dcafaca 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -21,7 +21,7 @@ #include "includes.h" #include "smb_server/smb_server.h" - +#include "ntvfs/ntvfs.h" /* connect/disconnect */ NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index e360321882..ad31865425 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -24,6 +24,7 @@ #include "includes.h" #include "dlinklist.h" #include "smb_server/smb_server.h" +#include "ntvfs/ntvfs.h" NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 9eec368157..dd2bf74543 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -25,6 +25,7 @@ #include "system/filesys.h" #include "smb_server/smb_server.h" +#include "ntvfs/ntvfs.h" /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index c04cf76f33..e933f5502b 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -25,6 +25,7 @@ #include "includes.h" #include "ioctl.h" #include "smb_server/smb_server.h" +#include "ntvfs/ntvfs.h" /* connect to a share - used when a tree_connect operation comes diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index ac5cf69e9a..d332abb091 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -28,6 +28,7 @@ #include "svfs.h" #include "system/time.h" #include "system/dir.h" +#include "ntvfs/ntvfs.h" /* convert a windows path to a unix path - don't do any manging or case sensitive handling diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index e9063c38c5..1198cafbe9 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -33,6 +33,7 @@ #include "system/time.h" #include "dlinklist.h" #include "smb_server/smb_server.h" +#include "ntvfs/ntvfs.h" #ifndef O_DIRECTORY #define O_DIRECTORY 0 diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 928ff8241b..8bdf732735 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -27,6 +27,7 @@ #include "auth/auth.h" #include "librpc/gen_ndr/ndr_security.h" #include "smb_server/smb_server.h" +#include "ntvfs/ntvfs.h" struct unixuid_private { struct sidmap_context *sidmap; -- cgit From 2cd5ca7d25f12aa9198bf8c2deb6aea282f573ee Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 Dec 2005 15:38:36 +0000 Subject: r12542: Move some more prototypes out to seperate headers (This used to be commit 0aca5fd5130d980d07398f3291d294202aefe3c2) --- source4/ntvfs/common/sidmap.c | 3 +++ source4/ntvfs/ipc/vfs_ipc.c | 1 + source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/vfs_posix.h | 2 ++ 4 files changed, 7 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index f3ee938d84..1f19ba171d 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -25,6 +25,9 @@ #include "system/passwd.h" #include "librpc/gen_ndr/ndr_security.h" #include "ads.h" +#include "dsdb/samdb/samdb.h" +#include "auth/auth.h" +#include "libcli/ldap/ldap.h" /* these are used for the fallback local uid/gid to sid mapping diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 3a643d7145..415d09a729 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -30,6 +30,7 @@ #include "dlinklist.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" +#include "rpc_server/dcerpc_server.h" #define IPC_BASE_FNUM 0x400 diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 53c51cf805..a2a4685d8c 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -3,6 +3,7 @@ [MODULE::ntvfs_posix] SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_posix_init +PRIVATE_PROTO_HEADER = vfs_posix_proto.h OBJ_FILES = \ vfs_posix.o \ pvfs_util.o \ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index dd2bf74543..3028053f5e 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -204,4 +204,6 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, void (*fn)(void *, enum pvfs_wait_notice), void *private); +#include "ntvfs/posix/vfs_posix_proto.h" + #endif /* _VFS_POSIX_H_ */ -- cgit From d4de4c2d210d2e8c9b5aedf70695594809ad6a0b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 Dec 2005 13:16:54 +0000 Subject: r12608: Remove some unused #include lines. (This used to be commit 70e7449318aa0e9d2639c76730a7d1683b2f4981) --- source4/ntvfs/cifs/vfs_cifs.c | 2 -- source4/ntvfs/common/sidmap.c | 2 -- source4/ntvfs/ipc/vfs_ipc.c | 1 - source4/ntvfs/unixuid/vfs_unixuid.c | 1 - 4 files changed, 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 16a472104b..412af07aa2 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -26,9 +26,7 @@ */ #include "includes.h" -#include "lib/events/events.h" #include "libcli/raw/libcliraw.h" -#include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "smb_server/smb_server.h" #include "smbd/service_stream.h" diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 1f19ba171d..b2408d42bd 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -21,9 +21,7 @@ */ #include "includes.h" -#include "system/filesys.h" #include "system/passwd.h" -#include "librpc/gen_ndr/ndr_security.h" #include "ads.h" #include "dsdb/samdb/samdb.h" #include "auth/auth.h" diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 415d09a729..7eb9250eb2 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -26,7 +26,6 @@ #include "includes.h" -#include "system/filesys.h" #include "dlinklist.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 8bdf732735..886ace819e 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -25,7 +25,6 @@ #include "system/filesys.h" #include "system/passwd.h" #include "auth/auth.h" -#include "librpc/gen_ndr/ndr_security.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" -- cgit From 78c50015bb8bd5a1d831a6e7ec796b3367c73145 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 15:40:05 +0000 Subject: r12694: Move some headers to the directory of the subsystem they belong to. (This used to be commit c722f665c90103f3ed57621c460e32ad33e7a8a3) --- source4/ntvfs/common/brlock.c | 2 +- source4/ntvfs/common/opendb.c | 3 ++- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/simple/svfs_util.c | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e06cb0602e..3fc3c09316 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -28,7 +28,7 @@ #include "includes.h" #include "system/filesys.h" #include "lib/tdb/include/tdb.h" -#include "messages.h" +#include "messaging/messaging.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 72e9fff1c6..7d45f38840 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -41,9 +41,10 @@ #include "includes.h" #include "system/filesys.h" #include "lib/tdb/include/tdb.h" -#include "messages.h" +#include "messaging/messaging.h" #include "librpc/gen_ndr/ndr_security.h" #include "db_wrap.h" +#include "smb_server/smb_server.h" #include "lib/messaging/irpc.h" struct odb_context { diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index a0832723b6..5031e4cef7 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -24,7 +24,7 @@ #include "vfs_posix.h" #include "system/time.h" #include "dlinklist.h" -#include "messages.h" +#include "messaging/messaging.h" /* diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 0e2a85bab1..5aeb5eb7e8 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -25,7 +25,7 @@ #include "system/dir.h" #include "system/time.h" #include "dlinklist.h" -#include "messages.h" +#include "messaging/messaging.h" #include "librpc/gen_ndr/ndr_xattr.h" /* diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index d332abb091..ab1eccc551 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -28,6 +28,7 @@ #include "svfs.h" #include "system/time.h" #include "system/dir.h" +#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" /* -- cgit From 63d718e243fd03e6ea24c47e7442975ec088a5b5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Jan 2006 17:27:33 +0000 Subject: r12696: Reduce the size of include/structs.h (This used to be commit 63917616016133c623fc6ff59454bc313ee7dd8f) --- source4/ntvfs/posix/pvfs_xattr.c | 1 - source4/ntvfs/posix/vfs_posix.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index e67253e657..e9cb077c06 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -22,7 +22,6 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_xattr.h" /* pull a xattr as a blob diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 3028053f5e..3219631ebb 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -23,6 +23,7 @@ #ifndef _VFS_POSIX_H_ #define _VFS_POSIX_H_ +#include "librpc/gen_ndr/ndr_xattr.h" #include "system/filesys.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" -- cgit From 69f7c004fefc4f4e85843bd171fe066167703bb8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Jan 2006 10:53:52 +0000 Subject: r12838: make the ntvfs function public metze (This used to be commit 41a564fdba5969fc7e518439520764fd56cfa280) --- source4/ntvfs/ntvfs_base.c | 6 +- source4/ntvfs/ntvfs_generic.c | 36 ++++---- source4/ntvfs/ntvfs_interface.c | 196 ++++++++++++++++++++-------------------- source4/ntvfs/ntvfs_util.c | 10 +- 4 files changed, 124 insertions(+), 124 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index d20904737f..e14ae71da2 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -45,7 +45,7 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -NTSTATUS ntvfs_register(const void *_ops) +_PUBLIC_ NTSTATUS ntvfs_register(const void *_ops) { const struct ntvfs_ops *ops = _ops; struct ntvfs_ops *new_ops; @@ -79,7 +79,7 @@ NTSTATUS ntvfs_register(const void *_ops) /* return the operations structure for a named backend of the specified type */ -const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) +_PUBLIC_ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) { int i; @@ -99,7 +99,7 @@ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type t This can be used by backends to either detect compilation errors, or provide multiple implementations for different smbd compilation options in one module */ -const struct ntvfs_critical_sizes *ntvfs_interface_version(void) +_PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { static const struct ntvfs_critical_sizes critical_sizes = { NTVFS_INTERFACE_VERSION, diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index dc638ade5f..b30508b1d7 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -346,8 +346,8 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, /* NTVFS open generic to any mapper */ -NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_open *io2; @@ -480,8 +480,8 @@ done: /* NTVFS fsinfo generic to any mapper */ -NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_fsinfo *fs2; @@ -609,8 +609,8 @@ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, /* NTVFS fileinfo generic to any mapper */ -NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, - union smb_fileinfo *info2) +_PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, + union smb_fileinfo *info2) { int i; /* and convert it to the required level using results in info2 */ @@ -835,8 +835,8 @@ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info /* NTVFS fileinfo generic to any mapper */ -NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info, + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_fileinfo *info2; @@ -864,8 +864,8 @@ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *inf /* NTVFS pathinfo generic to any mapper */ -NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info, + struct ntvfs_module_context *ntvfs) { NTSTATUS status; union smb_fileinfo *info2; @@ -897,8 +897,8 @@ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *inf /* NTVFS lock generic to any mapper */ -NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck, + struct ntvfs_module_context *ntvfs) { union smb_lock *lck2; struct smb_lock_entry *locks; @@ -1020,8 +1020,8 @@ static NTSTATUS ntvfs_map_write_finish(struct smbsrv_request *req, /* NTVFS write generic to any mapper */ -NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, + struct ntvfs_module_context *ntvfs) { union smb_write *wr2; NTSTATUS status; @@ -1118,8 +1118,8 @@ static NTSTATUS ntvfs_map_read_finish(struct smbsrv_request *req, /* NTVFS read* to readx mapper */ -NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, + struct ntvfs_module_context *ntvfs) { union smb_read *rd2; union smb_lock *lck; @@ -1202,8 +1202,8 @@ done: /* NTVFS close generic to any mapper */ -NTSTATUS ntvfs_map_close(struct smbsrv_request *req, union smb_close *cl, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_close(struct smbsrv_request *req, union smb_close *cl, + struct ntvfs_module_context *ntvfs) { union smb_close *cl2; diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 788dcafaca..5a2415f5f9 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -24,7 +24,7 @@ #include "ntvfs/ntvfs.h" /* connect/disconnect */ -NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) +_PUBLIC_ NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->connect) { @@ -33,7 +33,7 @@ NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) return ntvfs->ops->connect(ntvfs, req, sharename); } -NTSTATUS ntvfs_disconnect(struct smbsrv_tcon *tcon) +_PUBLIC_ NTSTATUS ntvfs_disconnect(struct smbsrv_tcon *tcon) { struct ntvfs_module_context *ntvfs; if (tcon->ntvfs_ctx == NULL) { @@ -47,7 +47,7 @@ NTSTATUS ntvfs_disconnect(struct smbsrv_tcon *tcon) } /* path operations */ -NTSTATUS ntvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +_PUBLIC_ NTSTATUS ntvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->unlink) { @@ -56,7 +56,7 @@ NTSTATUS ntvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) return ntvfs->ops->unlink(ntvfs, req, unl); } -NTSTATUS ntvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +_PUBLIC_ NTSTATUS ntvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->chkpath) { @@ -65,7 +65,7 @@ NTSTATUS ntvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) return ntvfs->ops->chkpath(ntvfs, req, cp); } -NTSTATUS ntvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *st) +_PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *st) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->qpathinfo) { @@ -74,7 +74,7 @@ NTSTATUS ntvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *st) return ntvfs->ops->qpathinfo(ntvfs, req, st); } -NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +_PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->setpathinfo) { @@ -83,7 +83,7 @@ NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st return ntvfs->ops->setpathinfo(ntvfs, req, st); } -NTSTATUS ntvfs_openfile(struct smbsrv_request *req, union smb_open *oi) +_PUBLIC_ NTSTATUS ntvfs_openfile(struct smbsrv_request *req, union smb_open *oi) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->openfile) { @@ -92,7 +92,7 @@ NTSTATUS ntvfs_openfile(struct smbsrv_request *req, union smb_open *oi) return ntvfs->ops->openfile(ntvfs, req, oi); } -NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +_PUBLIC_ NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->mkdir) { @@ -101,7 +101,7 @@ NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) return ntvfs->ops->mkdir(ntvfs, req, md); } -NTSTATUS ntvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +_PUBLIC_ NTSTATUS ntvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->rmdir) { @@ -110,7 +110,7 @@ NTSTATUS ntvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) return ntvfs->ops->rmdir(ntvfs, req, rd); } -NTSTATUS ntvfs_rename(struct smbsrv_request *req, union smb_rename *ren) +_PUBLIC_ NTSTATUS ntvfs_rename(struct smbsrv_request *req, union smb_rename *ren) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->rename) { @@ -119,7 +119,7 @@ NTSTATUS ntvfs_rename(struct smbsrv_request *req, union smb_rename *ren) return ntvfs->ops->rename(ntvfs, req, ren); } -NTSTATUS ntvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) +_PUBLIC_ NTSTATUS ntvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->copy) { @@ -129,8 +129,8 @@ NTSTATUS ntvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) } /* directory search */ -NTSTATUS ntvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *private, - BOOL ntvfs_callback(void *private, union smb_search_data *file)) +_PUBLIC_ NTSTATUS ntvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *private, + BOOL ntvfs_callback(void *private, union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->search_first) { @@ -139,8 +139,8 @@ NTSTATUS ntvfs_search_first(struct smbsrv_request *req, union smb_search_first * return ntvfs->ops->search_first(ntvfs, req, io, private, ntvfs_callback); } -NTSTATUS ntvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *private, - BOOL ntvfs_callback(void *private, union smb_search_data *file)) +_PUBLIC_ NTSTATUS ntvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *private, + BOOL ntvfs_callback(void *private, union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->search_next) { @@ -149,7 +149,7 @@ NTSTATUS ntvfs_search_next(struct smbsrv_request *req, union smb_search_next *io return ntvfs->ops->search_next(ntvfs, req, io, private, ntvfs_callback); } -NTSTATUS ntvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +_PUBLIC_ NTSTATUS ntvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->search_close) { @@ -159,7 +159,7 @@ NTSTATUS ntvfs_search_close(struct smbsrv_request *req, union smb_search_close * } /* operations on open files */ -NTSTATUS ntvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +_PUBLIC_ NTSTATUS ntvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->ioctl) { @@ -168,7 +168,7 @@ NTSTATUS ntvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) return ntvfs->ops->ioctl(ntvfs, req, io); } -NTSTATUS ntvfs_read(struct smbsrv_request *req, union smb_read *io) +_PUBLIC_ NTSTATUS ntvfs_read(struct smbsrv_request *req, union smb_read *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->read) { @@ -177,7 +177,7 @@ NTSTATUS ntvfs_read(struct smbsrv_request *req, union smb_read *io) return ntvfs->ops->read(ntvfs, req, io); } -NTSTATUS ntvfs_write(struct smbsrv_request *req, union smb_write *io) +_PUBLIC_ NTSTATUS ntvfs_write(struct smbsrv_request *req, union smb_write *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->write) { @@ -186,7 +186,7 @@ NTSTATUS ntvfs_write(struct smbsrv_request *req, union smb_write *io) return ntvfs->ops->write(ntvfs, req, io); } -NTSTATUS ntvfs_seek(struct smbsrv_request *req, struct smb_seek *io) +_PUBLIC_ NTSTATUS ntvfs_seek(struct smbsrv_request *req, struct smb_seek *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->seek) { @@ -195,7 +195,7 @@ NTSTATUS ntvfs_seek(struct smbsrv_request *req, struct smb_seek *io) return ntvfs->ops->seek(ntvfs, req, io); } -NTSTATUS ntvfs_flush(struct smbsrv_request *req, struct smb_flush *flush) +_PUBLIC_ NTSTATUS ntvfs_flush(struct smbsrv_request *req, struct smb_flush *flush) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->flush) { @@ -204,7 +204,7 @@ NTSTATUS ntvfs_flush(struct smbsrv_request *req, struct smb_flush *flush) return ntvfs->ops->flush(ntvfs, req, flush); } -NTSTATUS ntvfs_close(struct smbsrv_request *req, union smb_close *io) +_PUBLIC_ NTSTATUS ntvfs_close(struct smbsrv_request *req, union smb_close *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->close) { @@ -213,7 +213,7 @@ NTSTATUS ntvfs_close(struct smbsrv_request *req, union smb_close *io) return ntvfs->ops->close(ntvfs, req, io); } -NTSTATUS ntvfs_exit(struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_exit(struct smbsrv_request *req) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->exit) { @@ -222,7 +222,7 @@ NTSTATUS ntvfs_exit(struct smbsrv_request *req) return ntvfs->ops->exit(ntvfs, req); } -NTSTATUS ntvfs_lock(struct smbsrv_request *req, union smb_lock *lck) +_PUBLIC_ NTSTATUS ntvfs_lock(struct smbsrv_request *req, union smb_lock *lck) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->lock) { @@ -231,7 +231,7 @@ NTSTATUS ntvfs_lock(struct smbsrv_request *req, union smb_lock *lck) return ntvfs->ops->lock(ntvfs, req, lck); } -NTSTATUS ntvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->setfileinfo) { @@ -240,7 +240,7 @@ NTSTATUS ntvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *in return ntvfs->ops->setfileinfo(ntvfs, req, info); } -NTSTATUS ntvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->qfileinfo) { @@ -250,7 +250,7 @@ NTSTATUS ntvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) } /* filesystem operations */ -NTSTATUS ntvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +_PUBLIC_ NTSTATUS ntvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->fsinfo) { @@ -260,7 +260,7 @@ NTSTATUS ntvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) } /* printing specific operations */ -NTSTATUS ntvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +_PUBLIC_ NTSTATUS ntvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->lpq) { @@ -270,7 +270,7 @@ NTSTATUS ntvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) } /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ -NTSTATUS ntvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) +_PUBLIC_ NTSTATUS ntvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->trans2) { @@ -280,7 +280,7 @@ NTSTATUS ntvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) } /* trans interface - used by IPC backend for pipes and RAP calls */ -NTSTATUS ntvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans) +_PUBLIC_ NTSTATUS ntvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->trans) { @@ -290,7 +290,7 @@ NTSTATUS ntvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans) } /* logoff - called when a vuid is closed */ -NTSTATUS ntvfs_logoff(struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_logoff(struct smbsrv_request *req) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->logoff) { @@ -301,7 +301,7 @@ NTSTATUS ntvfs_logoff(struct smbsrv_request *req) /* async setup - called by a backend that wants to setup any state for a async request */ -NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private) +_PUBLIC_ NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->async_setup) { @@ -314,7 +314,7 @@ NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private) /* cancel an outstanding async request */ -NTSTATUS ntvfs_cancel(struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_cancel(struct smbsrv_request *req) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->cancel) { @@ -325,8 +325,8 @@ NTSTATUS ntvfs_cancel(struct smbsrv_request *req) /* initial setup */ -NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) +_PUBLIC_ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, const char *sharename) { if (!ntvfs->next || !ntvfs->next->ops->connect) { return NT_STATUS_NOT_IMPLEMENTED; @@ -334,8 +334,8 @@ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->connect(ntvfs->next, req, sharename); } -NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +_PUBLIC_ NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs, + struct smbsrv_tcon *tcon) { if (!ntvfs->next || !ntvfs->next->ops->disconnect) { return NT_STATUS_NOT_IMPLEMENTED; @@ -344,8 +344,8 @@ NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs, } /* path operations */ -NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) +_PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_unlink *unl) { if (!ntvfs->next || !ntvfs->next->ops->unlink) { return NT_STATUS_NOT_IMPLEMENTED; @@ -353,8 +353,8 @@ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->unlink(ntvfs->next, req, unl); } -NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) +_PUBLIC_ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_chkpath *cp) { if (!ntvfs->next || !ntvfs->next->ops->chkpath) { return NT_STATUS_NOT_IMPLEMENTED; @@ -362,8 +362,8 @@ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->chkpath(ntvfs->next, req, cp); } -NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *st) +_PUBLIC_ NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *st) { if (!ntvfs->next || !ntvfs->next->ops->qpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; @@ -371,8 +371,8 @@ NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->qpathinfo(ntvfs->next, req, st); } -NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) +_PUBLIC_ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *st) { if (!ntvfs->next || !ntvfs->next->ops->setpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; @@ -380,8 +380,8 @@ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st); } -NTSTATUS ntvfs_next_openfile(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *oi) +_PUBLIC_ NTSTATUS ntvfs_next_openfile(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_open *oi) { if (!ntvfs->next || !ntvfs->next->ops->openfile) { return NT_STATUS_NOT_IMPLEMENTED; @@ -389,8 +389,8 @@ NTSTATUS ntvfs_next_openfile(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->openfile(ntvfs->next, req, oi); } -NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) +_PUBLIC_ NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_mkdir *md) { if (!ntvfs->next || !ntvfs->next->ops->mkdir) { return NT_STATUS_NOT_IMPLEMENTED; @@ -398,8 +398,8 @@ NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->mkdir(ntvfs->next, req, md); } -NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) +_PUBLIC_ NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_rmdir *rd) { if (!ntvfs->next || !ntvfs->next->ops->rmdir) { return NT_STATUS_NOT_IMPLEMENTED; @@ -407,8 +407,8 @@ NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->rmdir(ntvfs->next, req, rd); } -NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) +_PUBLIC_ NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_rename *ren) { if (!ntvfs->next || !ntvfs->next->ops->rename) { return NT_STATUS_NOT_IMPLEMENTED; @@ -416,8 +416,8 @@ NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->rename(ntvfs->next, req, ren); } -NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) +_PUBLIC_ NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_copy *cp) { if (!ntvfs->next || !ntvfs->next->ops->copy) { return NT_STATUS_NOT_IMPLEMENTED; @@ -426,9 +426,9 @@ NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, } /* directory search */ -NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) +_PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_first *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_first) { return NT_STATUS_NOT_IMPLEMENTED; @@ -436,9 +436,9 @@ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->search_first(ntvfs->next, req, io, private, callback); } -NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) +_PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_next *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_next) { return NT_STATUS_NOT_IMPLEMENTED; @@ -446,8 +446,8 @@ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->search_next(ntvfs->next, req, io, private, callback); } -NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) +_PUBLIC_ NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_search_close *io) { if (!ntvfs->next || !ntvfs->next->ops->search_close) { return NT_STATUS_NOT_IMPLEMENTED; @@ -456,8 +456,8 @@ NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, } /* operations on open files */ -NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) +_PUBLIC_ NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_ioctl *io) { if (!ntvfs->next || !ntvfs->next->ops->ioctl) { return NT_STATUS_NOT_IMPLEMENTED; @@ -465,8 +465,8 @@ NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->ioctl(ntvfs->next, req, io); } -NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *io) +_PUBLIC_ NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_read *io) { if (!ntvfs->next || !ntvfs->next->ops->read) { return NT_STATUS_NOT_IMPLEMENTED; @@ -474,8 +474,8 @@ NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->read(ntvfs->next, req, io); } -NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *io) +_PUBLIC_ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_write *io) { if (!ntvfs->next || !ntvfs->next->ops->write) { return NT_STATUS_NOT_IMPLEMENTED; @@ -483,8 +483,8 @@ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->write(ntvfs->next, req, io); } -NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) +_PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_seek *io) { if (!ntvfs->next || !ntvfs->next->ops->seek) { return NT_STATUS_NOT_IMPLEMENTED; @@ -492,8 +492,8 @@ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->seek(ntvfs->next, req, io); } -NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *flush) +_PUBLIC_ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_flush *flush) { if (!ntvfs->next || !ntvfs->next->ops->flush) { return NT_STATUS_NOT_IMPLEMENTED; @@ -501,8 +501,8 @@ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->flush(ntvfs->next, req, flush); } -NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) +_PUBLIC_ NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_close *io) { if (!ntvfs->next || !ntvfs->next->ops->close) { return NT_STATUS_NOT_IMPLEMENTED; @@ -510,8 +510,8 @@ NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->close(ntvfs->next, req, io); } -NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { if (!ntvfs->next || !ntvfs->next->ops->exit) { return NT_STATUS_NOT_IMPLEMENTED; @@ -519,8 +519,8 @@ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->exit(ntvfs->next, req); } -NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) +_PUBLIC_ NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lock *lck) { if (!ntvfs->next || !ntvfs->next->ops->lock) { return NT_STATUS_NOT_IMPLEMENTED; @@ -528,8 +528,8 @@ NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->lock(ntvfs->next, req, lck); } -NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_setfileinfo *info) { if (!ntvfs->next || !ntvfs->next->ops->setfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; @@ -537,8 +537,8 @@ NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info); } -NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fileinfo *info) { if (!ntvfs->next || !ntvfs->next->ops->qfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; @@ -547,8 +547,8 @@ NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, } /* filesystem operations */ -NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) +_PUBLIC_ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_fsinfo *fs) { if (!ntvfs->next || !ntvfs->next->ops->fsinfo) { return NT_STATUS_NOT_IMPLEMENTED; @@ -557,8 +557,8 @@ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, } /* printing specific operations */ -NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) +_PUBLIC_ NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, union smb_lpq *lpq) { if (!ntvfs->next || !ntvfs->next->ops->lpq) { return NT_STATUS_NOT_IMPLEMENTED; @@ -567,8 +567,8 @@ NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, } /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ -NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) +_PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans2) { if (!ntvfs->next || !ntvfs->next->ops->trans2) { return NT_STATUS_NOT_IMPLEMENTED; @@ -577,8 +577,8 @@ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, } /* trans interface - used by IPC backend for pipes and RAP calls */ -NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans) +_PUBLIC_ NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans) { if (!ntvfs->next || !ntvfs->next->ops->trans) { return NT_STATUS_NOT_IMPLEMENTED; @@ -587,8 +587,8 @@ NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, } /* logoff - called when a vuid is closed */ -NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { if (!ntvfs->next || !ntvfs->next->ops->logoff) { return NT_STATUS_NOT_IMPLEMENTED; @@ -597,9 +597,9 @@ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, } /* async_setup - called when setting up for a async request */ -NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, - void *private) +_PUBLIC_ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, + void *private) { if (!ntvfs->next || !ntvfs->next->ops->async_setup) { return NT_STATUS_NOT_IMPLEMENTED; @@ -608,8 +608,8 @@ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, } /* cancel - called to cancel an outstanding async request */ -NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req) { if (!ntvfs->next || !ntvfs->next->ops->cancel) { return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index ad31865425..861f266271 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -27,10 +27,10 @@ #include "ntvfs/ntvfs.h" -NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, - void *private_data, - void (*send_fn)(struct smbsrv_request *), - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, + void *private_data, + void (*send_fn)(struct smbsrv_request *), + struct ntvfs_module_context *ntvfs) { struct ntvfs_async_state *async; @@ -51,7 +51,7 @@ NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, return NT_STATUS_OK; } -void ntvfs_async_state_pop(struct smbsrv_request *req) +_PUBLIC_ void ntvfs_async_state_pop(struct smbsrv_request *req) { struct ntvfs_async_state *async; -- cgit From 5bfa7bef7d48ff3c12c70f099a7c5c348ab64906 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 24 Jan 2006 00:34:58 +0000 Subject: r13099: allow shares that point to / (This used to be commit ac4b8b98392cba69d0d06bce8e9023769ee301d8) --- source4/ntvfs/posix/vfs_posix.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index bedc81389c..3b52ff6237 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -124,7 +124,9 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, /* for simplicity of path construction, remove any trailing slash now */ base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); NT_STATUS_HAVE_NO_MEMORY(base_directory); - trim_string(base_directory, NULL, "/"); + if (strcmp(base_directory, "/") != 0) { + trim_string(base_directory, NULL, "/"); + } pvfs->tcon = tcon; pvfs->base_directory = base_directory; -- cgit From 60954d80e1afd0527a5fa426bf02e9359ed19890 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Jan 2006 12:19:13 +0000 Subject: r13128: init the private_data to NULL so so that we don't crash when ntvfs_connect() fails metze (This used to be commit 96680f12001c67b6f6644654dfd74a86538d51b6) --- source4/ntvfs/ntvfs_base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index e14ae71da2..63476c7fee 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -140,6 +140,8 @@ NTSTATUS ntvfs_init_connection(struct smbsrv_request *req, enum ntvfs_type type) ntvfs = talloc(ctx, struct ntvfs_module_context); NT_STATUS_HAVE_NO_MEMORY(ntvfs); + ntvfs->private_data = NULL; + ntvfs->ops = ntvfs_backend_byname(handlers[i], ctx->type); if (!ntvfs->ops) { DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", -- cgit From 5497dfe64ad810a2a3fb22da6869d311894bfed0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 25 Jan 2006 12:19:49 +0000 Subject: r13129: fix the memory hierachie metze (This used to be commit 19205b8d89d3d7e99a65938f59412e0c4e8ac5fe) --- source4/ntvfs/cifs/vfs_cifs.c | 3 ++- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/nbench/vfs_nbench.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 4 ++-- source4/ntvfs/unixuid/vfs_unixuid.c | 3 ++- 5 files changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 412af07aa2..138c9d566f 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -93,7 +93,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, machine_account = lp_parm_bool(req->tcon->service, "cifs", "use_machine_account", False); - private = talloc(req->tcon, struct cvfs_private); + private = talloc(ntvfs, struct cvfs_private); if (!private) { return NT_STATUS_NO_MEMORY; } @@ -178,6 +178,7 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; talloc_free(private); + ntvfs->private_data = NULL; return NT_STATUS_OK; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7eb9250eb2..dd7994c1fb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -87,7 +87,7 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(tcon->dev_type); /* prepare the private state for this connection */ - private = talloc(tcon, struct ipc_private); + private = talloc(ntvfs, struct ipc_private); NT_STATUS_HAVE_NO_MEMORY(private); ntvfs->private_data = private; diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 3c95621694..e88adbafcc 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -99,7 +99,7 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, NTSTATUS status; char *logname = NULL; - nprivates = talloc(req->tcon, struct nbench_private); + nprivates = talloc(ntvfs, struct nbench_private); if (!nprivates) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 1198cafbe9..ad06a95041 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -54,10 +54,10 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_tcon *tcon = req->tcon; struct svfs_private *private; - private = talloc(tcon, struct svfs_private); + private = talloc(ntvfs, struct svfs_private); private->next_search_handle = 0; - private->connectpath = talloc_strdup(tcon, lp_pathname(tcon->service)); + private->connectpath = talloc_strdup(private, lp_pathname(tcon->service)); private->open_files = NULL; private->search = NULL; diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 886ace819e..df627bd2d1 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -207,7 +207,7 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, struct unixuid_private *private; NTSTATUS status; - private = talloc(req->tcon, struct unixuid_private); + private = talloc(ntvfs, struct unixuid_private); if (!private) { return NT_STATUS_NO_MEMORY; } @@ -239,6 +239,7 @@ static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs, NTSTATUS status; talloc_free(private); + ntvfs->private_data = NULL; status = ntvfs_next_disconnect(ntvfs, tcon); -- cgit From ad6303f82fa862111c239b32b39f299e563a0802 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 28 Jan 2006 12:58:38 +0000 Subject: r13208: Clearly separate named pipes from the IPC$ NTVFS type. This allows the easy addition of additional named pipes and removes the circular dependencies between the CIFS, RPC and RAP servers. Simple tests for a custom named pipe included. (This used to be commit 898d15acbd18e3b302a856c847e08c22c5024792) --- source4/ntvfs/config.mk | 5 +- source4/ntvfs/ipc/ipc.h | 30 ++++++ source4/ntvfs/ipc/np_echo.c | 77 ++++++++++++++ source4/ntvfs/ipc/vfs_ipc.c | 243 ++++++++++++++++++++++---------------------- 4 files changed, 233 insertions(+), 122 deletions(-) create mode 100644 source4/ntvfs/ipc/ipc.h create mode 100644 source4/ntvfs/ipc/np_echo.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 74b62809f7..df96998cfe 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -47,7 +47,10 @@ OBJ_FILES = \ # End MODULE ntvfs_ipc ################################################ - +[MODULE::np_echo] +INIT_FUNCTION = np_echo_init +OBJ_FILES = ipc/np_echo.o +SUBSYSTEM = ntvfs_ipc ################################################ # Start MODULE ntvfs_nbench diff --git a/source4/ntvfs/ipc/ipc.h b/source4/ntvfs/ipc/ipc.h new file mode 100644 index 0000000000..53818a5845 --- /dev/null +++ b/source4/ntvfs/ipc/ipc.h @@ -0,0 +1,30 @@ +/* + Unix SMB/CIFS implementation. + NTVFS IPC$ Named Pipes + Copyright (C) Jelmer Vernooij 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +struct named_pipe_ops { + NTSTATUS (*open)(void *context_data, + const char *path, + struct auth_session_info *session, + struct stream_connection *stream, + TALLOC_CTX *ctx, void **private_data); + NTSTATUS (*trans)(void *private_data, DATA_BLOB *in, DATA_BLOB *out); + NTSTATUS (*write)(void *private_data, DATA_BLOB *out); + NTSTATUS (*read)(void *private_data, DATA_BLOB *in); +}; diff --git a/source4/ntvfs/ipc/np_echo.c b/source4/ntvfs/ipc/np_echo.c new file mode 100644 index 0000000000..bfa0083b79 --- /dev/null +++ b/source4/ntvfs/ipc/np_echo.c @@ -0,0 +1,77 @@ +/* + Unix SMB/CIFS implementation. + DCE/RPC over named pipes support (glue between dcerpc and smb servers) + + Copyright (C) Jelmer Vernooij 2005 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "lib/socket/socket.h" +#include "lib/events/events.h" +#include "rpc_server/dcerpc_server.h" +#include "ntvfs/ipc/ipc.h" + +static NTSTATUS echo_pipe_open (void *context_data, const char *path, struct auth_session_info *session_info, struct stream_connection *srv_conn, TALLOC_CTX *mem_ctx, void **private_data) +{ + *private_data = talloc_zero(mem_ctx, DATA_BLOB); + + return NT_STATUS_OK; +} + +static NTSTATUS echo_pipe_trans(void *private_data, DATA_BLOB *in, DATA_BLOB *out) +{ + memcpy(out->data, in->data, MIN(out->length,in->length)); + + return NT_STATUS_OK; +} + +static NTSTATUS echo_pipe_write(void *private_data, DATA_BLOB *out) +{ + DATA_BLOB *cache = private_data; + return data_blob_append(cache, cache, out->data, out->length); +} + +static NTSTATUS echo_pipe_read(void *private_data, DATA_BLOB *in) +{ + uint8_t *newdata; + DATA_BLOB *cache = private_data; + uint32_t numread = MIN(in->length, cache->length); + + memcpy(in->data, cache->data, numread); + + cache->length -= numread; + newdata = talloc_memdup(cache, cache+numread, cache->length); + if (newdata == NULL) + return NT_STATUS_NO_MEMORY; + + talloc_free(cache->data); + cache->data = newdata; + + return NT_STATUS_OK; +} + +const struct named_pipe_ops echo_pipe_ops = { + .open = echo_pipe_open, + .write = echo_pipe_write, + .read = echo_pipe_read, + .trans = echo_pipe_trans +}; + +NTSTATUS np_echo_init(void) +{ + return named_pipe_listen("\\PIPE\\NPECHO", &echo_pipe_ops, NULL); +} diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index dd7994c1fb..bde87684e1 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 2003 Copyright (C) Stefan (metze) Metzmacher 2004-2005 + Copyright (C) Jelmer Vernooij 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -28,8 +29,10 @@ #include "includes.h" #include "dlinklist.h" #include "smb_server/smb_server.h" +#include "ntvfs/ipc/ipc.h" #include "ntvfs/ntvfs.h" #include "rpc_server/dcerpc_server.h" +#include "smb_build.h" #define IPC_BASE_FNUM 0x400 @@ -46,8 +49,9 @@ struct ipc_private { struct pipe_state *next, *prev; struct ipc_private *private; const char *pipe_name; + const struct named_pipe_ops *ops; + void *private_data; 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 */ @@ -76,7 +80,6 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) { - NTSTATUS status; struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; @@ -97,10 +100,6 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, private->idtree_fnum = idr_init(private); NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum); - /* setup the DCERPC server subsystem */ - status = dcesrv_init_ipc_context(private, &private->dcesrv); - NT_STATUS_NOT_OK_RETURN(status); - return NT_STATUS_OK; } @@ -171,6 +170,55 @@ static int ipc_fd_destructor(void *ptr) return 0; } +static struct named_pipe { + struct named_pipe *prev, *next; + const char *name; + const struct named_pipe_ops *ops; + void *context_data; +} *named_pipes = NULL; + +static NTSTATUS find_pipe_ops(const char *fname, const struct named_pipe_ops **ops, void **context_data) +{ + struct named_pipe *np; + + for (np = named_pipes; np; np = np->next) { + if (strcasecmp_m(np->name, fname) == 0) { + if (ops) *ops = np->ops; + if (context_data) *context_data = np->context_data; + return NT_STATUS_OK; + } + } + + return NT_STATUS_OBJECT_NAME_NOT_FOUND; +} + +NTSTATUS named_pipe_listen(const char *name, const struct named_pipe_ops *ops, void *context_data) +{ + NTSTATUS status; + struct named_pipe *np; + DEBUG(3, ("Registering named pipe `%s'\n", name)); + + status = find_pipe_ops(name, NULL, NULL); + if (NT_STATUS_IS_OK(status)) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + return status; + } + + np = talloc(talloc_autofree_context(), struct named_pipe); + np->name = talloc_strdup(np, name); + np->ops = ops; + np->context_data = context_data; + np->prev = np->next = NULL; + + DLIST_ADD(named_pipes, np); + + return NT_STATUS_OK; +} + + /* open a file backend - used for MSRPC pipes @@ -181,10 +229,9 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, { struct pipe_state *p; NTSTATUS status; - struct dcerpc_binding *ep_description; struct ipc_private *private = ntvfs->private_data; + void *context_data; int fnum; - struct stream_connection *srv_conn = req->smb_conn->connection; if (!req->session || !req->session->session_info) { return NT_STATUS_ACCESS_DENIED; @@ -193,14 +240,24 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p = talloc(req, struct pipe_state); NT_STATUS_HAVE_NO_MEMORY(p); - ep_description = talloc(req, struct dcerpc_binding); - NT_STATUS_HAVE_NO_MEMORY(ep_description); - while (fname[0] == '\\') fname++; - + p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); NT_STATUS_HAVE_NO_MEMORY(p->pipe_name); + status = find_pipe_ops(p->pipe_name, &p->ops, &context_data); + + /* FIXME: Perhaps fall back to opening /var/lib/samba/ipc/ ? */ + if (NT_STATUS_IS_ERR(status)) { + DEBUG(0, ("Unable to find pipe ops for `%s'\n", p->pipe_name)); + return status; + } + + status = p->ops->open(context_data, p->pipe_name, req->session->session_info, req->smb_conn->connection, p, &p->private_data); + if (NT_STATUS_IS_ERR(status)) { + return status; + } + fnum = idr_get_new_above(private->idtree_fnum, p, IPC_BASE_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; @@ -209,29 +266,6 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p->fnum = fnum; p->ipc_state = 0x5ff; - /* - we're all set, now ask the dcerpc server subsystem to open the - endpoint. At this stage the pipe isn't bound, so we don't - know what interface the user actually wants, just that they want - one of the interfaces attached to this pipe endpoint. - */ - ep_description->transport = NCACN_NP; - ep_description->endpoint = talloc_reference(ep_description, p->pipe_name); - - /* The session info is refcount-increased in the - * dcesrv_endpoint_search_connect() function - */ - status = dcesrv_endpoint_search_connect(private->dcesrv, - p, - ep_description, - req->session->session_info, - srv_conn, - &p->dce_conn); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(private->idtree_fnum, p->fnum); - return status; - } - DLIST_ADD(private->pipe_list, p); p->smbpid = req->smbpid; @@ -351,18 +385,6 @@ static NTSTATUS ipc_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) -{ - DATA_BLOB *blob = private_data; - - if (out->length < blob->length) { - blob->length = out->length; - } - memcpy(blob->data, out->data, blob->length); - *nwritten = blob->length; - return NT_STATUS_OK; -} - /* read from a file */ @@ -393,7 +415,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, } if (data.length != 0) { - status = dcesrv_output(p->dce_conn, &data, ipc_readx_dcesrv_output); + status = p->ops->read(p->private_data, &data); if (NT_STATUS_IS_ERR(status)) { return status; } @@ -431,7 +453,7 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - status = dcesrv_input(p->dce_conn, &data); + status = p->ops->write(p->private_data, &data); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -617,30 +639,12 @@ static NTSTATUS ipc_search_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) -{ - NTSTATUS status = NT_STATUS_OK; - DATA_BLOB *blob = private_data; - - if (out->length > blob->length) { - status = STATUS_BUFFER_OVERFLOW; - } - - if (out->length < blob->length) { - blob->length = out->length; - } - memcpy(blob->data, out->data, blob->length); - *nwritten = blob->length; - return status; -} - -/* SMBtrans - handle a DCERPC command */ -static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans) +/* SMBtrans - set named pipe state */ +static NTSTATUS ipc_np_set_nm_state(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans) { - struct pipe_state *p; struct ipc_private *private = ntvfs->private_data; - NTSTATUS status; + struct pipe_state *p; /* the fnum is in setup[1] */ p = pipe_state_find(private, trans->in.setup[1]); @@ -648,43 +652,25 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data); - if (!trans->out.data.data) { - return NT_STATUS_NO_MEMORY; - } - - /* pass the data to the dcerpc server. Note that we don't - expect this to fail, and things like NDR faults are not - reported at this stage. Those sorts of errors happen in the - dcesrv_output stage */ - status = dcesrv_input(p->dce_conn, &trans->in.data); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* - now ask the dcerpc system for some output. This doesn't yet handle - async calls. Again, we only expect NT_STATUS_OK. If the call fails then - the error is encoded at the dcerpc level - */ - status = dcesrv_output(p->dce_conn, &trans->out.data, ipc_trans_dcesrv_output); - if (NT_STATUS_IS_ERR(status)) { - return status; + if (trans->in.params.length != 2) { + return NT_STATUS_INVALID_PARAMETER; } + p->ipc_state = SVAL(trans->in.params.data, 0); trans->out.setup_count = 0; trans->out.setup = NULL; trans->out.params = data_blob(NULL, 0); + trans->out.data = data_blob(NULL, 0); - return status; + return NT_STATUS_OK; } - -/* SMBtrans - set named pipe state */ -static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, +/* SMBtrans - named pipe transaction */ +static NTSTATUS ipc_np_trans(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans) { struct ipc_private *private = ntvfs->private_data; + NTSTATUS status; struct pipe_state *p; /* the fnum is in setup[1] */ @@ -693,50 +679,55 @@ static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (trans->in.params.length != 2) { + if (trans->in.setup_count != 2) { return NT_STATUS_INVALID_PARAMETER; } - p->ipc_state = SVAL(trans->in.params.data, 0); + + trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data); + if (!trans->out.data.data) { + return NT_STATUS_NO_MEMORY; + } + + status = p->ops->trans(p->private_data, &trans->in.data, &trans->out.data); + if (NT_STATUS_IS_ERR(status)) { + return status; + } trans->out.setup_count = 0; trans->out.setup = NULL; trans->out.params = data_blob(NULL, 0); - trans->out.data = data_blob(NULL, 0); return NT_STATUS_OK; } - /* SMBtrans - used to provide access to SMB pipes */ static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans) { NTSTATUS status; - if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) - return ipc_rap_call(req, trans); - - if (trans->in.setup_count != 2) { - return NT_STATUS_INVALID_PARAMETER; - } - - switch (trans->in.setup[0]) { - case TRANSACT_SETNAMEDPIPEHANDLESTATE: - status = ipc_set_nm_pipe_state(ntvfs, req, trans); - break; - case TRANSACT_DCERPCCMD: - status = ipc_dcerpc_cmd(ntvfs, req, trans); - break; - default: - status = NT_STATUS_INVALID_PARAMETER; - break; + if (strequal(trans->in.trans_name, "\\PIPE\\")) { /* Named pipe */ + switch (trans->in.setup[0]) { + case NAMED_PIPE_SETHANDLESTATE: + status = ipc_np_set_nm_state(ntvfs, req, trans); + break; + case NAMED_PIPE_TRANSACT: + status = ipc_np_trans(ntvfs, req, trans); + break; + default: + status = NT_STATUS_INVALID_PARAMETER; + break; + } + } else if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) { /* RAP */ + status = ipc_rap_call(req, trans); + } else { + DEBUG(1, ("Unknown transaction name `%s'\n", trans->in.trans_name)); + status = NT_STATUS_NOT_SUPPORTED; } return status; } - - /* initialialise the IPC backend, registering ourselves with the ntvfs subsystem */ @@ -744,7 +735,9 @@ NTSTATUS ntvfs_ipc_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - + init_module_fn static_init[] = STATIC_ntvfs_ipc_MODULES; + init_module_fn *shared_init; + ZERO_STRUCT(ops); /* fill in the name and type */ @@ -791,5 +784,13 @@ NTSTATUS ntvfs_ipc_init(void) return ret; } + /* load available named pipe backends */ + shared_init = load_samba_modules(NULL, "np"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); + return ret; } -- cgit From 713b296441ec8b1447a0bc451720a8b84fd7e1fc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 28 Jan 2006 20:08:03 +0000 Subject: r13210: Revert my named pipes patch until it passes not just 'make quicktest' but also 'make test' (This used to be commit e3d0676aee84e96e5c87bed4cd0cde75a4191953) --- source4/ntvfs/config.mk | 5 +- source4/ntvfs/ipc/ipc.h | 30 ------ source4/ntvfs/ipc/np_echo.c | 77 -------------- source4/ntvfs/ipc/vfs_ipc.c | 243 ++++++++++++++++++++++---------------------- 4 files changed, 122 insertions(+), 233 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index df96998cfe..74b62809f7 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -47,10 +47,7 @@ OBJ_FILES = \ # End MODULE ntvfs_ipc ################################################ -[MODULE::np_echo] -INIT_FUNCTION = np_echo_init -OBJ_FILES = ipc/np_echo.o -SUBSYSTEM = ntvfs_ipc + ################################################ # Start MODULE ntvfs_nbench diff --git a/source4/ntvfs/ipc/ipc.h b/source4/ntvfs/ipc/ipc.h index 53818a5845..e69de29bb2 100644 --- a/source4/ntvfs/ipc/ipc.h +++ b/source4/ntvfs/ipc/ipc.h @@ -1,30 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NTVFS IPC$ Named Pipes - Copyright (C) Jelmer Vernooij 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -struct named_pipe_ops { - NTSTATUS (*open)(void *context_data, - const char *path, - struct auth_session_info *session, - struct stream_connection *stream, - TALLOC_CTX *ctx, void **private_data); - NTSTATUS (*trans)(void *private_data, DATA_BLOB *in, DATA_BLOB *out); - NTSTATUS (*write)(void *private_data, DATA_BLOB *out); - NTSTATUS (*read)(void *private_data, DATA_BLOB *in); -}; diff --git a/source4/ntvfs/ipc/np_echo.c b/source4/ntvfs/ipc/np_echo.c index bfa0083b79..e69de29bb2 100644 --- a/source4/ntvfs/ipc/np_echo.c +++ b/source4/ntvfs/ipc/np_echo.c @@ -1,77 +0,0 @@ -/* - Unix SMB/CIFS implementation. - DCE/RPC over named pipes support (glue between dcerpc and smb servers) - - Copyright (C) Jelmer Vernooij 2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "lib/socket/socket.h" -#include "lib/events/events.h" -#include "rpc_server/dcerpc_server.h" -#include "ntvfs/ipc/ipc.h" - -static NTSTATUS echo_pipe_open (void *context_data, const char *path, struct auth_session_info *session_info, struct stream_connection *srv_conn, TALLOC_CTX *mem_ctx, void **private_data) -{ - *private_data = talloc_zero(mem_ctx, DATA_BLOB); - - return NT_STATUS_OK; -} - -static NTSTATUS echo_pipe_trans(void *private_data, DATA_BLOB *in, DATA_BLOB *out) -{ - memcpy(out->data, in->data, MIN(out->length,in->length)); - - return NT_STATUS_OK; -} - -static NTSTATUS echo_pipe_write(void *private_data, DATA_BLOB *out) -{ - DATA_BLOB *cache = private_data; - return data_blob_append(cache, cache, out->data, out->length); -} - -static NTSTATUS echo_pipe_read(void *private_data, DATA_BLOB *in) -{ - uint8_t *newdata; - DATA_BLOB *cache = private_data; - uint32_t numread = MIN(in->length, cache->length); - - memcpy(in->data, cache->data, numread); - - cache->length -= numread; - newdata = talloc_memdup(cache, cache+numread, cache->length); - if (newdata == NULL) - return NT_STATUS_NO_MEMORY; - - talloc_free(cache->data); - cache->data = newdata; - - return NT_STATUS_OK; -} - -const struct named_pipe_ops echo_pipe_ops = { - .open = echo_pipe_open, - .write = echo_pipe_write, - .read = echo_pipe_read, - .trans = echo_pipe_trans -}; - -NTSTATUS np_echo_init(void) -{ - return named_pipe_listen("\\PIPE\\NPECHO", &echo_pipe_ops, NULL); -} diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index bde87684e1..dd7994c1fb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -4,7 +4,6 @@ Copyright (C) Andrew Tridgell 2003 Copyright (C) Stefan (metze) Metzmacher 2004-2005 - Copyright (C) Jelmer Vernooij 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,10 +28,8 @@ #include "includes.h" #include "dlinklist.h" #include "smb_server/smb_server.h" -#include "ntvfs/ipc/ipc.h" #include "ntvfs/ntvfs.h" #include "rpc_server/dcerpc_server.h" -#include "smb_build.h" #define IPC_BASE_FNUM 0x400 @@ -49,9 +46,8 @@ struct ipc_private { struct pipe_state *next, *prev; struct ipc_private *private; const char *pipe_name; - const struct named_pipe_ops *ops; - void *private_data; 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 */ @@ -80,6 +76,7 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) { + NTSTATUS status; struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; @@ -100,6 +97,10 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, private->idtree_fnum = idr_init(private); NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum); + /* setup the DCERPC server subsystem */ + status = dcesrv_init_ipc_context(private, &private->dcesrv); + NT_STATUS_NOT_OK_RETURN(status); + return NT_STATUS_OK; } @@ -170,55 +171,6 @@ static int ipc_fd_destructor(void *ptr) return 0; } -static struct named_pipe { - struct named_pipe *prev, *next; - const char *name; - const struct named_pipe_ops *ops; - void *context_data; -} *named_pipes = NULL; - -static NTSTATUS find_pipe_ops(const char *fname, const struct named_pipe_ops **ops, void **context_data) -{ - struct named_pipe *np; - - for (np = named_pipes; np; np = np->next) { - if (strcasecmp_m(np->name, fname) == 0) { - if (ops) *ops = np->ops; - if (context_data) *context_data = np->context_data; - return NT_STATUS_OK; - } - } - - return NT_STATUS_OBJECT_NAME_NOT_FOUND; -} - -NTSTATUS named_pipe_listen(const char *name, const struct named_pipe_ops *ops, void *context_data) -{ - NTSTATUS status; - struct named_pipe *np; - DEBUG(3, ("Registering named pipe `%s'\n", name)); - - status = find_pipe_ops(name, NULL, NULL); - if (NT_STATUS_IS_OK(status)) { - return NT_STATUS_OBJECT_NAME_COLLISION; - } - - if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - return status; - } - - np = talloc(talloc_autofree_context(), struct named_pipe); - np->name = talloc_strdup(np, name); - np->ops = ops; - np->context_data = context_data; - np->prev = np->next = NULL; - - DLIST_ADD(named_pipes, np); - - return NT_STATUS_OK; -} - - /* open a file backend - used for MSRPC pipes @@ -229,9 +181,10 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, { struct pipe_state *p; NTSTATUS status; + struct dcerpc_binding *ep_description; struct ipc_private *private = ntvfs->private_data; - void *context_data; int fnum; + struct stream_connection *srv_conn = req->smb_conn->connection; if (!req->session || !req->session->session_info) { return NT_STATUS_ACCESS_DENIED; @@ -240,24 +193,14 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p = talloc(req, struct pipe_state); NT_STATUS_HAVE_NO_MEMORY(p); + ep_description = talloc(req, struct dcerpc_binding); + NT_STATUS_HAVE_NO_MEMORY(ep_description); + while (fname[0] == '\\') fname++; - + p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); NT_STATUS_HAVE_NO_MEMORY(p->pipe_name); - status = find_pipe_ops(p->pipe_name, &p->ops, &context_data); - - /* FIXME: Perhaps fall back to opening /var/lib/samba/ipc/ ? */ - if (NT_STATUS_IS_ERR(status)) { - DEBUG(0, ("Unable to find pipe ops for `%s'\n", p->pipe_name)); - return status; - } - - status = p->ops->open(context_data, p->pipe_name, req->session->session_info, req->smb_conn->connection, p, &p->private_data); - if (NT_STATUS_IS_ERR(status)) { - return status; - } - fnum = idr_get_new_above(private->idtree_fnum, p, IPC_BASE_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; @@ -266,6 +209,29 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p->fnum = fnum; p->ipc_state = 0x5ff; + /* + we're all set, now ask the dcerpc server subsystem to open the + endpoint. At this stage the pipe isn't bound, so we don't + know what interface the user actually wants, just that they want + one of the interfaces attached to this pipe endpoint. + */ + ep_description->transport = NCACN_NP; + ep_description->endpoint = talloc_reference(ep_description, p->pipe_name); + + /* The session info is refcount-increased in the + * dcesrv_endpoint_search_connect() function + */ + status = dcesrv_endpoint_search_connect(private->dcesrv, + p, + ep_description, + req->session->session_info, + srv_conn, + &p->dce_conn); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(private->idtree_fnum, p->fnum); + return status; + } + DLIST_ADD(private->pipe_list, p); p->smbpid = req->smbpid; @@ -385,6 +351,18 @@ static NTSTATUS ipc_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } +static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) +{ + DATA_BLOB *blob = private_data; + + if (out->length < blob->length) { + blob->length = out->length; + } + memcpy(blob->data, out->data, blob->length); + *nwritten = blob->length; + return NT_STATUS_OK; +} + /* read from a file */ @@ -415,7 +393,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, } if (data.length != 0) { - status = p->ops->read(p->private_data, &data); + status = dcesrv_output(p->dce_conn, &data, ipc_readx_dcesrv_output); if (NT_STATUS_IS_ERR(status)) { return status; } @@ -453,7 +431,7 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - status = p->ops->write(p->private_data, &data); + status = dcesrv_input(p->dce_conn, &data); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -639,12 +617,30 @@ static NTSTATUS ipc_search_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -/* SMBtrans - set named pipe state */ -static NTSTATUS ipc_np_set_nm_state(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans) +static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *out, size_t *nwritten) +{ + NTSTATUS status = NT_STATUS_OK; + DATA_BLOB *blob = private_data; + + if (out->length > blob->length) { + status = STATUS_BUFFER_OVERFLOW; + } + + if (out->length < blob->length) { + blob->length = out->length; + } + memcpy(blob->data, out->data, blob->length); + *nwritten = blob->length; + return status; +} + +/* SMBtrans - handle a DCERPC command */ +static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_trans2 *trans) { - struct ipc_private *private = ntvfs->private_data; struct pipe_state *p; + struct ipc_private *private = ntvfs->private_data; + NTSTATUS status; /* the fnum is in setup[1] */ p = pipe_state_find(private, trans->in.setup[1]); @@ -652,25 +648,43 @@ static NTSTATUS ipc_np_set_nm_state(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (trans->in.params.length != 2) { - return NT_STATUS_INVALID_PARAMETER; + trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data); + if (!trans->out.data.data) { + return NT_STATUS_NO_MEMORY; + } + + /* pass the data to the dcerpc server. Note that we don't + expect this to fail, and things like NDR faults are not + reported at this stage. Those sorts of errors happen in the + dcesrv_output stage */ + status = dcesrv_input(p->dce_conn, &trans->in.data); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* + now ask the dcerpc system for some output. This doesn't yet handle + async calls. Again, we only expect NT_STATUS_OK. If the call fails then + the error is encoded at the dcerpc level + */ + status = dcesrv_output(p->dce_conn, &trans->out.data, ipc_trans_dcesrv_output); + if (NT_STATUS_IS_ERR(status)) { + return status; } - p->ipc_state = SVAL(trans->in.params.data, 0); trans->out.setup_count = 0; trans->out.setup = NULL; trans->out.params = data_blob(NULL, 0); - trans->out.data = data_blob(NULL, 0); - return NT_STATUS_OK; + return status; } -/* SMBtrans - named pipe transaction */ -static NTSTATUS ipc_np_trans(struct ntvfs_module_context *ntvfs, + +/* SMBtrans - set named pipe state */ +static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans) { struct ipc_private *private = ntvfs->private_data; - NTSTATUS status; struct pipe_state *p; /* the fnum is in setup[1] */ @@ -679,55 +693,50 @@ static NTSTATUS ipc_np_trans(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - if (trans->in.setup_count != 2) { + if (trans->in.params.length != 2) { return NT_STATUS_INVALID_PARAMETER; } - - trans->out.data = data_blob_talloc(req, NULL, trans->in.max_data); - if (!trans->out.data.data) { - return NT_STATUS_NO_MEMORY; - } - - status = p->ops->trans(p->private_data, &trans->in.data, &trans->out.data); - if (NT_STATUS_IS_ERR(status)) { - return status; - } + p->ipc_state = SVAL(trans->in.params.data, 0); trans->out.setup_count = 0; trans->out.setup = NULL; trans->out.params = data_blob(NULL, 0); + trans->out.data = data_blob(NULL, 0); return NT_STATUS_OK; } + /* SMBtrans - used to provide access to SMB pipes */ static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, struct smb_trans2 *trans) { NTSTATUS status; - if (strequal(trans->in.trans_name, "\\PIPE\\")) { /* Named pipe */ - switch (trans->in.setup[0]) { - case NAMED_PIPE_SETHANDLESTATE: - status = ipc_np_set_nm_state(ntvfs, req, trans); - break; - case NAMED_PIPE_TRANSACT: - status = ipc_np_trans(ntvfs, req, trans); - break; - default: - status = NT_STATUS_INVALID_PARAMETER; - break; - } - } else if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) { /* RAP */ - status = ipc_rap_call(req, trans); - } else { - DEBUG(1, ("Unknown transaction name `%s'\n", trans->in.trans_name)); - status = NT_STATUS_NOT_SUPPORTED; + if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) + return ipc_rap_call(req, trans); + + if (trans->in.setup_count != 2) { + return NT_STATUS_INVALID_PARAMETER; + } + + switch (trans->in.setup[0]) { + case TRANSACT_SETNAMEDPIPEHANDLESTATE: + status = ipc_set_nm_pipe_state(ntvfs, req, trans); + break; + case TRANSACT_DCERPCCMD: + status = ipc_dcerpc_cmd(ntvfs, req, trans); + break; + default: + status = NT_STATUS_INVALID_PARAMETER; + break; } return status; } + + /* initialialise the IPC backend, registering ourselves with the ntvfs subsystem */ @@ -735,9 +744,7 @@ NTSTATUS ntvfs_ipc_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - init_module_fn static_init[] = STATIC_ntvfs_ipc_MODULES; - init_module_fn *shared_init; - + ZERO_STRUCT(ops); /* fill in the name and type */ @@ -784,13 +791,5 @@ NTSTATUS ntvfs_ipc_init(void) return ret; } - /* load available named pipe backends */ - shared_init = load_samba_modules(NULL, "np"); - - run_init_functions(static_init); - run_init_functions(shared_init); - - talloc_free(shared_init); - return ret; } -- cgit From 99c559cd58478ae6bf6a2cb88293b0ab240a8e1f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 1 Feb 2006 05:20:54 +0000 Subject: r13276: start to work towards the BASE-DELETE test passing. This change ensures that we give the right error code to opens that are denied due to the file having delete pending set (This used to be commit c5b709fae66f9135e5c0e2eeb2e25dd8837b64de) --- source4/ntvfs/common/opendb.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 7d45f38840..af7be199f7 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -154,10 +154,12 @@ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, /* determine if two odb_entry structures conflict + + return NT_STATUS_OK on no conflict */ -static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) +static NTSTATUS share_conflict(struct odb_entry *e1, struct odb_entry *e2) { - if (e1->pending || e2->pending) return False; + if (e1->pending || e2->pending) return NT_STATUS_OK; /* if either open involves no read.write or delete access then it can't conflict */ @@ -166,25 +168,25 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) SEC_FILE_READ_DATA | SEC_FILE_EXECUTE | SEC_STD_DELETE))) { - return False; + return NT_STATUS_OK; } if (!(e2->access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | SEC_FILE_READ_DATA | SEC_FILE_EXECUTE | SEC_STD_DELETE))) { - return False; + return NT_STATUS_OK; } /* data IO access masks. This is skipped if the two open handles are on different streams (as in that case the masks don't interact) */ if (e1->stream_id != e2->stream_id) { - return False; + return NT_STATUS_OK; } #define CHECK_MASK(am, right, sa, share) \ - if (((am) & (right)) && !((sa) & (share))) return True + if (((am) & (right)) && !((sa) & (share))) return NT_STATUS_SHARING_VIOLATION CHECK_MASK(e1->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, e2->share_access, NTCREATEX_SHARE_ACCESS_WRITE); @@ -204,10 +206,10 @@ static BOOL share_conflict(struct odb_entry *e1, struct odb_entry *e2) /* if a delete is pending then a second open is not allowed */ if ((e1->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) || (e2->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { - return True; + return NT_STATUS_DELETE_PENDING; } - return False; + return NT_STATUS_OK; } /* @@ -242,9 +244,11 @@ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, count = dbuf.dsize / sizeof(struct odb_entry); for (i=0;i Date: Wed, 1 Feb 2006 10:04:11 +0000 Subject: r13281: Use TALLOC_CTX * not a void *, and use tmp_ctx as the name for consistancy. (I was chasing ghosts in this code, and decided to do a cleanup while I was there). Andrew Bartlett (This used to be commit c05f6be09a0cffdd0b87483f5b3751cc3f96e7f5) --- source4/ntvfs/common/sidmap.c | 117 +++++++++++++++++++++--------------------- 1 file changed, 59 insertions(+), 58 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index b2408d42bd..e96d65e138 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -128,15 +128,15 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, "unixName", "sAMAccountType", NULL }; int ret; const char *s; - void *ctx; + TALLOC_CTX *tmp_ctx; struct ldb_message **res; struct dom_sid *domain_sid; NTSTATUS status; - ctx = talloc_new(sidmap); + tmp_ctx = talloc_new(sidmap); - ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, - "objectSid=%s", ldap_encode_ndr_dom_sid(ctx, sid)); + ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, + "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); if (ret != 1) { goto allocated_sid; } @@ -144,8 +144,8 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, /* make sure its a user, not a group */ if (!is_user_account(res[0])) { DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", - dom_sid_string(ctx, sid))); - talloc_free(ctx); + dom_sid_string(tmp_ctx, sid))); + talloc_free(tmp_ctx); return NT_STATUS_INVALID_SID; } @@ -153,7 +153,7 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, s = samdb_result_string(res[0], "unixID", NULL); if (s != NULL) { *uid = strtoul(s, NULL, 0); - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } @@ -162,12 +162,13 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, if (s != NULL) { struct passwd *pwd = getpwnam(s); if (!pwd) { - DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, dom_sid_string(ctx, sid))); - talloc_free(ctx); + DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, + dom_sid_string(tmp_ctx, sid))); + talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; } *uid = pwd->pw_uid; - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } @@ -177,20 +178,20 @@ NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, struct passwd *pwd = getpwnam(s); if (!pwd) { DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", - s, dom_sid_string(ctx, sid))); - talloc_free(ctx); + s, dom_sid_string(tmp_ctx, sid))); + talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; } *uid = pwd->pw_uid; - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } allocated_sid: - status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid); + status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); if (!NT_STATUS_IS_OK(status)) { - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_DOMAIN; } @@ -199,16 +200,16 @@ allocated_sid: if (rid >= SIDMAP_LOCAL_USER_BASE && rid < SIDMAP_LOCAL_GROUP_BASE) { *uid = rid - SIDMAP_LOCAL_USER_BASE; - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } } DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", - dom_sid_string(ctx, sid))); + dom_sid_string(tmp_ctx, sid))); - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_INVALID_SID; } @@ -223,15 +224,15 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, "unixName", "sAMAccountType", NULL }; int ret; const char *s; - void *ctx; + TALLOC_CTX *tmp_ctx; struct ldb_message **res; NTSTATUS status; struct dom_sid *domain_sid; - ctx = talloc_new(sidmap); + tmp_ctx = talloc_new(sidmap); - ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, - "objectSid=%s", ldap_encode_ndr_dom_sid(ctx, sid)); + ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, + "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); if (ret != 1) { goto allocated_sid; } @@ -239,8 +240,8 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, /* make sure its not a user */ if (!is_group_account(res[0])) { DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", - dom_sid_string(ctx, sid))); - talloc_free(ctx); + dom_sid_string(tmp_ctx, sid))); + talloc_free(tmp_ctx); return NT_STATUS_INVALID_SID; } @@ -248,7 +249,7 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, s = samdb_result_string(res[0], "unixID", NULL); if (s != NULL) { *gid = strtoul(s, NULL, 0); - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } @@ -258,12 +259,12 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, struct group *grp = getgrnam(s); if (!grp) { DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", - s, dom_sid_string(ctx, sid))); - talloc_free(ctx); + s, dom_sid_string(tmp_ctx, sid))); + talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; } *gid = grp->gr_gid; - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } @@ -272,19 +273,19 @@ NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, if (s != NULL) { struct group *grp = getgrnam(s); if (!grp) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, dom_sid_string(ctx, sid))); - talloc_free(ctx); + DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, dom_sid_string(tmp_ctx, sid))); + talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_USER; } *gid = grp->gr_gid; - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } allocated_sid: - status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid); + status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); if (!NT_STATUS_IS_OK(status)) { - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_NO_SUCH_DOMAIN; } @@ -292,15 +293,15 @@ allocated_sid: uint32_t rid = sid->sub_auths[sid->num_auths-1]; if (rid >= SIDMAP_LOCAL_GROUP_BASE) { *gid = rid - SIDMAP_LOCAL_GROUP_BASE; - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_OK; } } DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", - dom_sid_string(ctx, sid))); + dom_sid_string(tmp_ctx, sid))); - talloc_free(ctx); + talloc_free(tmp_ctx); return NT_STATUS_INVALID_SID; } @@ -315,7 +316,7 @@ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, { const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL }; int ret, i; - void *ctx; + TALLOC_CTX *tmp_ctx; struct ldb_message **res; struct passwd *pwd; struct dom_sid *domain_sid; @@ -336,7 +337,7 @@ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, */ - ctx = talloc_new(sidmap); + tmp_ctx = talloc_new(mem_ctx); /* @@ -344,13 +345,13 @@ NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, given uid */ - ret = gendb_search(sidmap->samctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, "unixID=%u", (unsigned int)uid); for (i=0;isamctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, "(|(unixName=%s)(sAMAccountName=%s))", pwd->pw_name, pwd->pw_name); for (i=0;isamctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, "unixID=%u", (unsigned int)gid); for (i=0;isamctx, ctx, NULL, &res, attrs, + ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, "(|(unixName=%s)(sAMAccountName=%s))", grp->gr_name, grp->gr_name); for (i=0;isub_auths[sid->num_auths-1]; if (rid < SIDMAP_LOCAL_USER_BASE) { -- cgit From fd9a6d5e4679ba4d1480dcbff23fb49504573715 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Feb 2006 11:11:16 +0000 Subject: r13623: - make sure ntvfs_map_qfileinfo isn't used for async replies - add some comments metze (This used to be commit e1611b622184b48d2cef1eff2646a09f9e691f9b) --- source4/ntvfs/ntvfs_generic.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index b30508b1d7..e5224aafcd 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -495,8 +495,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo return NT_STATUS_INVALID_LEVEL; } - /* this map function is only used by the simple backend, which - doesn't do async */ + /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; /* ask the backend for the generic info */ @@ -854,6 +853,9 @@ _PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_file info2->generic.level = RAW_FILEINFO_GENERIC; info2->generic.in.fnum = info->generic.in.fnum; + /* only used by the simple backend, which doesn't do async */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + status = ntvfs->ops->qfileinfo(ntvfs, req, info2); if (!NT_STATUS_IS_OK(status)) { return status; @@ -937,6 +939,11 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck locks->offset = lck->lock.in.offset; locks->count = lck->lock.in.count; + /* + * we don't need to call ntvfs_map_async_setup() here, + * as lock() doesn't have any output fields + */ + return ntvfs->ops->lock(ntvfs, req, lck2); } @@ -1222,5 +1229,10 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct smbsrv_request *req, union smb_close *c break; } + /* + * we don't need to call ntvfs_map_async_setup() here, + * as close() doesn't have any output fields + */ + return ntvfs->ops->close(ntvfs, req, cl2); } -- cgit From 10d88a02d727ae16336eec8f696a94b76c1132cd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 11:29:01 +0000 Subject: r13652: Move some more stuff out off include/ (This used to be commit 26bf2a393b90acc098be0b30886dbba34d348a01) --- source4/ntvfs/ipc/ipc_rap.c | 2 +- source4/ntvfs/ipc/rap_server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index d93b67b715..f97ae4cd89 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "rap.h" +#include "libcli/rap/rap.h" #define NERR_Success 0 #define NERR_badpass 86 diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index c69ba2d168..b68f806ba1 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "rap.h" +#include "libcli/rap/rap.h" #include "librpc/gen_ndr/ndr_srvsvc.h" /* At this moment these are just dummy functions, but you might get the -- cgit From 80c8a522861068e7b0974986936f65052dd6f70f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 12:48:13 +0000 Subject: r13655: Use new name of build header (This used to be commit bca0e8054f6d9c7adc9d92e0c30d4323f994c9e9) --- source4/ntvfs/ntvfs_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 63476c7fee..cfd2c1f5de 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -26,7 +26,7 @@ #include "includes.h" #include "dlinklist.h" #include "smb_server/smb_server.h" -#include "smb_build.h" +#include "build.h" #include "ntvfs/ntvfs.h" /* the list of currently registered NTVFS backends, note that there -- cgit From dfc517b05395d925a4d7b1ce9633a849f9468e70 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 23 Feb 2006 15:52:24 +0000 Subject: r13658: More moving around of files: - Collect the generic utility functions into a lib/util/ (a la GLib is for the GNOME folks) - Remove even more files from include/ (This used to be commit ba62880f5b05c2a505dc7f54676b231197a7e707) --- source4/ntvfs/common/brlock.c | 7 ++++--- source4/ntvfs/config.mk | 15 ++++----------- source4/ntvfs/posix/config.mk | 2 +- source4/ntvfs/posix/pvfs_ioctl.c | 2 +- source4/ntvfs/print/vfs_print.c | 2 +- source4/ntvfs/unixuid/config.mk | 2 -- 6 files changed, 11 insertions(+), 19 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 3fc3c09316..6548a2c199 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -31,6 +31,7 @@ #include "messaging/messaging.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" +#include "libcli/libcli.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies @@ -237,7 +238,7 @@ NTSTATUS brl_lock(struct brl_context *brl, struct lock_struct lock, *locks=NULL; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = (uint8_t *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -287,7 +288,7 @@ NTSTATUS brl_lock(struct brl_context *brl, status = NT_STATUS_NO_MEMORY; goto fail; } else { - dbuf.dptr = (char *)locks; + dbuf.dptr = (uint8_t *)locks; } locks[count] = lock; dbuf.dsize += sizeof(lock); @@ -382,7 +383,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = (uint8_t *)file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 74b62809f7..8194fc1963 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -59,16 +59,6 @@ OBJ_FILES = \ # End MODULE ntvfs_nbench ################################################ -################################################ -# Start SUBSYSTEM ntvfs_common -[SUBSYSTEM::ntvfs_common] -OBJ_FILES = \ - common/brlock.o \ - common/opendb.o \ - common/sidmap.o -# End SUBSYSTEM ntvfs_common -################################################ - ################################################ # Start SUBSYSTEM NTVFS @@ -83,7 +73,10 @@ OBJ_FILES = \ ntvfs_base.o \ ntvfs_generic.o \ ntvfs_interface.o \ - ntvfs_util.o + ntvfs_util.o \ + common/brlock.o \ + common/opendb.o \ + common/sidmap.o # # End SUBSYSTEM NTVFS ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index a2a4685d8c..85fcc10e06 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -31,6 +31,6 @@ OBJ_FILES = \ pvfs_acl.o \ xattr_system.o \ xattr_tdb.o -REQUIRED_SUBSYSTEMS = NDR_XATTR ntvfs_common EXT_LIB_XATTR EXT_LIB_BLKID +REQUIRED_SUBSYSTEMS = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index abf575aa3d..b35a98fa87 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "ioctl.h" +#include "libcli/raw/ioctl.h" /* old ioctl interface diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index e933f5502b..b0c34b2abe 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -23,7 +23,7 @@ */ #include "includes.h" -#include "ioctl.h" +#include "libcli/raw/ioctl.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index d99229729c..bb811bca2b 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -5,7 +5,5 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = NTVFS OBJ_FILES = \ vfs_unixuid.o -REQUIRED_SUBSYSTEMS = \ - ntvfs_common # End MODULE ntvfs_unixuid ################################################ -- cgit From 04cf19bd597df38c391e236bfe95f5df7138cdef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Feb 2006 01:03:21 +0000 Subject: r13701: removed some unnecessary casts (This used to be commit f7d0ac936380102e087d4b7c336d7feb68b62314) --- source4/ntvfs/common/brlock.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 6548a2c199..ddbab257bc 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -238,7 +238,7 @@ NTSTATUS brl_lock(struct brl_context *brl, struct lock_struct lock, *locks=NULL; NTSTATUS status; - kbuf.dptr = (uint8_t *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -383,7 +383,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = (uint8_t *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -467,7 +467,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { @@ -538,7 +538,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, int count, i; struct lock_struct lock, *locks; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; dbuf = tdb_fetch(brl->w->tdb, kbuf); @@ -581,7 +581,7 @@ NTSTATUS brl_close(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = (char *)file_key->data; + kbuf.dptr = file_key->data; kbuf.dsize = file_key->length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { -- cgit From 6236e5cabc7b08849e43b25203702e82c9a63dea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Feb 2006 09:57:14 +0000 Subject: r13708: fix compiler warnings metze (This used to be commit 830c42afda70c616ccd32703c6e7c47f38c2271c) --- source4/ntvfs/common/opendb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index af7be199f7..330af47862 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -258,7 +258,7 @@ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, return NT_STATUS_NO_MEMORY; } - dbuf.dptr = (char *)elist; + dbuf.dptr = (uint8_t *)elist; dbuf.dsize = (count+1) * sizeof(struct odb_entry); memcpy(dbuf.dptr + (count*sizeof(struct odb_entry)), @@ -307,7 +307,7 @@ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) return NT_STATUS_NO_MEMORY; } - dbuf.dptr = (char *)elist; + dbuf.dptr = (uint8_t *)elist; dbuf.dsize = (count+1) * sizeof(struct odb_entry); memcpy(dbuf.dptr + (count*sizeof(struct odb_entry)), @@ -495,7 +495,7 @@ NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key, int i, count; struct odb_entry e; - kbuf.dptr = (char *)key->data; + kbuf.dptr = key->data; kbuf.dsize = key->length; dbuf = tdb_fetch(odb->w->tdb, kbuf); -- cgit From 40a8d58551526a0f367d23d0c9603a5b9d86b270 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 28 Feb 2006 03:47:02 +0000 Subject: r13739: a fairly major overhaul of the opendb code to allow the BASE-DELETE test to pass. To try to make the code a bit more understandable, I moved to using an IDL description of the opendb tdb record format. One of the larger changes was to make directory opens and creates go via the opendb code, so directory operations now obey all the share mode restrictions, as well as delete on close semantics. I also changed the period over which the opendb locks are held, to try to minimise races due to two open operations happening at the same time. (This used to be commit cd2602d05725e1734b0862131dd91601c6b6d51a) --- source4/ntvfs/common/opendb.c | 474 ++++++++++++----------- source4/ntvfs/posix/pvfs_fileinfo.c | 3 +- source4/ntvfs/posix/pvfs_open.c | 685 +++++++++++++++++++++++++++++---- source4/ntvfs/posix/pvfs_qfileinfo.c | 13 +- source4/ntvfs/posix/pvfs_rename.c | 15 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 14 +- source4/ntvfs/posix/pvfs_unlink.c | 6 +- 7 files changed, 887 insertions(+), 323 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 330af47862..1faa6387b7 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -46,6 +46,7 @@ #include "db_wrap.h" #include "smb_server/smb_server.h" #include "lib/messaging/irpc.h" +#include "librpc/gen_ndr/ndr_opendb.h" struct odb_context { struct tdb_wrap *w; @@ -53,22 +54,6 @@ struct odb_context { struct messaging_context *messaging_ctx; }; -/* - the database is indexed by a file_key, and contains entries of the - following form -*/ -struct odb_entry { - uint32_t server; - void *file_handle; - uint32_t stream_id; - uint32_t share_access; - uint32_t create_options; - uint32_t access_mask; - void *notify_ptr; - BOOL pending; -}; - - /* an odb lock handle. You must obtain one of these using odb_lock() before doing any other operations. @@ -157,10 +142,8 @@ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, return NT_STATUS_OK on no conflict */ -static NTSTATUS share_conflict(struct odb_entry *e1, struct odb_entry *e2) +static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2) { - if (e1->pending || e2->pending) return NT_STATUS_OK; - /* if either open involves no read.write or delete access then it can't conflict */ if (!(e1->access_mask & (SEC_FILE_WRITE_DATA | @@ -203,187 +186,198 @@ static NTSTATUS share_conflict(struct odb_entry *e1, struct odb_entry *e2) CHECK_MASK(e2->access_mask, SEC_STD_DELETE, e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE); - /* if a delete is pending then a second open is not allowed */ - if ((e1->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) || - (e2->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { - return NT_STATUS_DELETE_PENDING; - } - return NT_STATUS_OK; } /* - register an open file in the open files database. This implements the share_access - rules + pull a record, translating from the db format to the opendb_file structure defined + in opendb.idl */ -NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, - uint32_t stream_id, - uint32_t share_access, uint32_t create_options, - uint32_t access_mask) +static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) { struct odb_context *odb = lck->odb; TDB_DATA dbuf; - struct odb_entry e; - int i, count; - struct odb_entry *elist; + DATA_BLOB blob; + NTSTATUS status; dbuf = tdb_fetch(odb->w->tdb, lck->key); - - e.server = odb->server; - e.file_handle = file_handle; - e.stream_id = stream_id; - e.share_access = share_access; - e.create_options = create_options; - e.access_mask = access_mask; - e.notify_ptr = NULL; - e.pending = False; - - /* check the existing file opens to see if they - conflict */ - elist = (struct odb_entry *)dbuf.dptr; - count = dbuf.dsize / sizeof(struct odb_entry); - - for (i=0;iw->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { - free(dbuf.dptr); + return status; +} + +/* + push a record, translating from the opendb_file structure defined in opendb.idl +*/ +static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) +{ + struct odb_context *odb = lck->odb; + TDB_DATA dbuf; + DATA_BLOB blob; + NTSTATUS status; + int ret; + + if (file->num_entries == 0) { + ret = tdb_delete(odb->w->tdb, lck->key); + if (ret != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return NT_STATUS_OK; + } + + status = ndr_push_struct_blob(&blob, lck, file, (ndr_push_flags_fn_t)ndr_push_opendb_file); + NT_STATUS_NOT_OK_RETURN(status); + + dbuf.dptr = blob.data; + dbuf.dsize = blob.length; + + ret = tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE); + data_blob_free(&blob); + if (ret != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - free(dbuf.dptr); return NT_STATUS_OK; } /* - register a pending open file in the open files database + register an open file in the open files database. This implements the share_access + rules + + Note that the path is only used by the delete on close logic, not + for comparing with other filenames */ -NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) +NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, BOOL delete_on_close, + const char *path) { struct odb_context *odb = lck->odb; - TDB_DATA dbuf; - struct odb_entry e; - struct odb_entry *elist; - int count; - - dbuf = tdb_fetch(odb->w->tdb, lck->key); + struct opendb_entry e; + int i; + struct opendb_file file; + NTSTATUS status; - e.server = odb->server; - e.file_handle = NULL; - e.stream_id = 0; - e.share_access = 0; - e.create_options = 0; - e.access_mask = 0; - e.notify_ptr = private; - e.pending = True; - - /* check the existing file opens to see if they - conflict */ - elist = (struct odb_entry *)dbuf.dptr; - count = dbuf.dsize / sizeof(struct odb_entry); - - elist = realloc_p(dbuf.dptr, struct odb_entry, count+1); - if (elist == NULL) { - if (dbuf.dptr) free(dbuf.dptr); - return NT_STATUS_NO_MEMORY; + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + /* initialise a blank structure */ + ZERO_STRUCT(file); + file.path = path; + } else { + NT_STATUS_NOT_OK_RETURN(status); } - dbuf.dptr = (uint8_t *)elist; - dbuf.dsize = (count+1) * sizeof(struct odb_entry); - memcpy(dbuf.dptr + (count*sizeof(struct odb_entry)), - &e, sizeof(struct odb_entry)); + if (file.delete_on_close || + (file.num_entries != 0 && delete_on_close)) { + /* while delete on close is set, no new opens are allowed */ + return NT_STATUS_DELETE_PENDING; + } - if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { - free(dbuf.dptr); - return NT_STATUS_INTERNAL_DB_CORRUPTION; + /* see if it conflicts */ + e.server = odb->server; + e.file_handle = file_handle; + e.stream_id = stream_id; + e.share_access = share_access; + e.access_mask = access_mask; + e.delete_on_close = delete_on_close; + + for (i=0;iodb; - TDB_DATA dbuf; - struct odb_entry *elist; - int i, count; + struct opendb_file file; NTSTATUS status; + + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); - dbuf = tdb_fetch(odb->w->tdb, lck->key); + file.pending = talloc_realloc(lck, file.pending, struct opendb_pending, + file.num_pending+1); + NT_STATUS_HAVE_NO_MEMORY(file.pending); - if (dbuf.dptr == NULL) { - return NT_STATUS_UNSUCCESSFUL; - } + file.pending[file.num_pending].server = odb->server; + file.pending[file.num_pending].notify_ptr = private; - elist = (struct odb_entry *)dbuf.dptr; - count = dbuf.dsize / sizeof(struct odb_entry); + file.num_pending++; - /* send any pending notifications, removing them once sent */ - for (i=0;imessaging_ctx, elist[i].server, - MSG_PVFS_RETRY_OPEN, elist[i].notify_ptr); - memmove(&elist[i], &elist[i+1], sizeof(struct odb_entry)*(count-(i+1))); - i--; - count--; - } - } + return odb_push_record(lck, &file); +} + + +/* + remove a opendb entry +*/ +NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) +{ + struct odb_context *odb = lck->odb; + struct opendb_file file; + int i; + NTSTATUS status; + + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); /* find the entry, and delete it */ - for (i=0;iserver == elist[i].server) { - if (i < count-1) { - memmove(elist+i, elist+i+1, - (count - (i+1)) * sizeof(struct odb_entry)); + for (i=0;iserver == file.entries[i].server) { + if (file.entries[i].delete_on_close) { + file.delete_on_close = True; + } + if (i < file.num_entries-1) { + memmove(file.entries+i, file.entries+i+1, + (file.num_entries - (i+1)) * + sizeof(struct opendb_entry)); } break; } } - status = NT_STATUS_OK; - - if (i == count) { - status = NT_STATUS_UNSUCCESSFUL; - } else if (count == 1) { - if (tdb_delete(odb->w->tdb, lck->key) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } else { - dbuf.dsize = (count-1) * sizeof(struct odb_entry); - if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } + if (i == file.num_entries) { + return NT_STATUS_UNSUCCESSFUL; } - free(dbuf.dptr); + /* send any pending notifications, removing them once sent */ + for (i=0;imessaging_ctx, file.pending[i].server, + MSG_PVFS_RETRY_OPEN, + file.pending[i].notify_ptr); + } + file.num_pending = 0; - return status; + file.num_entries--; + + return odb_push_record(lck, &file); } @@ -393,91 +387,112 @@ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) { struct odb_context *odb = lck->odb; - TDB_DATA dbuf; - struct odb_entry *elist; - int i, count; + int i; NTSTATUS status; + struct opendb_file file; - dbuf = tdb_fetch(odb->w->tdb, lck->key); - - if (dbuf.dptr == NULL) { - return NT_STATUS_UNSUCCESSFUL; - } - - elist = (struct odb_entry *)dbuf.dptr; - count = dbuf.dsize / sizeof(struct odb_entry); + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); /* find the entry, and delete it */ - for (i=0;iserver == elist[i].server) { - if (i < count-1) { - memmove(elist+i, elist+i+1, - (count - (i+1)) * sizeof(struct odb_entry)); + for (i=0;iserver == file.pending[i].server) { + if (i < file.num_pending-1) { + memmove(file.pending+i, file.pending+i+1, + (file.num_pending - (i+1)) * + sizeof(struct opendb_pending)); } break; } } - status = NT_STATUS_OK; - - if (i == count) { - status = NT_STATUS_UNSUCCESSFUL; - } else if (count == 1) { - if (tdb_delete(odb->w->tdb, lck->key) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } else { - dbuf.dsize = (count-1) * sizeof(struct odb_entry); - if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } + if (i == file.num_pending) { + return NT_STATUS_UNSUCCESSFUL; } - free(dbuf.dptr); - - return status; + file.num_pending--; + + return odb_push_record(lck, &file); } /* - update create options on an open file + rename the path in a open file */ -NTSTATUS odb_set_create_options(struct odb_lock *lck, - void *file_handle, uint32_t create_options) +NTSTATUS odb_rename(struct odb_lock *lck, const char *path) { - struct odb_context *odb = lck->odb; - TDB_DATA dbuf; - struct odb_entry *elist; - int i, count; + struct opendb_file file; NTSTATUS status; - dbuf = tdb_fetch(odb->w->tdb, lck->key); - if (dbuf.dptr == NULL) { - return NT_STATUS_UNSUCCESSFUL; + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { + /* not having the record at all is OK */ + return NT_STATUS_OK; } + NT_STATUS_NOT_OK_RETURN(status); + + file.path = path; + return odb_push_record(lck, &file); +} + +/* + update delete on close flag on an open file +*/ +NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) +{ + NTSTATUS status; + struct opendb_file file; - elist = (struct odb_entry *)dbuf.dptr; - count = dbuf.dsize / sizeof(struct odb_entry); + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); - /* find the entry, and modify it */ - for (i=0;iserver == elist[i].server) { - elist[i].create_options = create_options; - break; - } + file.delete_on_close = del_on_close; + + return odb_push_record(lck, &file); +} + +/* + return the current value of the delete_on_close bit, and how many + people still have the file open +*/ +NTSTATUS odb_get_delete_on_close(struct odb_context *odb, + DATA_BLOB *key, BOOL *del_on_close, + int *open_count, char **path) +{ + NTSTATUS status; + struct opendb_file file; + struct odb_lock *lck; + + lck = odb_lock(odb, odb, key); + NT_STATUS_HAVE_NO_MEMORY(lck); + + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { + talloc_free(lck); + (*del_on_close) = False; + return NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; } - if (tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } else { - status = NT_STATUS_OK; + (*del_on_close) = file.delete_on_close; + if (open_count != NULL) { + (*open_count) = file.num_entries; + } + if (path != NULL) { + *path = talloc_strdup(odb, file.path); + NT_STATUS_HAVE_NO_MEMORY(*path); + if (file.num_entries == 1 && file.entries[0].delete_on_close) { + (*del_on_close) = True; + } } - free(dbuf.dptr); + talloc_free(lck); - return status; + return NT_STATUS_OK; } @@ -485,46 +500,40 @@ NTSTATUS odb_set_create_options(struct odb_lock *lck, determine if a file can be opened with the given share_access, create_options and access_mask */ -NTSTATUS odb_can_open(struct odb_context *odb, DATA_BLOB *key, +NTSTATUS odb_can_open(struct odb_lock *lck, uint32_t share_access, uint32_t create_options, uint32_t access_mask) { - TDB_DATA dbuf; - TDB_DATA kbuf; - struct odb_entry *elist; - int i, count; - struct odb_entry e; - - kbuf.dptr = key->data; - kbuf.dsize = key->length; + struct odb_context *odb = lck->odb; + NTSTATUS status; + struct opendb_file file; + struct opendb_entry e; + int i; - dbuf = tdb_fetch(odb->w->tdb, kbuf); - if (dbuf.dptr == NULL) { + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { return NT_STATUS_OK; } + NT_STATUS_NOT_OK_RETURN(status); - elist = (struct odb_entry *)dbuf.dptr; - count = dbuf.dsize / sizeof(struct odb_entry); + if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + file.num_entries != 0) { + return NT_STATUS_SHARING_VIOLATION; + } - if (count == 0) { - free(dbuf.dptr); - return NT_STATUS_OK; + if (file.delete_on_close) { + return NT_STATUS_DELETE_PENDING; } - e.server = odb->server; - e.file_handle = NULL; - e.stream_id = 0; - e.share_access = share_access; - e.create_options = create_options; - e.access_mask = access_mask; - e.notify_ptr = NULL; - e.pending = False; - - for (i=0;iserver; + e.file_handle = NULL; + e.stream_id = 0; + e.share_access = share_access; + e.access_mask = access_mask; + + for (i=0;ist.st_mode)) { name->st.st_size = 0; + name->st.st_nlink = 1; } /* for now just use the simple samba mapping */ diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5aeb5eb7e8..a8c0bba97f 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -68,17 +68,41 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, static int pvfs_dir_handle_destructor(void *p) { struct pvfs_file_handle *h = p; + int open_count; + char *path; - if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { - NTSTATUS status = pvfs_xattr_unlink_hook(h->pvfs, h->name->full_name); + if (h->name->stream_name == NULL && + pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && + open_count == 1) { + NTSTATUS status; + status = pvfs_xattr_unlink_hook(h->pvfs, path); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Warning: xattr rmdir hook failed for '%s' - %s\n", - h->name->full_name, nt_errstr(status))); + DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", + path, nt_errstr(status))); + } + if (rmdir(path) != 0) { + DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n", + path, strerror(errno))); + } + } + + if (h->have_opendb_entry) { + struct odb_lock *lck; + NTSTATUS status; + + lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for close\n")); + return 0; } - if (rmdir(h->name->full_name) != 0 && errno != ENOTEMPTY) { - DEBUG(0,("pvfs_close: failed to rmdir '%s' - %s\n", - h->name->full_name, strerror(errno))); + + status = odb_close_file(lck, h); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); } + + talloc_free(lck); } return 0; @@ -133,6 +157,379 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, return status; } +/* + form the lock context used for opendb locking. Note that we must + zero here to take account of possible padding on some architectures +*/ +static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, + TALLOC_CTX *mem_ctx, DATA_BLOB *key) +{ + struct { + dev_t device; + ino_t inode; + } lock_context; + ZERO_STRUCT(lock_context); + + lock_context.device = name->st.st_dev; + lock_context.inode = name->st.st_ino; + + *key = data_blob_talloc(mem_ctx, &lock_context, sizeof(lock_context)); + if (key->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + + +/* + create a new directory +*/ +static NTSTATUS pvfs_create_directory(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + union smb_open *io) +{ + struct pvfs_file *f; + NTSTATUS status; + int fnum, ret; + struct odb_lock *lck; + uint32_t create_options = io->generic.in.create_options; + uint32_t share_access = io->generic.in.share_access; + uint32_t access_mask = io->generic.in.access_mask; + mode_t mode; + uint32_t attrib; + BOOL del_on_close; + + if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && + (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + return NT_STATUS_CANNOT_DELETE; + } + + status = pvfs_access_check_create(pvfs, req, name, &access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + f = talloc(req, struct pvfs_file); + if (f == NULL) { + return NT_STATUS_NO_MEMORY; + } + + f->handle = talloc(f, struct pvfs_file_handle); + if (f->handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + + fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_NEW_FNUM, UINT16_MAX); + if (fnum == -1) { + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + + attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_DIRECTORY; + mode = pvfs_fileperms(pvfs, attrib); + + /* create the directory */ + ret = mkdir(name->full_name, mode); + if (ret == -1) { + idr_remove(pvfs->idtree_fnum, fnum); + return pvfs_map_errno(pvfs, errno); + } + + pvfs_xattr_unlink_hook(pvfs, name->full_name); + + /* re-resolve the new directory */ + status = pvfs_resolve_name_fd(pvfs, -1, name); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, fnum); + rmdir(name->full_name); + return status; + } + + name->dos.attrib = attrib; + + status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, fnum, io); + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; + } + + /* form the lock context used for opendb locking */ + status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; + } + + /* grab a lock on the open file record */ + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", + name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto cleanup_delete; + } + + if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + del_on_close = True; + } else { + del_on_close = False; + } + + status = odb_open_file(lck, f->handle, name->stream_id, + share_access, access_mask, del_on_close, name->full_name); + talloc_free(lck); + if (!NT_STATUS_IS_OK(status)) { + /* bad news, we must have hit a race */ + idr_remove(pvfs->idtree_fnum, fnum); + return status; + } + + f->fnum = fnum; + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->share_access = io->generic.in.share_access; + f->access_mask = access_mask; + f->impersonation = io->generic.in.impersonation; + + f->handle->pvfs = pvfs; + f->handle->name = talloc_steal(f->handle, name); + f->handle->fd = -1; + f->handle->create_options = io->generic.in.create_options; + f->handle->seek_offset = 0; + f->handle->position = 0; + f->handle->mode = 0; + f->handle->have_opendb_entry = True; + f->handle->sticky_write_time = False; + + DLIST_ADD(pvfs->open_files, f); + + /* setup a destructor to avoid file descriptor leaks on + abnormal termination */ + talloc_set_destructor(f, pvfs_dir_fnum_destructor); + talloc_set_destructor(f->handle, pvfs_dir_handle_destructor); + + io->generic.out.oplock_level = OPLOCK_NONE; + io->generic.out.fnum = f->fnum; + io->generic.out.create_action = NTCREATEX_ACTION_CREATED; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 0; + + /* success - keep the file handle */ + talloc_steal(pvfs, f); + + return NT_STATUS_OK; + +cleanup_delete: + idr_remove(pvfs->idtree_fnum, fnum); + rmdir(name->full_name); + return status; +} + +#if 0 +/* + open a directory +*/ +static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + union smb_open *io) +{ + struct pvfs_file *f; + NTSTATUS status; + int fnum; + struct odb_lock *lck; + uint32_t create_options; + uint32_t share_access; + uint32_t access_mask; + BOOL del_on_close; + + create_options = io->generic.in.create_options; + share_access = io->generic.in.share_access; + access_mask = io->generic.in.access_mask; + + /* certain create options are not allowed */ + if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + !(access_mask & SEC_STD_DELETE)) { + return NT_STATUS_INVALID_PARAMETER; + } + + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_SUPERSEDE: + case NTCREATEX_DISP_OVERWRITE_IF: + case NTCREATEX_DISP_OPEN_IF: + break; + + case NTCREATEX_DISP_OPEN: + case NTCREATEX_DISP_OVERWRITE: + if (!name->exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + break; + + case NTCREATEX_DISP_CREATE: + if (name->exists) { + return NT_STATUS_OBJECT_NAME_COLLISION; + } + break; + + default: + return NT_STATUS_INVALID_PARAMETER; + } + + /* handle creating a new directory separately */ + if (!name->exists) { + status = pvfs_create_directory(pvfs, req, name, io); + if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { + return status; + } + + /* we've hit a race - the directory was created during this call */ + if (io->generic.in.open_disposition == NTCREATEX_DISP_CREATE) { + return status; + } + + /* try re-resolving the name */ + status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + /* fall through to a normal open */ + } + + if ((name->dos.attrib & FILE_ATTRIBUTE_READONLY) && + (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + return NT_STATUS_CANNOT_DELETE; + } + + /* check the security descriptor */ + status = pvfs_access_check(pvfs, req, name, &access_mask); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + f = talloc(req, struct pvfs_file); + if (f == NULL) { + return NT_STATUS_NO_MEMORY; + } + + f->handle = talloc(f, struct pvfs_file_handle); + if (f->handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* allocate a fnum */ + fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); + if (fnum == -1) { + return NT_STATUS_TOO_MANY_OPENED_FILES; + } + + f->fnum = fnum; + f->session = req->session; + f->smbpid = req->smbpid; + f->pvfs = pvfs; + f->pending_list = NULL; + f->lock_count = 0; + f->share_access = io->generic.in.share_access; + f->access_mask = access_mask; + f->impersonation = io->generic.in.impersonation; + + f->handle->pvfs = pvfs; + f->handle->fd = -1; + f->handle->name = talloc_steal(f->handle, name); + f->handle->create_options = io->generic.in.create_options; + f->handle->seek_offset = 0; + f->handle->position = 0; + f->handle->mode = 0; + f->handle->have_opendb_entry = False; + f->handle->sticky_write_time = False; + + /* form the lock context used for opendb locking */ + status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, f->fnum); + return status; + } + + /* get a lock on this file before the actual open */ + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", + name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + idr_remove(pvfs->idtree_fnum, fnum); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + DLIST_ADD(pvfs->open_files, f); + + /* setup a destructor to avoid file descriptor leaks on + abnormal termination */ + talloc_set_destructor(f, pvfs_dir_fnum_destructor); + talloc_set_destructor(f->handle, pvfs_dir_handle_destructor); + + if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + pvfs_directory_empty(pvfs, f->handle->name)) { + del_on_close = True; + } else { + del_on_close = False; + } + + /* see if we are allowed to open at the same time as existing opens */ + status = odb_open_file(lck, f->handle, f->handle->name->stream_id, + share_access, access_mask, del_on_close, name->full_name); + +#if 0 + /* we don't do async open retries on directories yet */ + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_open_setup_retry(ntvfs, req, io, f, lck); + } +#endif + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } + + f->handle->have_opendb_entry = True; + + talloc_free(lck); + + io->generic.out.oplock_level = OPLOCK_NONE; + io->generic.out.fnum = f->fnum; + io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.attrib = name->dos.attrib; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.file_type = FILE_TYPE_DISK; + io->generic.out.ipc_state = 0; + io->generic.out.is_directory = 0; + + /* success - keep the file handle */ + talloc_steal(f->pvfs, f); + + return NT_STATUS_OK; +} +#endif + +#if 1 /* open a directory */ @@ -146,6 +543,13 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, NTSTATUS status; uint32_t create_action; uint32_t access_mask = io->generic.in.access_mask; + struct odb_lock *lck; + BOOL del_on_close; + uint32_t create_options; + uint32_t share_access; + + create_options = io->generic.in.create_options; + share_access = io->generic.in.share_access; if (name->stream_name) { return NT_STATUS_NOT_A_DIRECTORY; @@ -227,10 +631,47 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->mode = 0; f->handle->sticky_write_time = False; - DLIST_ADD(pvfs->open_files, f); + if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + pvfs_directory_empty(pvfs, f->handle->name)) { + del_on_close = True; + } else { + del_on_close = False; + } + + + if (name->exists) { + /* form the lock context used for opendb locking */ + status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, f->fnum); + return status; + } + + /* get a lock on this file before the actual open */ + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", + name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + idr_remove(pvfs->idtree_fnum, fnum); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* see if we are allowed to open at the same time as existing opens */ + status = odb_open_file(lck, f->handle, f->handle->name->stream_id, + share_access, access_mask, del_on_close, name->full_name); + + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, f->fnum); + talloc_free(lck); + return status; + } + + f->handle->have_opendb_entry = True; + } - /* TODO: should we check in the opendb? Do directory opens - follow the share_access rules? */ + DLIST_ADD(pvfs->open_files, f); /* setup destructors to avoid leaks on abnormal termination */ talloc_set_destructor(f->handle, pvfs_dir_handle_destructor); @@ -239,6 +680,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, if (!name->exists) { uint32_t attrib = io->generic.in.file_attr | FILE_ATTRIBUTE_DIRECTORY; mode_t mode = pvfs_fileperms(pvfs, attrib); + if (mkdir(name->full_name, mode) == -1) { idr_remove(pvfs->idtree_fnum, fnum); return pvfs_map_errno(pvfs,errno); @@ -256,6 +698,32 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, goto cleanup_delete; } + /* form the lock context used for opendb locking */ + status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); + if (!NT_STATUS_IS_OK(status)) { + idr_remove(pvfs->idtree_fnum, f->fnum); + return status; + } + + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", + name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + idr_remove(pvfs->idtree_fnum, fnum); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = odb_open_file(lck, f->handle, f->handle->name->stream_id, + share_access, access_mask, del_on_close, name->full_name); + + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; + } + + f->handle->have_opendb_entry = True; + create_action = NTCREATEX_ACTION_CREATED; } else { create_action = NTCREATEX_ACTION_EXISTED; @@ -290,6 +758,7 @@ cleanup_delete: rmdir(name->full_name); return status; } +#endif /* destroy a struct pvfs_file_handle @@ -297,6 +766,8 @@ cleanup_delete: static int pvfs_handle_destructor(void *p) { struct pvfs_file_handle *h = p; + int open_count; + char *path; /* the write time is no longer sticky */ if (h->sticky_write_time) { @@ -326,17 +797,18 @@ static int pvfs_handle_destructor(void *p) h->fd = -1; } - if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - h->name->stream_name == NULL) { + if (h->name->stream_name == NULL && + pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && + open_count == 1) { NTSTATUS status; - status = pvfs_xattr_unlink_hook(h->pvfs, h->name->full_name); + status = pvfs_xattr_unlink_hook(h->pvfs, path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", - h->name->full_name, nt_errstr(status))); + path, nt_errstr(status))); } - if (unlink(h->name->full_name) != 0) { + if (unlink(path) != 0) { DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", - h->name->full_name, strerror(errno))); + path, strerror(errno))); } } @@ -378,30 +850,6 @@ static int pvfs_fnum_destructor(void *p) } -/* - form the lock context used for opendb locking. Note that we must - zero here to take account of possible padding on some architectures -*/ -static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, - TALLOC_CTX *mem_ctx, DATA_BLOB *key) -{ - struct { - dev_t device; - ino_t inode; - } lock_context; - ZERO_STRUCT(lock_context); - - lock_context.device = name->st.st_dev; - lock_context.inode = name->st.st_ino; - - *key = data_blob_talloc(mem_ctx, &lock_context, sizeof(lock_context)); - if (key->data == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - /* form the lock context used for byte range locking. This is separate from the locking key used for opendb locking as it needs to take @@ -451,6 +899,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t access_mask = io->generic.in.access_mask; mode_t mode; uint32_t attrib; + BOOL del_on_close; + struct pvfs_filename *parent; if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { @@ -458,8 +908,20 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } status = pvfs_access_check_create(pvfs, req, name, &access_mask); - if (!NT_STATUS_IS_OK(status)) { - return status; + NT_STATUS_NOT_OK_RETURN(status); + + /* check that the parent isn't opened with delete on close set */ + status = pvfs_resolve_parent(pvfs, req, name, &parent); + if (NT_STATUS_IS_OK(status)) { + DATA_BLOB locking_key; + status = pvfs_locking_key(parent, req, &locking_key); + NT_STATUS_NOT_OK_RETURN(status); + status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, + &del_on_close, NULL, NULL); + NT_STATUS_NOT_OK_RETURN(status); + if (del_on_close) { + return NT_STATUS_DELETE_PENDING; + } } if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { @@ -548,8 +1010,14 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, goto cleanup_delete; } + if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + del_on_close = True; + } else { + del_on_close = False; + } + status = odb_open_file(lck, f->handle, name->stream_id, - share_access, create_options, access_mask); + share_access, access_mask, del_on_close, name->full_name); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { /* bad news, we must have hit a race - we don't delete the file @@ -1037,10 +1505,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_set_destructor(f, pvfs_fnum_destructor); talloc_set_destructor(f->handle, pvfs_handle_destructor); - /* see if we are allowed to open at the same time as existing opens */ status = odb_open_file(lck, f->handle, f->handle->name->stream_id, - share_access, create_options, access_mask); + share_access, access_mask, False, name->full_name); /* on a sharing violation we need to retry when the file is closed by the other user, or after 1 second */ @@ -1222,41 +1689,36 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, /* - change the create options on an already open file + change the delete on close flag on an already open file */ -NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, - struct smbsrv_request *req, - struct pvfs_file *f, uint32_t create_options) +NTSTATUS pvfs_set_delete_on_close(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_file *f, BOOL del_on_close) { struct odb_lock *lck; NTSTATUS status; - if (f->handle->create_options == create_options) { - return NT_STATUS_OK; - } - - if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && - (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_READONLY) && del_on_close) { return NT_STATUS_CANNOT_DELETE; } - - if (f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { - if (!pvfs_directory_empty(pvfs, f->handle->name)) { - return NT_STATUS_DIRECTORY_NOT_EMPTY; - } - f->handle->create_options = create_options; - return NT_STATUS_OK; + + if ((f->handle->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + !pvfs_directory_empty(pvfs, f->handle->name)) { + return NT_STATUS_DIRECTORY_NOT_EMPTY; } + if (del_on_close) { + f->handle->create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + } else { + f->handle->create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE; + } + lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); if (lck == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_set_create_options(lck, f->handle, create_options); - if (NT_STATUS_IS_OK(status)) { - f->handle->create_options = create_options; - } + status = odb_set_delete_on_close(lck, del_on_close); talloc_free(lck); @@ -1270,17 +1732,25 @@ NTSTATUS pvfs_change_create_options(struct pvfs_state *pvfs, */ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, struct smbsrv_request *req, - struct pvfs_filename *name) + struct pvfs_filename *name, + struct odb_lock **lckp) { NTSTATUS status; DATA_BLOB key; + struct odb_lock *lck; status = pvfs_locking_key(name, name, &key); if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_NO_MEMORY; } - status = odb_can_open(pvfs->odb_context, &key, + lck = odb_lock(req, pvfs->odb_context, &key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for can_delete\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = odb_can_open(lck, NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE, @@ -1291,6 +1761,13 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE); } + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + *lckp = lck; + } else if (lckp != NULL) { + *lckp = lck; + } + return status; } @@ -1298,21 +1775,89 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, determine if a file can be renamed, or if it is prevented by an already open file */ -NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, struct pvfs_filename *name) +NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name, + struct odb_lock **lckp) { NTSTATUS status; DATA_BLOB key; + struct odb_lock *lck; status = pvfs_locking_key(name, name, &key); if (!NT_STATUS_IS_OK(status)) { return NT_STATUS_NO_MEMORY; } - status = odb_can_open(pvfs->odb_context, &key, + lck = odb_lock(req, pvfs->odb_context, &key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for can_stat\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = odb_can_open(lck, NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE, 0, SEC_STD_DELETE); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + *lckp = lck; + } else if (lckp != NULL) { + *lckp = lck; + } + return status; } + +/* + determine if file meta data can be accessed, or if it is prevented by an + already open file +*/ +NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, + struct smbsrv_request *req, + struct pvfs_filename *name) +{ + NTSTATUS status; + DATA_BLOB key; + struct odb_lock *lck; + + status = pvfs_locking_key(name, name, &key); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_NO_MEMORY; + } + + lck = odb_lock(req, pvfs->odb_context, &key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for can_stat\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = odb_can_open(lck, + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE, + 0, 0); + + return status; +} + + +/* + determine if delete on close is set on +*/ +BOOL pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h, + int *open_count, char **path) +{ + NTSTATUS status; + BOOL del_on_close; + + status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, + &del_on_close, open_count, path); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("WARNING: unable to determine delete on close status for open file\n")); + return False; + } + + return del_on_close; +} diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 1f2f86e953..ca26331373 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -185,7 +185,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, case RAW_FILEINFO_STANDARD_INFORMATION: info->standard_info.out.alloc_size = name->dos.alloc_size; info->standard_info.out.size = name->st.st_size; - info->standard_info.out.nlink = name->st.st_nlink; + info->standard_info.out.nlink = name->dos.nlink; info->standard_info.out.delete_pending = 0; info->standard_info.out.directory = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; @@ -210,7 +210,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, info->all_info.out.attrib = name->dos.attrib; info->all_info.out.alloc_size = name->dos.alloc_size; info->all_info.out.size = name->st.st_size; - info->all_info.out.nlink = name->st.st_nlink; + info->all_info.out.nlink = name->dos.nlink; info->all_info.out.delete_pending = 0; info->all_info.out.directory = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; @@ -298,6 +298,11 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + status = pvfs_can_stat(pvfs, req, name); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_DELETE_PENDING; + } + status = pvfs_access_check_simple(pvfs, req, name, pvfs_fileinfo_access(info->generic.level)); if (!NT_STATUS_IS_OK(status)) { @@ -345,7 +350,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, switch (info->generic.level) { case RAW_FILEINFO_STANDARD_INFO: case RAW_FILEINFO_STANDARD_INFORMATION: - if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { info->standard_info.out.delete_pending = 1; info->standard_info.out.nlink--; } @@ -353,7 +358,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, case RAW_FILEINFO_ALL_INFO: case RAW_FILEINFO_ALL_INFORMATION: - if (h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { info->all_info.out.delete_pending = 1; info->all_info.out.nlink--; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index b70f129888..7f1f43e719 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -130,6 +130,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, struct pvfs_filename *name1, *name2; TALLOC_CTX *mem_ctx = talloc_new(req); NTSTATUS status; + struct odb_lock *lck, *lck2; /* resolve the wildcard pattern for this name */ fname2 = pvfs_resolve_wildcard(mem_ctx, fname1, fname2); @@ -150,7 +151,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, goto failed; } - status = pvfs_can_rename(pvfs, name1); + status = pvfs_can_rename(pvfs, req, name1, &lck); if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -159,7 +160,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, status = pvfs_resolve_partial(pvfs, mem_ctx, dir_path, fname2, &name2); if (NT_STATUS_IS_OK(status)) { - status = pvfs_can_delete(pvfs, req, name2); + status = pvfs_can_delete(pvfs, req, name2, &lck2); if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -177,6 +178,8 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, return pvfs_map_errno(pvfs, errno); } + status = odb_rename(lck, fname2); + failed: talloc_free(mem_ctx); return status; @@ -246,6 +249,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; + struct odb_lock *lck; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, @@ -286,7 +290,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_can_rename(pvfs, name1); + status = pvfs_can_rename(pvfs, req, name1, &lck); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -294,6 +298,8 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, if (rename(name1->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } + + status = odb_rename(lck, name2->full_name); return NT_STATUS_OK; } @@ -308,6 +314,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; + struct odb_lock *lck; switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: @@ -353,7 +360,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_can_rename(pvfs, name1); + status = pvfs_can_rename(pvfs, req, name1, &lck); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 0753ccb40b..69c9cd5e4a 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -121,6 +121,8 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, /* if the destination exists, then check the rename is allowed */ if (name2->exists) { + struct odb_lock *lck; + if (strcmp(name2->full_name, name->full_name) == 0) { /* rename to same name is null-op */ return NT_STATUS_OK; @@ -130,7 +132,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_can_delete(pvfs, req, name2); + status = pvfs_can_delete(pvfs, req, name2, &lck); if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { return NT_STATUS_ACCESS_DENIED; } @@ -243,7 +245,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct utimbuf unix_times; struct pvfs_file *f; struct pvfs_file_handle *h; - uint32_t create_options; struct pvfs_filename newstats; NTSTATUS status; uint32_t access_needed; @@ -322,13 +323,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: - create_options = h->create_options; - if (info->disposition_info.in.delete_on_close) { - create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; - } else { - create_options &= ~NTCREATEX_OPTIONS_DELETE_ON_CLOSE; - } - return pvfs_change_create_options(pvfs, req, f, create_options); + return pvfs_set_delete_on_close(pvfs, req, f, + info->disposition_info.in.delete_on_close); case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 5f8a828f15..8eea2c47b8 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -33,6 +33,7 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, uint16_t attrib) { NTSTATUS status; + struct odb_lock *lck; if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -44,7 +45,7 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, return status; } - status = pvfs_can_delete(pvfs, req, name); + status = pvfs_can_delete(pvfs, req, name, &lck); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -63,6 +64,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, { struct pvfs_filename *name; NTSTATUS status; + struct odb_lock *lck; /* get a pvfs_filename object */ status = pvfs_resolve_partial(pvfs, req, @@ -78,7 +80,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return status; } - status = pvfs_can_delete(pvfs, req, name); + status = pvfs_can_delete(pvfs, req, name, &lck); if (!NT_STATUS_IS_OK(status)) { talloc_free(name); return status; -- cgit From 4d3cc7384338fe2182a2029c2e6d2fcca2ec8813 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 28 Feb 2006 05:48:21 +0000 Subject: r13745: remove some code I was experimenting with and forgot was there when I committed that will teach me to run svn diff before committing .... (This used to be commit ef6e30c72cf610728584dfab1755b47bfc53f01c) --- source4/ntvfs/posix/pvfs_open.c | 349 ---------------------------------------- 1 file changed, 349 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a8c0bba97f..e24887ca96 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -182,354 +182,6 @@ static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, } -/* - create a new directory -*/ -static NTSTATUS pvfs_create_directory(struct pvfs_state *pvfs, - struct smbsrv_request *req, - struct pvfs_filename *name, - union smb_open *io) -{ - struct pvfs_file *f; - NTSTATUS status; - int fnum, ret; - struct odb_lock *lck; - uint32_t create_options = io->generic.in.create_options; - uint32_t share_access = io->generic.in.share_access; - uint32_t access_mask = io->generic.in.access_mask; - mode_t mode; - uint32_t attrib; - BOOL del_on_close; - - if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && - (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { - return NT_STATUS_CANNOT_DELETE; - } - - status = pvfs_access_check_create(pvfs, req, name, &access_mask); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - f = talloc(req, struct pvfs_file); - if (f == NULL) { - return NT_STATUS_NO_MEMORY; - } - - f->handle = talloc(f, struct pvfs_file_handle); - if (f->handle == NULL) { - return NT_STATUS_NO_MEMORY; - } - - fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_NEW_FNUM, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - - attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_DIRECTORY; - mode = pvfs_fileperms(pvfs, attrib); - - /* create the directory */ - ret = mkdir(name->full_name, mode); - if (ret == -1) { - idr_remove(pvfs->idtree_fnum, fnum); - return pvfs_map_errno(pvfs, errno); - } - - pvfs_xattr_unlink_hook(pvfs, name->full_name); - - /* re-resolve the new directory */ - status = pvfs_resolve_name_fd(pvfs, -1, name); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); - rmdir(name->full_name); - return status; - } - - name->dos.attrib = attrib; - - status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, fnum, io); - if (!NT_STATUS_IS_OK(status)) { - goto cleanup_delete; - } - - /* form the lock context used for opendb locking */ - status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); - if (!NT_STATUS_IS_OK(status)) { - goto cleanup_delete; - } - - /* grab a lock on the open file record */ - lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); - if (lck == NULL) { - DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", - name->full_name)); - /* we were supposed to do a blocking lock, so something - is badly wrong! */ - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto cleanup_delete; - } - - if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { - del_on_close = True; - } else { - del_on_close = False; - } - - status = odb_open_file(lck, f->handle, name->stream_id, - share_access, access_mask, del_on_close, name->full_name); - talloc_free(lck); - if (!NT_STATUS_IS_OK(status)) { - /* bad news, we must have hit a race */ - idr_remove(pvfs->idtree_fnum, fnum); - return status; - } - - f->fnum = fnum; - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; - f->pending_list = NULL; - f->lock_count = 0; - f->share_access = io->generic.in.share_access; - f->access_mask = access_mask; - f->impersonation = io->generic.in.impersonation; - - f->handle->pvfs = pvfs; - f->handle->name = talloc_steal(f->handle, name); - f->handle->fd = -1; - f->handle->create_options = io->generic.in.create_options; - f->handle->seek_offset = 0; - f->handle->position = 0; - f->handle->mode = 0; - f->handle->have_opendb_entry = True; - f->handle->sticky_write_time = False; - - DLIST_ADD(pvfs->open_files, f); - - /* setup a destructor to avoid file descriptor leaks on - abnormal termination */ - talloc_set_destructor(f, pvfs_dir_fnum_destructor); - talloc_set_destructor(f->handle, pvfs_dir_handle_destructor); - - io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.out.fnum = f->fnum; - io->generic.out.create_action = NTCREATEX_ACTION_CREATED; - io->generic.out.create_time = name->dos.create_time; - io->generic.out.access_time = name->dos.access_time; - io->generic.out.write_time = name->dos.write_time; - io->generic.out.change_time = name->dos.change_time; - io->generic.out.attrib = name->dos.attrib; - io->generic.out.alloc_size = name->dos.alloc_size; - io->generic.out.size = name->st.st_size; - io->generic.out.file_type = FILE_TYPE_DISK; - io->generic.out.ipc_state = 0; - io->generic.out.is_directory = 0; - - /* success - keep the file handle */ - talloc_steal(pvfs, f); - - return NT_STATUS_OK; - -cleanup_delete: - idr_remove(pvfs->idtree_fnum, fnum); - rmdir(name->full_name); - return status; -} - -#if 0 -/* - open a directory -*/ -static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, - struct smbsrv_request *req, - struct pvfs_filename *name, - union smb_open *io) -{ - struct pvfs_file *f; - NTSTATUS status; - int fnum; - struct odb_lock *lck; - uint32_t create_options; - uint32_t share_access; - uint32_t access_mask; - BOOL del_on_close; - - create_options = io->generic.in.create_options; - share_access = io->generic.in.share_access; - access_mask = io->generic.in.access_mask; - - /* certain create options are not allowed */ - if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - !(access_mask & SEC_STD_DELETE)) { - return NT_STATUS_INVALID_PARAMETER; - } - - switch (io->generic.in.open_disposition) { - case NTCREATEX_DISP_SUPERSEDE: - case NTCREATEX_DISP_OVERWRITE_IF: - case NTCREATEX_DISP_OPEN_IF: - break; - - case NTCREATEX_DISP_OPEN: - case NTCREATEX_DISP_OVERWRITE: - if (!name->exists) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - break; - - case NTCREATEX_DISP_CREATE: - if (name->exists) { - return NT_STATUS_OBJECT_NAME_COLLISION; - } - break; - - default: - return NT_STATUS_INVALID_PARAMETER; - } - - /* handle creating a new directory separately */ - if (!name->exists) { - status = pvfs_create_directory(pvfs, req, name, io); - if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { - return status; - } - - /* we've hit a race - the directory was created during this call */ - if (io->generic.in.open_disposition == NTCREATEX_DISP_CREATE) { - return status; - } - - /* try re-resolving the name */ - status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - /* fall through to a normal open */ - } - - if ((name->dos.attrib & FILE_ATTRIBUTE_READONLY) && - (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { - return NT_STATUS_CANNOT_DELETE; - } - - /* check the security descriptor */ - status = pvfs_access_check(pvfs, req, name, &access_mask); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - f = talloc(req, struct pvfs_file); - if (f == NULL) { - return NT_STATUS_NO_MEMORY; - } - - f->handle = talloc(f, struct pvfs_file_handle); - if (f->handle == NULL) { - return NT_STATUS_NO_MEMORY; - } - - /* allocate a fnum */ - fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - - f->fnum = fnum; - f->session = req->session; - f->smbpid = req->smbpid; - f->pvfs = pvfs; - f->pending_list = NULL; - f->lock_count = 0; - f->share_access = io->generic.in.share_access; - f->access_mask = access_mask; - f->impersonation = io->generic.in.impersonation; - - f->handle->pvfs = pvfs; - f->handle->fd = -1; - f->handle->name = talloc_steal(f->handle, name); - f->handle->create_options = io->generic.in.create_options; - f->handle->seek_offset = 0; - f->handle->position = 0; - f->handle->mode = 0; - f->handle->have_opendb_entry = False; - f->handle->sticky_write_time = False; - - /* form the lock context used for opendb locking */ - status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, f->fnum); - return status; - } - - /* get a lock on this file before the actual open */ - lck = odb_lock(req, pvfs->odb_context, &f->handle->odb_locking_key); - if (lck == NULL) { - DEBUG(0,("pvfs_open: failed to lock file '%s' in opendb\n", - name->full_name)); - /* we were supposed to do a blocking lock, so something - is badly wrong! */ - idr_remove(pvfs->idtree_fnum, fnum); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - DLIST_ADD(pvfs->open_files, f); - - /* setup a destructor to avoid file descriptor leaks on - abnormal termination */ - talloc_set_destructor(f, pvfs_dir_fnum_destructor); - talloc_set_destructor(f->handle, pvfs_dir_handle_destructor); - - if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - pvfs_directory_empty(pvfs, f->handle->name)) { - del_on_close = True; - } else { - del_on_close = False; - } - - /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, f->handle, f->handle->name->stream_id, - share_access, access_mask, del_on_close, name->full_name); - -#if 0 - /* we don't do async open retries on directories yet */ - if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) && - (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return pvfs_open_setup_retry(ntvfs, req, io, f, lck); - } -#endif - - if (!NT_STATUS_IS_OK(status)) { - talloc_free(lck); - return status; - } - - f->handle->have_opendb_entry = True; - - talloc_free(lck); - - io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.out.fnum = f->fnum; - io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; - io->generic.out.create_time = name->dos.create_time; - io->generic.out.access_time = name->dos.access_time; - io->generic.out.write_time = name->dos.write_time; - io->generic.out.change_time = name->dos.change_time; - io->generic.out.attrib = name->dos.attrib; - io->generic.out.alloc_size = name->dos.alloc_size; - io->generic.out.size = name->st.st_size; - io->generic.out.file_type = FILE_TYPE_DISK; - io->generic.out.ipc_state = 0; - io->generic.out.is_directory = 0; - - /* success - keep the file handle */ - talloc_steal(f->pvfs, f); - - return NT_STATUS_OK; -} -#endif - -#if 1 /* open a directory */ @@ -758,7 +410,6 @@ cleanup_delete: rmdir(name->full_name); return status; } -#endif /* destroy a struct pvfs_file_handle -- cgit From a7d5bc2dd3837ce98710d0475f16ec571202bab5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 3 Mar 2006 08:28:42 +0000 Subject: r13813: fix compiler warnings metze (This used to be commit f1471c6c6ca796b5852e940ba88563b2edc21167) --- source4/ntvfs/posix/xattr_tdb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index f488569ca5..cea50bb4fa 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -52,7 +52,7 @@ static NTSTATUS xattr_tdb_add_list(struct pvfs_state *pvfs, const char *attr_nam blob = data_blob(NULL, 0); } - for (s=blob.data; s < (char *)(blob.data+blob.length); s += strlen(s) + 1) { + for (s=(const char *)blob.data; s < (const char *)(blob.data+blob.length); s += strlen(s) + 1) { if (strcmp(attr_name, s) == 0) { talloc_free(mem_ctx); return NT_STATUS_OK; @@ -96,7 +96,7 @@ static NTSTATUS get_ea_db_key(TALLOC_CTX *mem_ctx, } } - key->dptr = talloc_array(mem_ctx, char, 16 + len); + key->dptr = talloc_array(mem_ctx, uint8_t, 16 + len); if (key->dptr == NULL) { return NT_STATUS_NO_MEMORY; } @@ -225,7 +225,7 @@ NTSTATUS unlink_xattr_tdb(struct pvfs_state *pvfs, const char *fname) return NT_STATUS_OK; } - for (s=blob.data; s < (char *)(blob.data+blob.length); s += strlen(s) + 1) { + for (s=(const char *)blob.data; s < (const char *)(blob.data+blob.length); s += strlen(s) + 1) { delete_xattr_tdb(pvfs, s, fname, -1); } -- cgit From 86dda205623926e83d28a20d0b4d87ea1ac11824 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 21:36:24 +0000 Subject: r13899: Get the shared library build building again. Just compiles for now, but modules don't work yet.. (Run LIBRARY_OUTPUT_TYPE=SHARED_LIBRARY MODULE_OUTPUT_TYPE=SHARED_LIBRARY ./config.status) (This used to be commit ba74f24e422eda0379615f2ab39bef1e1e025ce7) --- source4/ntvfs/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 8194fc1963..177ce5d77b 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -77,6 +77,7 @@ OBJ_FILES = \ common/brlock.o \ common/opendb.o \ common/sidmap.o +REQUIRED_SUBSYSTEMS = NDR_OPENDB # # End SUBSYSTEM NTVFS ################################################ -- cgit From ba564a901e519b0f2cf2b7651bd260f618506b5c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 6 Mar 2006 23:28:18 +0000 Subject: r13903: Don't generate prototypes for modules and binaries in include/proto.h by default. (This used to be commit c80a8f1102caf744b66c13bebde38fba74983dc4) --- source4/ntvfs/config.mk | 2 ++ source4/ntvfs/ipc/ipc_rap.c | 1 + source4/ntvfs/ipc/vfs_ipc.c | 1 + source4/ntvfs/simple/vfs_simple.c | 1 + 4 files changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 177ce5d77b..84ec59e028 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -19,6 +19,7 @@ REQUIRED_SUBSYSTEMS = \ [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = NTVFS +PRIVATE_PROTO_HEADER = simple/proto.h OBJ_FILES = \ simple/vfs_simple.o \ simple/svfs_util.o @@ -40,6 +41,7 @@ OBJ_FILES = \ [MODULE::ntvfs_ipc] SUBSYSTEM = NTVFS INIT_FUNCTION = ntvfs_ipc_init +PRIVATE_PROTO_HEADER = ipc/proto.h OBJ_FILES = \ ipc/vfs_ipc.o \ ipc/ipc_rap.o \ diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index f97ae4cd89..5656a96621 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/rap/rap.h" +#include "ntvfs/ipc/proto.h" #define NERR_Success 0 #define NERR_badpass 86 diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index dd7994c1fb..d5259bc9a6 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -29,6 +29,7 @@ #include "dlinklist.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" +#include "ntvfs/ipc/proto.h" #include "rpc_server/dcerpc_server.h" #define IPC_BASE_FNUM 0x400 diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index ad06a95041..ce14877277 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -34,6 +34,7 @@ #include "dlinklist.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" +#include "ntvfs/simple/proto.h" #ifndef O_DIRECTORY #define O_DIRECTORY 0 -- cgit From 45c92c9cf08210e1d5792e2d8db93912727c3dba Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 7 Mar 2006 11:02:47 +0000 Subject: r13923: make the state_flags per dcesrv_connection this will may help with a generic named pipe solution metze (This used to be commit c6fa9bd15cdb096c3dfc7a4109d9298933981255) --- source4/ntvfs/ipc/vfs_ipc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index d5259bc9a6..ea4955d84e 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -227,6 +227,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, ep_description, req->session->session_info, srv_conn, + 0, &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { idr_remove(private->idtree_fnum, p->fnum); -- cgit From 4ac2be99588b48b0652a524bf12fb1aa9c3f5fbb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 11:07:23 +0000 Subject: r13924: Split more prototypes out of include/proto.h + initial work on header file dependencies (This used to be commit 122835876748a3eaf5e8d31ad1abddab9acb8781) --- source4/ntvfs/common/sidmap.c | 2 ++ source4/ntvfs/ipc/rap_server.c | 1 + source4/ntvfs/posix/pvfs_acl.c | 1 + source4/ntvfs/posix/vfs_posix.c | 2 ++ 4 files changed, 6 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index e96d65e138..70f7dea955 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -26,6 +26,8 @@ #include "dsdb/samdb/samdb.h" #include "auth/auth.h" #include "libcli/ldap/ldap.h" +#include "db_wrap.h" +#include "libcli/security/proto.h" /* these are used for the fallback local uid/gid to sid mapping diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index b68f806ba1..9fa831dd4f 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/rap/rap.h" #include "librpc/gen_ndr/ndr_srvsvc.h" +#include "rpc_server/common/common.h" /* At this moment these are just dummy functions, but you might get the * idea. */ diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 33756bc8bc..a5cd919ba3 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -24,6 +24,7 @@ #include "auth/auth.h" #include "vfs_posix.h" #include "librpc/gen_ndr/ndr_xattr.h" +#include "libcli/security/proto.h" /* diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 3b52ff6237..e600be446a 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -29,6 +29,8 @@ #include "librpc/gen_ndr/ndr_security.h" #include "smbd/service_stream.h" #include "lib/tdb/include/tdb.h" +#include "db_wrap.h" +#include "libcli/security/proto.h" /* -- cgit From f8fdbc967c774a1d62f87a534e4990d83ecc6b67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 14:34:32 +0000 Subject: r13944: Yet another round of splitups. (This used to be commit f87debeb12cebd734b47314554ab671c9e06237e) --- source4/ntvfs/posix/pvfs_xattr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index e9cb077c06..d0894a735e 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "util/unix_privs.h" /* pull a xattr as a blob -- cgit From ceb6e9717bf8ea5c83a01e159a7006fd8651620c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 16:41:04 +0000 Subject: r13960: Generate makefile rules for installing/removing shared modules. (This used to be commit 2c746980328431ab04852dc668899e3eb042da99) --- source4/ntvfs/config.mk | 12 ++++++------ source4/ntvfs/posix/config.mk | 2 +- source4/ntvfs/unixuid/config.mk | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 84ec59e028..4ed2bcf7c3 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -6,7 +6,7 @@ include unixuid/config.mk # Start MODULE ntvfs_cifs [MODULE::ntvfs_cifs] INIT_FUNCTION = ntvfs_cifs_init -SUBSYSTEM = NTVFS +SUBSYSTEM = ntvfs OBJ_FILES = \ cifs/vfs_cifs.o REQUIRED_SUBSYSTEMS = \ @@ -18,7 +18,7 @@ REQUIRED_SUBSYSTEMS = \ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init -SUBSYSTEM = NTVFS +SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = simple/proto.h OBJ_FILES = \ simple/vfs_simple.o \ @@ -30,7 +30,7 @@ OBJ_FILES = \ # Start MODULE ntvfs_print [MODULE::ntvfs_print] INIT_FUNCTION = ntvfs_print_init -SUBSYSTEM = NTVFS +SUBSYSTEM = ntvfs OBJ_FILES = \ print/vfs_print.o # End MODULE ntvfs_print @@ -39,7 +39,7 @@ OBJ_FILES = \ ################################################ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] -SUBSYSTEM = NTVFS +SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_ipc_init PRIVATE_PROTO_HEADER = ipc/proto.h OBJ_FILES = \ @@ -54,7 +54,7 @@ OBJ_FILES = \ ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] -SUBSYSTEM = NTVFS +SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_nbench_init OBJ_FILES = \ nbench/vfs_nbench.o @@ -64,7 +64,7 @@ OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS -[LIBRARY::NTVFS] +[LIBRARY::ntvfs] PUBLIC_HEADERS = ntvfs.h MAJOR_VERSION = 0 MINOR_VERSION = 0 diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 85fcc10e06..ccf2c2d1a9 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,7 +1,7 @@ ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] -SUBSYSTEM = NTVFS +SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_posix_init PRIVATE_PROTO_HEADER = vfs_posix_proto.h OBJ_FILES = \ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index bb811bca2b..3fdeb79e3d 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -2,7 +2,7 @@ # Start MODULE ntvfs_unixuid [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init -SUBSYSTEM = NTVFS +SUBSYSTEM = ntvfs OBJ_FILES = \ vfs_unixuid.o # End MODULE ntvfs_unixuid -- cgit From 0fbcfd8920e8df3cfb4ba5ce2d1fcf48b38a4acf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 7 Mar 2006 17:53:28 +0000 Subject: r13969: Make these names lowercase as well (just like they are now in the buildsystem) (This used to be commit 04c49e211fc4f80e03d9322b983bbde15baba640) --- source4/ntvfs/ntvfs_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index cfd2c1f5de..1201bdefbe 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -163,7 +163,7 @@ NTSTATUS ntvfs_init_connection(struct smbsrv_request *req, enum ntvfs_type type) NTSTATUS ntvfs_init(void) { - init_module_fn static_init[] = STATIC_NTVFS_MODULES; + init_module_fn static_init[] = STATIC_ntvfs_MODULES; init_module_fn *shared_init = load_samba_modules(NULL, "ntvfs"); run_init_functions(static_init); -- cgit From 418befec187066f6f107f1cf986d29bf77ca498c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 8 Mar 2006 03:54:24 +0000 Subject: r14011: - added a ntvfs_notify op to allow backends to support change notify - converted the nttrans server side code to be async (needed for change notify) This is the start of some work on supporting change notify via a new approach. More soon. (This used to be commit 0ad70bfd83b4a03c0e67f11f63822b833be67aa1) --- source4/ntvfs/cifs/vfs_cifs.c | 31 +++++++++++++++++++++++++++++++ source4/ntvfs/ntvfs.h | 4 ++++ source4/ntvfs/ntvfs_interface.c | 13 +++++++++++++ 3 files changed, 48 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 138c9d566f..44d4d069e8 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -837,6 +837,36 @@ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } +/* + a handler for async change notify replies + */ +static void async_changenotify(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct smbsrv_request *req = async->req; + req->async_states->status = smb_raw_changenotify_recv(c_req, req, async->parms); + req->async_states->send_fn(req); +} + +/* change notify request - always async */ +static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_notify *info) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + /* this request doesn't make sense unless its async */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return NT_STATUS_INVALID_PARAMETER; + } + + c_req = smb_raw_changenotify_send(private->tree, info); + + ASYNC_RECV_TAIL(info, async_changenotify); +} + /* initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem */ @@ -882,6 +912,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.logoff = cvfs_logoff; ops.async_setup = cvfs_async_setup; ops.cancel = cvfs_cancel; + ops.notify = cvfs_notify; if (lp_parm_bool(-1, "cifs", "maptrans2", False)) { ops.trans2 = cvfs_trans2; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 4ec8926ebc..80f6e94125 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -121,6 +121,10 @@ struct ntvfs_ops { /* cancel - cancels any pending async request */ NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req); + + /* change notify request */ + NTSTATUS (*notify)(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_notify *info); }; struct ntvfs_module_context { diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 5a2415f5f9..be536d5eef 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -324,6 +324,19 @@ _PUBLIC_ NTSTATUS ntvfs_cancel(struct smbsrv_request *req) } +/* + change notify request +*/ +_PUBLIC_ NTSTATUS ntvfs_notify(struct smbsrv_request *req, struct smb_notify *info) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->notify) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->notify(ntvfs, req, info); +} + + /* initial setup */ _PUBLIC_ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *sharename) -- cgit From 91931f97e8a926ad812d5a353524e7d5c5dc8a04 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 8 Mar 2006 05:46:09 +0000 Subject: r14012: added support for the SMBntcancel operation in the cifs ntvfs backend. This requires keeping a list of outstanding requests so the MID can be matched. Use a talloc destructor to manage the list. (This used to be commit 6ec250f55d7b7d9c899d3c3777666a96bf8ea06c) --- source4/ntvfs/cifs/vfs_cifs.c | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 44d4d069e8..5bac39f3a7 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,19 +32,24 @@ #include "smbd/service_stream.h" #include "auth/auth.h" #include "ntvfs/ntvfs.h" +#include "include/dlinklist.h" /* this is stored in ntvfs_private */ struct cvfs_private { struct smbcli_tree *tree; struct smbcli_transport *transport; struct smbsrv_tcon *tcon; + struct async_info *pending; BOOL map_generic; }; /* a structure used to pass information to an async handler */ struct async_info { + struct async_info *next, *prev; + struct cvfs_private *cvfs; struct smbsrv_request *req; + struct smbcli_request *c_req; void *parms; }; @@ -93,11 +98,10 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, machine_account = lp_parm_bool(req->tcon->service, "cifs", "use_machine_account", False); - private = talloc(ntvfs, struct cvfs_private); + private = talloc_zero(ntvfs, struct cvfs_private); if (!private) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(private); ntvfs->private_data = private; @@ -183,6 +187,16 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + destroy an async info structure +*/ +static int async_info_destructor(void *p) +{ + struct async_info *async = talloc_get_type(p, struct async_info); + DLIST_REMOVE(async->cvfs->pending, async); + return 0; +} + /* a handler for simple async replies this handler can only be used for functions that don't return any @@ -206,7 +220,11 @@ static void async_simple(struct smbcli_request *c_req) if (!async) return NT_STATUS_NO_MEMORY; \ async->parms = io; \ async->req = req; \ + async->cvfs = private; \ + async->c_req = c_req; \ + DLIST_ADD(private->pending, async); \ c_req->async.private = async; \ + talloc_set_destructor(async, async_info_destructor); \ } \ c_req->async.fn = async_fn; \ req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ @@ -673,7 +691,21 @@ static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) { - return NT_STATUS_NOT_IMPLEMENTED; + struct cvfs_private *private = ntvfs->private_data; + + /* find the matching request */ + struct async_info *a; + for (a=private->pending;a;a=a->next) { + if (SVAL(a->req->in.hdr, HDR_MID) == SVAL(req->in.hdr, HDR_MID)) { + break; + } + } + + if (a == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return smb_raw_ntcancel(a->c_req); } /* -- cgit From 30b4212a1a1101fee3ee8c9fe8fdc989bf9dc2b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 8 Mar 2006 11:13:13 +0000 Subject: r14037: add ntvfs_next_notify() metze (This used to be commit d4c0f8900e908bc70fd66059fc667432329abf89) --- source4/ntvfs/ntvfs_interface.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index be536d5eef..a3a605c0c8 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -629,3 +629,15 @@ _PUBLIC_ NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, } return ntvfs->next->ops->cancel(ntvfs->next, req); } + +/* + change notify request +*/ +_PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, + struct smbsrv_request *req, struct smb_notify *info) +{ + if (!ntvfs->next || !ntvfs->next->ops->notify) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->notify(ntvfs, req, info); +} -- cgit From 86497db6113c4ec3210d671c3fcf957d1026098c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Mar 2006 14:31:17 +0000 Subject: r14157: - pass a struct ntvfs_request to the ntvfs layer (for now we just do #define ntvfs_request smbsrv_request, but it's the first step...) - rename ntvfs_openfile() -> ntvfs_open() - fix the talloc hierachie in some places in the ntvfs_map_*() code metze (This used to be commit ed9ed1f48f602354810937c0b0de850b44322191) --- source4/ntvfs/cifs/vfs_cifs.c | 101 +++++---- source4/ntvfs/ipc/ipc_rap.c | 29 ++- source4/ntvfs/ipc/rap_server.c | 20 +- source4/ntvfs/ipc/vfs_ipc.c | 79 ++++--- source4/ntvfs/nbench/vfs_nbench.c | 131 ++++++------ source4/ntvfs/ntvfs.h | 184 +++++++++------- source4/ntvfs/ntvfs_base.c | 23 +- source4/ntvfs/ntvfs_generic.c | 122 ++++++----- source4/ntvfs/ntvfs_interface.c | 373 ++++++++++++++++++--------------- source4/ntvfs/ntvfs_util.c | 8 +- source4/ntvfs/posix/pvfs_acl.c | 18 +- source4/ntvfs/posix/pvfs_flush.c | 2 +- source4/ntvfs/posix/pvfs_fsinfo.c | 2 +- source4/ntvfs/posix/pvfs_ioctl.c | 6 +- source4/ntvfs/posix/pvfs_lock.c | 12 +- source4/ntvfs/posix/pvfs_mkdir.c | 6 +- source4/ntvfs/posix/pvfs_open.c | 36 ++-- source4/ntvfs/posix/pvfs_qfileinfo.c | 6 +- source4/ntvfs/posix/pvfs_read.c | 4 +- source4/ntvfs/posix/pvfs_rename.c | 10 +- source4/ntvfs/posix/pvfs_search.c | 10 +- source4/ntvfs/posix/pvfs_seek.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 6 +- source4/ntvfs/posix/pvfs_unlink.c | 6 +- source4/ntvfs/posix/pvfs_wait.c | 14 +- source4/ntvfs/posix/pvfs_write.c | 4 +- source4/ntvfs/posix/vfs_posix.c | 15 +- source4/ntvfs/posix/vfs_posix.h | 10 - source4/ntvfs/print/vfs_print.c | 9 +- source4/ntvfs/simple/svfs_util.c | 6 +- source4/ntvfs/simple/vfs_simple.c | 79 ++++--- source4/ntvfs/unixuid/vfs_unixuid.c | 73 ++++--- 32 files changed, 726 insertions(+), 680 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 5bac39f3a7..f6a8da14e7 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -48,7 +48,7 @@ struct cvfs_private { struct async_info { struct async_info *next, *prev; struct cvfs_private *cvfs; - struct smbsrv_request *req; + struct ntvfs_request *req; struct smbcli_request *c_req; void *parms; }; @@ -71,7 +71,7 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; NTSTATUS status; @@ -176,8 +176,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) { struct cvfs_private *private = ntvfs->private_data; @@ -205,7 +204,7 @@ static int async_info_destructor(void *p) static void async_simple(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smbcli_request_simple_recv(c_req); req->async_states->send_fn(req); } @@ -238,7 +237,7 @@ static void async_simple(struct smbcli_request *c_req) The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, struct smb_unlink *unl) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -262,7 +261,7 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, static void async_ioctl(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); req->async_states->send_fn(req); } @@ -271,7 +270,7 @@ static void async_ioctl(struct smbcli_request *c_req) ioctl interface */ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -293,7 +292,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, struct smb_chkpath *cp) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -315,7 +314,7 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, static void async_qpathinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); req->async_states->send_fn(req); } @@ -324,7 +323,7 @@ static void async_qpathinfo(struct smbcli_request *c_req) return info on a pathname */ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -346,7 +345,7 @@ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, static void async_qfileinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); req->async_states->send_fn(req); } @@ -355,7 +354,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) query info on a open file */ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -376,7 +375,7 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, set info on a pathname */ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) + struct ntvfs_request *req, union smb_setfileinfo *st) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -399,7 +398,7 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, static void async_open(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_open_recv(c_req, req, async->parms); req->async_states->send_fn(req); } @@ -408,7 +407,7 @@ static void async_open(struct smbcli_request *c_req) open a file */ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) + struct ntvfs_request *req, union smb_open *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -417,7 +416,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, if (io->generic.level != RAW_OPEN_GENERIC && private->map_generic) { - return ntvfs_map_open(req, io, ntvfs); + return ntvfs_map_open(ntvfs, req, io); } if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -433,7 +432,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, create a directory */ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -453,7 +452,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, remove a directory */ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, struct smb_rmdir *rd) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -472,7 +471,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, rename a set of files */ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -492,7 +491,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, copy a set of files */ static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) + struct ntvfs_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -503,7 +502,7 @@ static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, static void async_read(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_read_recv(c_req, async->parms); req->async_states->send_fn(req); } @@ -512,7 +511,7 @@ static void async_read(struct smbcli_request *c_req) read from a file */ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) + struct ntvfs_request *req, union smb_read *rd) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -521,7 +520,7 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, if (rd->generic.level != RAW_READ_GENERIC && private->map_generic) { - return ntvfs_map_read(req, rd, ntvfs); + return ntvfs_map_read(ntvfs, req, rd); } if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -539,7 +538,7 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, static void async_write(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_write_recv(c_req, async->parms); req->async_states->send_fn(req); } @@ -548,7 +547,7 @@ static void async_write(struct smbcli_request *c_req) write to a file */ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) + struct ntvfs_request *req, union smb_write *wr) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -557,7 +556,7 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, if (wr->generic.level != RAW_WRITE_GENERIC && private->map_generic) { - return ntvfs_map_write(req, wr, ntvfs); + return ntvfs_map_write(ntvfs, req, wr); } if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -575,7 +574,7 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, static void async_seek(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_seek_recv(c_req, async->parms); req->async_states->send_fn(req); } @@ -584,7 +583,7 @@ static void async_seek(struct smbcli_request *c_req) seek in a file */ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct ntvfs_request *req, struct smb_seek *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -604,7 +603,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) + struct ntvfs_request *req, struct smb_flush *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -624,7 +623,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, close a file */ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) + struct ntvfs_request *req, union smb_close *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -633,7 +632,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, if (io->generic.level != RAW_CLOSE_GENERIC && private->map_generic) { - return ntvfs_map_close(req, io, ntvfs); + return ntvfs_map_close(ntvfs, req, io); } if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -649,7 +648,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, exit - closing files open by the pid */ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -669,7 +668,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, logoff - closing files open by the user */ static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { /* we can't do this right in the cifs backend .... */ return NT_STATUS_OK; @@ -679,7 +678,7 @@ static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs, setup for an async call - nothing to do yet */ static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, void *private) { return NT_STATUS_OK; @@ -689,7 +688,7 @@ static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, cancel an async call */ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { struct cvfs_private *private = ntvfs->private_data; @@ -712,7 +711,7 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, lock a byte range */ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) + struct ntvfs_request *req, union smb_lock *lck) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -721,7 +720,7 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, if (lck->generic.level != RAW_LOCK_GENERIC && private->map_generic) { - return ntvfs_map_lock(req, lck, ntvfs); + return ntvfs_map_lock(ntvfs, req, lck); } if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -736,7 +735,7 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, set info on a open file */ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, union smb_setfileinfo *info) { struct cvfs_private *private = ntvfs->private_data; @@ -759,7 +758,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, static void async_fsinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); req->async_states->send_fn(req); } @@ -768,7 +767,7 @@ static void async_fsinfo(struct smbcli_request *c_req) return filesystem space info */ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) + struct ntvfs_request *req, union smb_fsinfo *fs) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -788,7 +787,7 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, return print queue info */ static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) + struct ntvfs_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -797,7 +796,7 @@ static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, list files in a directory matching a wildcard pattern */ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, + struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -810,7 +809,7 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, /* continue a search */ static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, + struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -823,7 +822,7 @@ static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, /* close a search */ static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) + struct ntvfs_request *req, union smb_search_close *io) { struct cvfs_private *private = ntvfs->private_data; @@ -838,14 +837,14 @@ static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, static void async_trans2(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); req->async_states->send_fn(req); } /* raw trans2 */ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, struct smb_trans2 *trans2) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -864,7 +863,7 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, /* SMBtrans - not used on file shares */ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } @@ -875,14 +874,14 @@ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, static void async_changenotify(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; - struct smbsrv_request *req = async->req; + struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_changenotify_recv(c_req, req, async->parms); req->async_states->send_fn(req); } /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_notify *info) + struct ntvfs_request *req, struct smb_notify *info) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -920,7 +919,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.chkpath = cvfs_chkpath; ops.qpathinfo = cvfs_qpathinfo; ops.setpathinfo = cvfs_setpathinfo; - ops.openfile = cvfs_open; + ops.open = cvfs_open; ops.mkdir = cvfs_mkdir; ops.rmdir = cvfs_rmdir; ops.rename = cvfs_rename; diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 5656a96621..bc9bc6f31e 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -201,8 +201,7 @@ static NTSTATUS rap_push_string(struct ndr_push *data_push, goto done; \ } while (0) -static NTSTATUS _rap_netshareenum(struct smbsrv_request *req, - struct rap_call *call) +static NTSTATUS _rap_netshareenum(struct rap_call *call) { struct rap_NetShareEnum r; NTSTATUS result; @@ -225,7 +224,7 @@ static NTSTATUS _rap_netshareenum(struct smbsrv_request *req, break; } - result = rap_netshareenum(req, &r); + result = rap_netshareenum(call, &r); if (!NT_STATUS_IS_OK(result)) return result; @@ -282,8 +281,7 @@ static NTSTATUS _rap_netshareenum(struct smbsrv_request *req, return result; } -static NTSTATUS _rap_netserverenum2(struct smbsrv_request *req, - struct rap_call *call) +static NTSTATUS _rap_netserverenum2(struct rap_call *call) { struct rap_NetServerEnum2 r; NTSTATUS result; @@ -308,7 +306,7 @@ static NTSTATUS _rap_netserverenum2(struct smbsrv_request *req, break; } - result = rap_netserverenum2(req, &r); + result = rap_netserverenum2(call, &r); if (!NT_STATUS_IS_OK(result)) return result; @@ -367,8 +365,7 @@ static NTSTATUS _rap_netserverenum2(struct smbsrv_request *req, return result; } -static NTSTATUS api_Unsupported(struct smbsrv_request *req, - struct rap_call *call) +static NTSTATUS api_Unsupported(struct rap_call *call) { call->status = NERR_notsupported; call->convert = 0; @@ -379,14 +376,14 @@ static const struct { const char *name; int id; - NTSTATUS (*fn)(struct smbsrv_request *req, struct rap_call *call); + NTSTATUS (*fn)(struct rap_call *call); } api_commands[] = { {"NetShareEnum", RAP_WshareEnum, _rap_netshareenum }, {"NetServerEnum2", RAP_NetServerEnum2, _rap_netserverenum2 }, {NULL, -1, api_Unsupported} }; -NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) +NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) { int i; NTSTATUS result; @@ -395,7 +392,7 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) struct ndr_push *final_param; struct ndr_push *final_data; - call = new_rap_srv_call(req, trans); + call = new_rap_srv_call(mem_ctx, trans); if (call == NULL) return NT_STATUS_NO_MEMORY; @@ -406,8 +403,8 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, &call->datadesc)); - call->ndr_push_param = ndr_push_init_ctx(req); - call->ndr_push_data = ndr_push_init_ctx(req); + call->ndr_push_param = ndr_push_init_ctx(call); + call->ndr_push_data = ndr_push_init_ctx(call); if ((call->ndr_push_param == NULL) || (call->ndr_push_data == NULL)) return NT_STATUS_NO_MEMORY; @@ -421,7 +418,7 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) if (api_commands[i].id == call->callno) { DEBUG(5, ("Running RAP call %s\n", api_commands[i].name)); - result = api_commands[i].fn(req, call); + result = api_commands[i].fn(call); break; } } @@ -432,8 +429,8 @@ NTSTATUS ipc_rap_call(struct smbsrv_request *req, struct smb_trans2 *trans) result_param = ndr_push_blob(call->ndr_push_param); result_data = ndr_push_blob(call->ndr_push_data); - final_param = ndr_push_init_ctx(req); - final_data = ndr_push_init_ctx(req); + final_param = ndr_push_init_ctx(call); + final_data = ndr_push_init_ctx(call); if ((final_param == NULL) || (final_data == NULL)) return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 9fa831dd4f..a593999693 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -27,30 +27,30 @@ /* At this moment these are just dummy functions, but you might get the * idea. */ -NTSTATUS rap_netshareenum(struct smbsrv_request *req, +NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, struct rap_NetShareEnum *r) { int i; r->out.status = 0; - r->out.available = dcesrv_common_get_count_of_shares(req, NULL); - r->out.info = talloc_array(req, - union rap_shareenum_info, r->out.available); + r->out.available = dcesrv_common_get_count_of_shares(mem_ctx, NULL); + r->out.info = talloc_array(mem_ctx, + union rap_shareenum_info, r->out.available); for (i=0;iout.available;i++) { strncpy(r->out.info[i].info1.name, - dcesrv_common_get_share_name(req, NULL, i), + dcesrv_common_get_share_name(mem_ctx, NULL, i), sizeof(r->out.info[0].info1.name)); r->out.info[i].info1.pad = 0; - r->out.info[i].info1.type = dcesrv_common_get_share_type(req, NULL, i); - r->out.info[i].info1.comment = talloc_strdup(req, - dcesrv_common_get_share_comment(req, NULL, i)); + r->out.info[i].info1.type = dcesrv_common_get_share_type(mem_ctx, NULL, i); + r->out.info[i].info1.comment = talloc_strdup(mem_ctx, + dcesrv_common_get_share_comment(mem_ctx, NULL, i)); } return NT_STATUS_OK; } -NTSTATUS rap_netserverenum2(struct smbsrv_request *req, - struct rap_NetServerEnum2 *r) +NTSTATUS rap_netserverenum2(TALLOC_CTX *mem_ctx, + struct rap_NetServerEnum2 *r) { r->out.status = 0; r->out.available = 0; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index ea4955d84e..36f0c9b82c 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -75,7 +75,7 @@ static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t connect to a share - always works */ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { NTSTATUS status; struct smbsrv_tcon *tcon = req->tcon; @@ -108,8 +108,7 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS ipc_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +static NTSTATUS ipc_disconnect(struct ntvfs_module_context *ntvfs) { return NT_STATUS_OK; } @@ -118,7 +117,7 @@ static NTSTATUS ipc_disconnect(struct ntvfs_module_context *ntvfs, delete a file */ static NTSTATUS ipc_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, struct smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } @@ -128,7 +127,7 @@ static NTSTATUS ipc_unlink(struct ntvfs_module_context *ntvfs, ioctl interface - we don't do any */ static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { return NT_STATUS_ACCESS_DENIED; } @@ -137,7 +136,7 @@ static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS ipc_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, struct smb_chkpath *cp) { return NT_STATUS_ACCESS_DENIED; } @@ -146,7 +145,7 @@ static NTSTATUS ipc_chkpath(struct ntvfs_module_context *ntvfs, return info on a pathname */ static NTSTATUS ipc_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -155,7 +154,7 @@ static NTSTATUS ipc_qpathinfo(struct ntvfs_module_context *ntvfs, set info on a pathname */ static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) + struct ntvfs_request *req, union smb_setfileinfo *st) { return NT_STATUS_ACCESS_DENIED; } @@ -177,7 +176,7 @@ static int ipc_fd_destructor(void *ptr) open a file backend - used for MSRPC pipes */ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *fname, + struct ntvfs_request *req, const char *fname, struct pipe_state **ps) { struct pipe_state *p; @@ -253,7 +252,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, open a file with ntcreatex - used for MSRPC pipes */ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *oi) + struct ntvfs_request *req, union smb_open *oi) { struct pipe_state *p; NTSTATUS status; @@ -275,7 +274,7 @@ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs, open a file with openx - used for MSRPC pipes */ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *oi) + struct ntvfs_request *req, union smb_open *oi) { struct pipe_state *p; NTSTATUS status; @@ -298,7 +297,7 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, open a file - used for MSRPC pipes */ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *oi) + struct ntvfs_request *req, union smb_open *oi) { NTSTATUS status; @@ -321,7 +320,7 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs, create a directory */ static NTSTATUS ipc_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { return NT_STATUS_ACCESS_DENIED; } @@ -330,7 +329,7 @@ static NTSTATUS ipc_mkdir(struct ntvfs_module_context *ntvfs, remove a directory */ static NTSTATUS ipc_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, struct smb_rmdir *rd) { return NT_STATUS_ACCESS_DENIED; } @@ -339,7 +338,7 @@ static NTSTATUS ipc_rmdir(struct ntvfs_module_context *ntvfs, rename a set of files */ static NTSTATUS ipc_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { return NT_STATUS_ACCESS_DENIED; } @@ -348,7 +347,7 @@ static NTSTATUS ipc_rename(struct ntvfs_module_context *ntvfs, copy a set of files */ static NTSTATUS ipc_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) + struct ntvfs_request *req, struct smb_copy *cp) { return NT_STATUS_ACCESS_DENIED; } @@ -369,7 +368,7 @@ static NTSTATUS ipc_readx_dcesrv_output(void *private_data, DATA_BLOB *out, size read from a file */ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) + struct ntvfs_request *req, union smb_read *rd) { struct ipc_private *private = ntvfs->private_data; DATA_BLOB data; @@ -378,7 +377,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, NTSTATUS status = NT_STATUS_OK; if (rd->generic.level != RAW_READ_GENERIC) { - return ntvfs_map_read(req, rd, ntvfs); + return ntvfs_map_read(ntvfs, req, rd); } fnum = rd->readx.in.fnum; @@ -412,7 +411,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, write to a file */ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) + struct ntvfs_request *req, union smb_write *wr) { struct ipc_private *private = ntvfs->private_data; DATA_BLOB data; @@ -421,7 +420,7 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (wr->generic.level != RAW_WRITE_GENERIC) { - return ntvfs_map_write(req, wr, ntvfs); + return ntvfs_map_write(ntvfs, req, wr); } fnum = wr->writex.in.fnum; @@ -448,7 +447,7 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, seek in a file */ static NTSTATUS ipc_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct ntvfs_request *req, struct smb_seek *io) { return NT_STATUS_ACCESS_DENIED; } @@ -457,7 +456,7 @@ static NTSTATUS ipc_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS ipc_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) + struct ntvfs_request *req, struct smb_flush *io) { return NT_STATUS_ACCESS_DENIED; } @@ -466,13 +465,13 @@ static NTSTATUS ipc_flush(struct ntvfs_module_context *ntvfs, close a file */ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) + struct ntvfs_request *req, union smb_close *io) { struct ipc_private *private = ntvfs->private_data; struct pipe_state *p; if (io->generic.level != RAW_CLOSE_CLOSE) { - return ntvfs_map_close(req, io, ntvfs); + return ntvfs_map_close(ntvfs, req, io); } p = pipe_state_find(private, io->close.in.fnum); @@ -489,7 +488,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, exit - closing files */ static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { struct ipc_private *private = ntvfs->private_data; struct pipe_state *p, *next; @@ -508,7 +507,7 @@ static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs, logoff - closing files open by the user */ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { struct ipc_private *private = ntvfs->private_data; struct pipe_state *p, *next; @@ -527,7 +526,7 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, setup for an async call */ static NTSTATUS ipc_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, void *private) { return NT_STATUS_OK; @@ -537,7 +536,7 @@ static NTSTATUS ipc_async_setup(struct ntvfs_module_context *ntvfs, cancel an async call */ static NTSTATUS ipc_cancel(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { return NT_STATUS_UNSUCCESSFUL; } @@ -546,7 +545,7 @@ static NTSTATUS ipc_cancel(struct ntvfs_module_context *ntvfs, lock a byte range */ static NTSTATUS ipc_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) + struct ntvfs_request *req, union smb_lock *lck) { return NT_STATUS_ACCESS_DENIED; } @@ -555,7 +554,7 @@ static NTSTATUS ipc_lock(struct ntvfs_module_context *ntvfs, set info on a open file */ static NTSTATUS ipc_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *info) + struct ntvfs_request *req, union smb_setfileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -564,7 +563,7 @@ static NTSTATUS ipc_setfileinfo(struct ntvfs_module_context *ntvfs, query info on a open file */ static NTSTATUS ipc_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { return NT_STATUS_ACCESS_DENIED; } @@ -574,7 +573,7 @@ static NTSTATUS ipc_qfileinfo(struct ntvfs_module_context *ntvfs, return filesystem info */ static NTSTATUS ipc_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) + struct ntvfs_request *req, union smb_fsinfo *fs) { return NT_STATUS_ACCESS_DENIED; } @@ -583,7 +582,7 @@ static NTSTATUS ipc_fsinfo(struct ntvfs_module_context *ntvfs, return print queue info */ static NTSTATUS ipc_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) + struct ntvfs_request *req, union smb_lpq *lpq) { return NT_STATUS_ACCESS_DENIED; } @@ -592,7 +591,7 @@ static NTSTATUS ipc_lpq(struct ntvfs_module_context *ntvfs, list files in a directory matching a wildcard pattern */ static NTSTATUS ipc_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, + struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -603,7 +602,7 @@ static NTSTATUS ipc_search_first(struct ntvfs_module_context *ntvfs, continue listing files in a directory */ static NTSTATUS ipc_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, + struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -614,7 +613,7 @@ static NTSTATUS ipc_search_next(struct ntvfs_module_context *ntvfs, end listing files in a directory */ static NTSTATUS ipc_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) + struct ntvfs_request *req, union smb_search_close *io) { return NT_STATUS_ACCESS_DENIED; } @@ -638,7 +637,7 @@ static NTSTATUS ipc_trans_dcesrv_output(void *private_data, DATA_BLOB *out, size /* SMBtrans - handle a DCERPC command */ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans) + struct ntvfs_request *req, struct smb_trans2 *trans) { struct pipe_state *p; struct ipc_private *private = ntvfs->private_data; @@ -684,7 +683,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, /* SMBtrans - set named pipe state */ static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans) + struct ntvfs_request *req, struct smb_trans2 *trans) { struct ipc_private *private = ntvfs->private_data; struct pipe_state *p; @@ -711,7 +710,7 @@ static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, /* SMBtrans - used to provide access to SMB pipes */ static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans) + struct ntvfs_request *req, struct smb_trans2 *trans) { NTSTATUS status; @@ -760,7 +759,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.chkpath = ipc_chkpath; ops.qpathinfo = ipc_qpathinfo; ops.setpathinfo = ipc_setpathinfo; - ops.openfile = ipc_open; + ops.open = ipc_open; ops.mkdir = ipc_mkdir; ops.rmdir = ipc_rmdir; ops.rename = ipc_rename; diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index e88adbafcc..9647666360 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -37,10 +37,10 @@ struct nbench_private { /* log one request to the nbench log */ -static void nbench_log(struct smbsrv_request *req, +static void nbench_log(struct ntvfs_request *req, const char *format, ...) PRINTF_ATTRIBUTE(2, 3); -static void nbench_log(struct smbsrv_request *req, +static void nbench_log(struct ntvfs_request *req, const char *format, ...) { struct nbench_private *private = req->async_states->ntvfs->private_data; @@ -63,7 +63,7 @@ static void nbench_log(struct smbsrv_request *req, status code and any result parameters much harder. */ #define PASS_THRU_REQ_PRE_ASYNC(ntvfs, req, op, par1) do { \ - status = ntvfs_async_state_push(req, par1, nbench_##op##_send, ntvfs); \ + status = ntvfs_async_state_push(ntvfs, req, par1, nbench_##op##_send); \ if (!NT_STATUS_IS_OK(status)) { \ return status; \ } \ @@ -93,7 +93,7 @@ static void nbench_log(struct smbsrv_request *req, connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { struct nbench_private *nprivates; NTSTATUS status; @@ -123,15 +123,14 @@ static NTSTATUS nbench_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs) { struct nbench_private *nprivates = ntvfs->private_data; NTSTATUS status; close(nprivates->log_fd); - status = ntvfs_next_disconnect(ntvfs, tcon); + status = ntvfs_next_disconnect(ntvfs); return status; } @@ -140,7 +139,7 @@ static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs, delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static void nbench_unlink_send(struct smbsrv_request *req) +static void nbench_unlink_send(struct ntvfs_request *req) { struct smb_unlink *unl = req->async_states->private_data; @@ -152,7 +151,7 @@ static void nbench_unlink_send(struct smbsrv_request *req) } static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, struct smb_unlink *unl) { NTSTATUS status; @@ -164,7 +163,7 @@ static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, /* ioctl interface */ -static void nbench_ioctl_send(struct smbsrv_request *req) +static void nbench_ioctl_send(struct ntvfs_request *req) { nbench_log(req, "Ioctl - NOT HANDLED\n"); @@ -172,7 +171,7 @@ static void nbench_ioctl_send(struct smbsrv_request *req) } static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { NTSTATUS status; @@ -184,7 +183,7 @@ static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, /* check if a directory exists */ -static void nbench_chkpath_send(struct smbsrv_request *req) +static void nbench_chkpath_send(struct ntvfs_request *req) { struct smb_chkpath *cp = req->async_states->private_data; @@ -196,7 +195,7 @@ static void nbench_chkpath_send(struct smbsrv_request *req) } static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, struct smb_chkpath *cp) { NTSTATUS status; @@ -208,7 +207,7 @@ static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, /* return info on a pathname */ -static void nbench_qpathinfo_send(struct smbsrv_request *req) +static void nbench_qpathinfo_send(struct ntvfs_request *req) { union smb_fileinfo *info = req->async_states->private_data; @@ -221,7 +220,7 @@ static void nbench_qpathinfo_send(struct smbsrv_request *req) } static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { NTSTATUS status; @@ -233,7 +232,7 @@ static NTSTATUS nbench_qpathinfo(struct ntvfs_module_context *ntvfs, /* query info on a open file */ -static void nbench_qfileinfo_send(struct smbsrv_request *req) +static void nbench_qfileinfo_send(struct ntvfs_request *req) { union smb_fileinfo *info = req->async_states->private_data; @@ -246,7 +245,7 @@ static void nbench_qfileinfo_send(struct smbsrv_request *req) } static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { NTSTATUS status; @@ -258,7 +257,7 @@ static NTSTATUS nbench_qfileinfo(struct ntvfs_module_context *ntvfs, /* set info on a pathname */ -static void nbench_setpathinfo_send(struct smbsrv_request *req) +static void nbench_setpathinfo_send(struct ntvfs_request *req) { union smb_setfileinfo *st = req->async_states->private_data; @@ -271,7 +270,7 @@ static void nbench_setpathinfo_send(struct smbsrv_request *req) } static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) + struct ntvfs_request *req, union smb_setfileinfo *st) { NTSTATUS status; @@ -283,7 +282,7 @@ static NTSTATUS nbench_setpathinfo(struct ntvfs_module_context *ntvfs, /* open a file */ -static void nbench_openfile_send(struct smbsrv_request *req) +static void nbench_open_send(struct ntvfs_request *req) { union smb_open *io = req->async_states->private_data; @@ -309,12 +308,12 @@ static void nbench_openfile_send(struct smbsrv_request *req) PASS_THRU_REP_POST(req); } -static NTSTATUS nbench_openfile(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) +static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, openfile, io, (ntvfs, req, io)); + PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io)); return status; } @@ -322,7 +321,7 @@ static NTSTATUS nbench_openfile(struct ntvfs_module_context *ntvfs, /* create a directory */ -static void nbench_mkdir_send(struct smbsrv_request *req) +static void nbench_mkdir_send(struct ntvfs_request *req) { nbench_log(req, "Mkdir - NOT HANDLED\n"); @@ -330,7 +329,7 @@ static void nbench_mkdir_send(struct smbsrv_request *req) } static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { NTSTATUS status; @@ -342,7 +341,7 @@ static NTSTATUS nbench_mkdir(struct ntvfs_module_context *ntvfs, /* remove a directory */ -static void nbench_rmdir_send(struct smbsrv_request *req) +static void nbench_rmdir_send(struct ntvfs_request *req) { struct smb_rmdir *rd = req->async_states->private_data; @@ -354,7 +353,7 @@ static void nbench_rmdir_send(struct smbsrv_request *req) } static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, struct smb_rmdir *rd) { NTSTATUS status; @@ -366,7 +365,7 @@ static NTSTATUS nbench_rmdir(struct ntvfs_module_context *ntvfs, /* rename a set of files */ -static void nbench_rename_send(struct smbsrv_request *req) +static void nbench_rename_send(struct ntvfs_request *req) { union smb_rename *ren = req->async_states->private_data; @@ -388,7 +387,7 @@ static void nbench_rename_send(struct smbsrv_request *req) } static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { NTSTATUS status; @@ -400,7 +399,7 @@ static NTSTATUS nbench_rename(struct ntvfs_module_context *ntvfs, /* copy a set of files */ -static void nbench_copy_send(struct smbsrv_request *req) +static void nbench_copy_send(struct ntvfs_request *req) { nbench_log(req, "Copy - NOT HANDLED\n"); @@ -408,7 +407,7 @@ static void nbench_copy_send(struct smbsrv_request *req) } static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) + struct ntvfs_request *req, struct smb_copy *cp) { NTSTATUS status; @@ -420,7 +419,7 @@ static NTSTATUS nbench_copy(struct ntvfs_module_context *ntvfs, /* read from a file */ -static void nbench_read_send(struct smbsrv_request *req) +static void nbench_read_send(struct ntvfs_request *req) { union smb_read *rd = req->async_states->private_data; @@ -446,7 +445,7 @@ static void nbench_read_send(struct smbsrv_request *req) } static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) + struct ntvfs_request *req, union smb_read *rd) { NTSTATUS status; @@ -458,7 +457,7 @@ static NTSTATUS nbench_read(struct ntvfs_module_context *ntvfs, /* write to a file */ -static void nbench_write_send(struct smbsrv_request *req) +static void nbench_write_send(struct ntvfs_request *req) { union smb_write *wr = req->async_states->private_data; @@ -497,7 +496,7 @@ static void nbench_write_send(struct smbsrv_request *req) } static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) + struct ntvfs_request *req, union smb_write *wr) { NTSTATUS status; @@ -509,7 +508,7 @@ static NTSTATUS nbench_write(struct ntvfs_module_context *ntvfs, /* seek in a file */ -static void nbench_seek_send(struct smbsrv_request *req) +static void nbench_seek_send(struct ntvfs_request *req) { nbench_log(req, "Seek - NOT HANDLED\n"); @@ -517,7 +516,7 @@ static void nbench_seek_send(struct smbsrv_request *req) } static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct ntvfs_request *req, struct smb_seek *io) { NTSTATUS status; @@ -529,7 +528,7 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, /* flush a file */ -static void nbench_flush_send(struct smbsrv_request *req) +static void nbench_flush_send(struct ntvfs_request *req) { struct smb_flush *io = req->async_states->private_data; @@ -541,7 +540,7 @@ static void nbench_flush_send(struct smbsrv_request *req) } static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) + struct ntvfs_request *req, struct smb_flush *io) { NTSTATUS status; @@ -553,7 +552,7 @@ static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, /* close a file */ -static void nbench_close_send(struct smbsrv_request *req) +static void nbench_close_send(struct ntvfs_request *req) { union smb_close *io = req->async_states->private_data; @@ -574,7 +573,7 @@ static void nbench_close_send(struct smbsrv_request *req) } static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) + struct ntvfs_request *req, union smb_close *io) { NTSTATUS status; @@ -586,7 +585,7 @@ static NTSTATUS nbench_close(struct ntvfs_module_context *ntvfs, /* exit - closing files */ -static void nbench_exit_send(struct smbsrv_request *req) +static void nbench_exit_send(struct ntvfs_request *req) { nbench_log(req, "Exit - NOT HANDLED\n"); @@ -594,7 +593,7 @@ static void nbench_exit_send(struct smbsrv_request *req) } static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { NTSTATUS status; @@ -606,7 +605,7 @@ static NTSTATUS nbench_exit(struct ntvfs_module_context *ntvfs, /* logoff - closing files */ -static void nbench_logoff_send(struct smbsrv_request *req) +static void nbench_logoff_send(struct ntvfs_request *req) { nbench_log(req, "Logoff - NOT HANDLED\n"); @@ -614,7 +613,7 @@ static void nbench_logoff_send(struct smbsrv_request *req) } static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { NTSTATUS status; @@ -626,7 +625,7 @@ static NTSTATUS nbench_logoff(struct ntvfs_module_context *ntvfs, /* async_setup - send fn */ -static void nbench_async_setup_send(struct smbsrv_request *req) +static void nbench_async_setup_send(struct ntvfs_request *req) { PASS_THRU_REP_POST(req); } @@ -635,7 +634,7 @@ static void nbench_async_setup_send(struct smbsrv_request *req) async setup */ static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, void *private) { NTSTATUS status; @@ -646,7 +645,7 @@ static NTSTATUS nbench_async_setup(struct ntvfs_module_context *ntvfs, } -static void nbench_cancel_send(struct smbsrv_request *req) +static void nbench_cancel_send(struct ntvfs_request *req) { PASS_THRU_REP_POST(req); } @@ -655,7 +654,7 @@ static void nbench_cancel_send(struct smbsrv_request *req) cancel an existing async request */ static NTSTATUS nbench_cancel(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { NTSTATUS status; @@ -667,7 +666,7 @@ static NTSTATUS nbench_cancel(struct ntvfs_module_context *ntvfs, /* lock a byte range */ -static void nbench_lock_send(struct smbsrv_request *req) +static void nbench_lock_send(struct ntvfs_request *req) { union smb_lock *lck = req->async_states->private_data; @@ -694,7 +693,7 @@ static void nbench_lock_send(struct smbsrv_request *req) } static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) + struct ntvfs_request *req, union smb_lock *lck) { NTSTATUS status; @@ -706,7 +705,7 @@ static NTSTATUS nbench_lock(struct ntvfs_module_context *ntvfs, /* set info on a open file */ -static void nbench_setfileinfo_send(struct smbsrv_request *req) +static void nbench_setfileinfo_send(struct ntvfs_request *req) { union smb_setfileinfo *info = req->async_states->private_data; @@ -719,7 +718,7 @@ static void nbench_setfileinfo_send(struct smbsrv_request *req) } static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, union smb_setfileinfo *info) { NTSTATUS status; @@ -732,7 +731,7 @@ static NTSTATUS nbench_setfileinfo(struct ntvfs_module_context *ntvfs, /* return filesystem space info */ -static void nbench_fsinfo_send(struct smbsrv_request *req) +static void nbench_fsinfo_send(struct ntvfs_request *req) { union smb_fsinfo *fs = req->async_states->private_data; @@ -744,7 +743,7 @@ static void nbench_fsinfo_send(struct smbsrv_request *req) } static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) + struct ntvfs_request *req, union smb_fsinfo *fs) { NTSTATUS status; @@ -756,7 +755,7 @@ static NTSTATUS nbench_fsinfo(struct ntvfs_module_context *ntvfs, /* return print queue info */ -static void nbench_lpq_send(struct smbsrv_request *req) +static void nbench_lpq_send(struct ntvfs_request *req) { union smb_lpq *lpq = req->async_states->private_data; @@ -766,7 +765,7 @@ static void nbench_lpq_send(struct smbsrv_request *req) } static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) + struct ntvfs_request *req, union smb_lpq *lpq) { NTSTATUS status; @@ -778,7 +777,7 @@ static NTSTATUS nbench_lpq(struct ntvfs_module_context *ntvfs, /* list files in a directory matching a wildcard pattern */ -static void nbench_search_first_send(struct smbsrv_request *req) +static void nbench_search_first_send(struct ntvfs_request *req) { union smb_search_first *io = req->async_states->private_data; @@ -804,7 +803,7 @@ static void nbench_search_first_send(struct smbsrv_request *req) } static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, + struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -816,7 +815,7 @@ static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, } /* continue a search */ -static void nbench_search_next_send(struct smbsrv_request *req) +static void nbench_search_next_send(struct ntvfs_request *req) { union smb_search_next *io = req->async_states->private_data; @@ -826,7 +825,7 @@ static void nbench_search_next_send(struct smbsrv_request *req) } static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, + struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -838,7 +837,7 @@ static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, } /* close a search */ -static void nbench_search_close_send(struct smbsrv_request *req) +static void nbench_search_close_send(struct ntvfs_request *req) { union smb_search_close *io = req->async_states->private_data; @@ -848,7 +847,7 @@ static void nbench_search_close_send(struct smbsrv_request *req) } static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) + struct ntvfs_request *req, union smb_search_close *io) { NTSTATUS status; @@ -858,7 +857,7 @@ static NTSTATUS nbench_search_close(struct ntvfs_module_context *ntvfs, } /* SMBtrans - not used on file shares */ -static void nbench_trans_send(struct smbsrv_request *req) +static void nbench_trans_send(struct ntvfs_request *req) { nbench_log(req, "Trans - NOT HANDLED\n"); @@ -866,7 +865,7 @@ static void nbench_trans_send(struct smbsrv_request *req) } static NTSTATUS nbench_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, struct smb_trans2 *trans2) { NTSTATUS status; @@ -896,7 +895,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.chkpath = nbench_chkpath; ops.qpathinfo = nbench_qpathinfo; ops.setpathinfo = nbench_setpathinfo; - ops.openfile = nbench_openfile; + ops.open = nbench_open; ops.mkdir = nbench_mkdir; ops.rmdir = nbench_rmdir; ops.rename = nbench_rename; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 80f6e94125..46d288c853 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -25,6 +25,8 @@ struct ntvfs_module_context; +#define ntvfs_request smbsrv_request + /* each backend has to be one one of the following 3 basic types. In * earlier versions of Samba backends needed to handle all types, now * we implement them separately. */ @@ -35,96 +37,123 @@ enum ntvfs_type {NTVFS_DISK, NTVFS_PRINT, NTVFS_IPC}; struct ntvfs_ops { const char *name; enum ntvfs_type type; - + /* initial setup */ - NTSTATUS (*connect)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename); - NTSTATUS (*disconnect)(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon); + NTSTATUS (*connect)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + const char *sharename); + NTSTATUS (*disconnect)(struct ntvfs_module_context *ntvfs); + + /* async_setup - called when a backend is processing a async request */ + NTSTATUS (*async_setup)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *private); + + /* filesystem operations */ + NTSTATUS (*fsinfo)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fsinfo *fs); /* path operations */ - NTSTATUS (*unlink)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl); - NTSTATUS (*chkpath)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp); - NTSTATUS (*qpathinfo)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *st); - NTSTATUS (*setpathinfo)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st); - NTSTATUS (*openfile)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *oi); - NTSTATUS (*mkdir)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md); - NTSTATUS (*rmdir)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd); - NTSTATUS (*rename)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren); - NTSTATUS (*copy)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp); + NTSTATUS (*unlink)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_unlink *unl); + NTSTATUS (*chkpath)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_chkpath *cp); + NTSTATUS (*qpathinfo)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fileinfo *st); + NTSTATUS (*setpathinfo)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *st); + NTSTATUS (*mkdir)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_mkdir *md); + NTSTATUS (*rmdir)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_rmdir *rd); + NTSTATUS (*rename)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_rename *ren); + NTSTATUS (*copy)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_copy *cp); + NTSTATUS (*open)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_open *oi); /* directory search */ - NTSTATUS (*search_first)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, void *private, + NTSTATUS (*search_first)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)); - NTSTATUS (*search_next)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)); - NTSTATUS (*search_close)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io); + NTSTATUS (*search_next)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_search_next *io, void *private, + BOOL (*callback)(void *private, union smb_search_data *file)); + NTSTATUS (*search_close)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_search_close *io); /* operations on open files */ - NTSTATUS (*ioctl)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io); - NTSTATUS (*read)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *io); - NTSTATUS (*write)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *io); - NTSTATUS (*seek)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io); - NTSTATUS (*flush)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *flush); - NTSTATUS (*close)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io); - NTSTATUS (*exit)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req); - NTSTATUS (*lock)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck); - NTSTATUS (*setfileinfo)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *info); - NTSTATUS (*qfileinfo)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info); - - /* filesystem operations */ - NTSTATUS (*fsinfo)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs); - - /* printing specific operations */ - NTSTATUS (*lpq)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq); - - /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ - NTSTATUS (*trans2)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2); + NTSTATUS (*ioctl)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_ioctl *io); + NTSTATUS (*read)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_read *io); + NTSTATUS (*write)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_write *io); + NTSTATUS (*seek)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_seek *io); + NTSTATUS (*flush)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_flush *flush); + NTSTATUS (*lock)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_lock *lck); + NTSTATUS (*qfileinfo)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fileinfo *info); + NTSTATUS (*setfileinfo)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *info); + NTSTATUS (*close)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_close *io); /* trans interface - used by IPC backend for pipes and RAP calls */ - NTSTATUS (*trans)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans); + NTSTATUS (*trans)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_trans2 *trans); - /* logoff - called when a vuid is closed */ - NTSTATUS (*logoff)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req); + /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ + NTSTATUS (*trans2)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_trans2 *trans2); - /* async_setup - called when a backend is processing a async request */ - NTSTATUS (*async_setup)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, void *private); + /* change notify request */ + NTSTATUS (*notify)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_notify *info); /* cancel - cancels any pending async request */ - NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req); + NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req); - /* change notify request */ - NTSTATUS (*notify)(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_notify *info); + /* printing specific operations */ + NTSTATUS (*lpq)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_lpq *lpq); + + /* logoff - called when a vuid is closed */ + NTSTATUS (*logoff)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req); + NTSTATUS (*exit)(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req); }; struct ntvfs_module_context { @@ -166,7 +195,7 @@ struct ntvfs_async_state { /* the async handling infos */ uint_t state; void *private_data; - void (*send_fn)(struct smbsrv_request *); + void (*send_fn)(struct ntvfs_request *); NTSTATUS status; /* the passthru module's per session private data */ @@ -181,8 +210,7 @@ struct ntvfs_critical_sizes { int sizeof_ntvfs_module_context; int sizeof_ntvfs_ops; int sizeof_ntvfs_async_state; - int sizeof_smbsrv_tcon; - int sizeof_smbsrv_request; + int sizeof_ntvfs_request; }; #include "ntvfs/ntvfs_proto.h" diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 1201bdefbe..7351d6b2a6 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -99,19 +99,18 @@ _PUBLIC_ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntv This can be used by backends to either detect compilation errors, or provide multiple implementations for different smbd compilation options in one module */ +static const struct ntvfs_critical_sizes critical_sizes = { + .interface_version = NTVFS_INTERFACE_VERSION, + .sizeof_ntvfs_critical_sizes = sizeof(struct ntvfs_critical_sizes), + .sizeof_ntvfs_context = sizeof(struct ntvfs_context), + .sizeof_ntvfs_module_context = sizeof(struct ntvfs_module_context), + .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), + .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), + .sizeof_ntvfs_request = sizeof(struct ntvfs_request), +}; + _PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { - static const struct ntvfs_critical_sizes critical_sizes = { - NTVFS_INTERFACE_VERSION, - sizeof(struct ntvfs_critical_sizes), - sizeof(struct ntvfs_context), - sizeof(struct ntvfs_module_context), - sizeof(struct ntvfs_ops), - sizeof(struct ntvfs_async_state), - sizeof(struct smbsrv_tcon), - sizeof(struct smbsrv_request), - }; - return &critical_sizes; } @@ -119,7 +118,7 @@ _PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) /* initialise a connection structure to point at a NTVFS backend */ -NTSTATUS ntvfs_init_connection(struct smbsrv_request *req, enum ntvfs_type type) +NTSTATUS ntvfs_init_connection(struct ntvfs_request *req, enum ntvfs_type type) { const char **handlers = lp_ntvfs_handler(req->tcon->service); int i; diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index e5224aafcd..5133f63268 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -38,8 +38,8 @@ /* a second stage function converts from the out parameters of the generic call onto the out parameters of the specific call made */ -typedef NTSTATUS (*second_stage_t)(struct smbsrv_request *, - struct ntvfs_module_context *, +typedef NTSTATUS (*second_stage_t)(struct ntvfs_module_context *, + struct ntvfs_request *, void *, void *, NTSTATUS); /* @@ -55,14 +55,14 @@ struct ntvfs_map_async { this is a async wrapper, called from the backend when it has completed a function that it has decided to reply to in an async fashion */ -static void ntvfs_map_async_send(struct smbsrv_request *req) +static void ntvfs_map_async_send(struct ntvfs_request *req) { struct ntvfs_map_async *m = req->async_states->private_data; ntvfs_async_state_pop(req); /* call the _finish function setup in ntvfs_map_async_setup() */ - req->async_states->status = m->fn(req, m->ntvfs, m->io, m->io2, req->async_states->status); + req->async_states->status = m->fn(m->ntvfs, req, m->io, m->io2, req->async_states->status); /* call the send function from the next module up */ req->async_states->send_fn(req); @@ -74,8 +74,8 @@ static void ntvfs_map_async_send(struct smbsrv_request *req) io2 is the new call structure for the mapped call fn is a second stage function for processing the out arguments */ -static NTSTATUS ntvfs_map_async_setup(struct smbsrv_request *req, - struct ntvfs_module_context *ntvfs, +static NTSTATUS ntvfs_map_async_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, void *io, void *io2, second_stage_t fn) { @@ -88,14 +88,13 @@ static NTSTATUS ntvfs_map_async_setup(struct smbsrv_request *req, m->io = io; m->io2 = io2; m->fn = fn; - return ntvfs_async_state_push(req, m, ntvfs_map_async_send, ntvfs); + return ntvfs_async_state_push(ntvfs, req, m, ntvfs_map_async_send); } - /* called when first stage processing is complete. */ -static NTSTATUS ntvfs_map_async_finish(struct smbsrv_request *req, NTSTATUS status) +static NTSTATUS ntvfs_map_async_finish(struct ntvfs_request *req, NTSTATUS status) { struct ntvfs_map_async *m; @@ -111,10 +110,9 @@ static NTSTATUS ntvfs_map_async_finish(struct smbsrv_request *req, NTSTATUS stat ntvfs_async_state_pop(req); - return m->fn(req, m->ntvfs, m->io, m->io2, status); + return m->fn(m->ntvfs, req, m->io, m->io2, status); } - /* see if a filename ends in EXE COM DLL or SYM. This is needed for the DENY_DOS mapping for OpenX @@ -140,8 +138,8 @@ BOOL is_exe_filename(const char *fname) /* NTVFS openx to ntcreatex mapper */ -static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, - struct ntvfs_module_context *ntvfs, +static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io, union smb_open *io2, NTSTATUS status) @@ -206,6 +204,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, io->ctemp.out.fnum = io2->generic.out.fnum; io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + strlen(io->ctemp.in.directory) + 1); + NT_STATUS_HAVE_NO_MEMORY(io->ctemp.out.name); break; default: @@ -218,9 +217,10 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; if (write_time != 0) { - sf = talloc(req, union smb_setfileinfo); - sf->generic.level = RAW_SFILEINFO_STANDARD; - sf->generic.file.fnum = io2->generic.out.fnum; + sf = talloc(req, union smb_setfileinfo); + NT_STATUS_HAVE_NO_MEMORY(sf); + sf->generic.level = RAW_SFILEINFO_STANDARD; + sf->generic.file.fnum = io2->generic.out.fnum; sf->standard.in.create_time = 0; sf->standard.in.write_time = write_time; sf->standard.in.access_time = 0; @@ -229,6 +229,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req, if (set_size != 0) { sf = talloc(req, union smb_setfileinfo); + NT_STATUS_HAVE_NO_MEMORY(sf); sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; sf->generic.file.fnum = io2->generic.out.fnum; sf->end_of_file_info.in.size = set_size; @@ -346,8 +347,9 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, /* NTVFS open generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_open *io) { NTSTATUS status; union smb_open *io2; @@ -357,7 +359,8 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, return NT_STATUS_NO_MEMORY; } - status = ntvfs_map_async_setup(req, ntvfs, io, io2, + status = ntvfs_map_async_setup(ntvfs, req, + io, io2, (second_stage_t)ntvfs_map_open_finish); if (!NT_STATUS_IS_OK(status)) { return status; @@ -379,7 +382,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.file_attr = io->openx.in.file_attrs; io2->generic.in.fname = io->openx.in.fname; - status = ntvfs->ops->openfile(ntvfs, req, io2); + status = ntvfs->ops->open(ntvfs, req, io2); break; @@ -396,7 +399,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.file_attr = io->openold.in.search_attrs; io2->generic.in.fname = io->openold.in.fname; - status = ntvfs->ops->openfile(ntvfs, req, io2); + status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_T2OPEN: @@ -422,7 +425,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.ea_list->num_eas = io->t2open.in.num_eas; io2->generic.in.ea_list->eas = io->t2open.in.eas; - status = ntvfs->ops->openfile(ntvfs, req, io2); + status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_MKNEW: @@ -435,7 +438,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - status = ntvfs->ops->openfile(ntvfs, req, io2); + status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_CREATE: @@ -448,7 +451,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - status = ntvfs->ops->openfile(ntvfs, req, io2); + status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_CTEMP: @@ -465,7 +468,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io, io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - status = ntvfs->ops->openfile(ntvfs, req, io2); + status = ntvfs->ops->open(ntvfs, req, io2); break; default: @@ -480,8 +483,9 @@ done: /* NTVFS fsinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fsinfo *fs) { NTSTATUS status; union smb_fsinfo *fs2; @@ -608,7 +612,8 @@ _PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct smbsrv_request *req, union smb_fsinfo /* NTVFS fileinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_fileinfo *info, +_PUBLIC_ NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, + union smb_fileinfo *info, union smb_fileinfo *info2) { int i; @@ -714,7 +719,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_filei info->stream_info.out.num_streams = info2->generic.out.num_streams; if (info->stream_info.out.num_streams > 0) { info->stream_info.out.streams = - talloc_array(req, + talloc_array(mem_ctx, struct stream_struct, info->stream_info.out.num_streams); if (!info->stream_info.out.streams) { @@ -725,7 +730,8 @@ _PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_filei for (i=0; i < info->stream_info.out.num_streams; i++) { info->stream_info.out.streams[i] = info2->generic.out.streams[i]; info->stream_info.out.streams[i].stream_name.s = - talloc_strdup(req, info2->generic.out.streams[i].stream_name.s); + talloc_strdup(info->stream_info.out.streams, + info2->generic.out.streams[i].stream_name.s); if (!info->stream_info.out.streams[i].stream_name.s) { DEBUG(2,("ntvfs_map_fileinfo: no memory for stream_name\n")); return NT_STATUS_NO_MEMORY; @@ -736,13 +742,15 @@ _PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_filei case RAW_FILEINFO_NAME_INFO: case RAW_FILEINFO_NAME_INFORMATION: - info->name_info.out.fname.s = talloc_strdup(req, info2->generic.out.fname.s); + info->name_info.out.fname.s = talloc_strdup(mem_ctx, info2->generic.out.fname.s); + NT_STATUS_HAVE_NO_MEMORY(info->name_info.out.fname.s); info->name_info.out.fname.private_length = info2->generic.out.fname.private_length; return NT_STATUS_OK; case RAW_FILEINFO_ALT_NAME_INFO: case RAW_FILEINFO_ALT_NAME_INFORMATION: - info->alt_name_info.out.fname.s = talloc_strdup(req, info2->generic.out.alt_fname.s); + info->alt_name_info.out.fname.s = talloc_strdup(mem_ctx, info2->generic.out.alt_fname.s); + NT_STATUS_HAVE_NO_MEMORY(info->alt_name_info.out.fname.s); info->alt_name_info.out.fname.private_length = info2->generic.out.alt_fname.private_length; return NT_STATUS_OK; @@ -753,7 +761,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_filei case RAW_FILEINFO_ALL_EAS: info->all_eas.out.num_eas = info2->generic.out.num_eas; if (info->all_eas.out.num_eas > 0) { - info->all_eas.out.eas = talloc_array(req, + info->all_eas.out.eas = talloc_array(mem_ctx, struct ea_struct, info->all_eas.out.num_eas); if (!info->all_eas.out.eas) { @@ -764,13 +772,14 @@ _PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_filei for (i = 0; i < info->all_eas.out.num_eas; i++) { info->all_eas.out.eas[i] = info2->generic.out.eas[i]; info->all_eas.out.eas[i].name.s = - talloc_strdup(req, info2->generic.out.eas[i].name.s); + talloc_strdup(info->all_eas.out.eas, + info2->generic.out.eas[i].name.s); if (!info->all_eas.out.eas[i].name.s) { DEBUG(2,("ntvfs_map_fileinfo: no memory for stream_name\n")); return NT_STATUS_NO_MEMORY; } info->all_eas.out.eas[i].value.data = - talloc_memdup(req, + talloc_memdup(info->all_eas.out.eas, info2->generic.out.eas[i].value.data, info2->generic.out.eas[i].value.length); if (!info->all_eas.out.eas[i].value.data) { @@ -834,8 +843,9 @@ _PUBLIC_ NTSTATUS ntvfs_map_fileinfo(struct smbsrv_request *req, union smb_filei /* NTVFS fileinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fileinfo *info) { NTSTATUS status; union smb_fileinfo *info2; @@ -866,8 +876,9 @@ _PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct smbsrv_request *req, union smb_file /* NTVFS pathinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *info, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fileinfo *info) { NTSTATUS status; union smb_fileinfo *info2; @@ -899,8 +910,9 @@ _PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct smbsrv_request *req, union smb_file /* NTVFS lock generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_lock *lck) { union smb_lock *lck2; struct smb_lock_entry *locks; @@ -951,12 +963,11 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct smbsrv_request *req, union smb_lock *lck /* NTVFS write generic to any mapper */ -static NTSTATUS ntvfs_map_write_finish(struct smbsrv_request *req, - struct ntvfs_module_context *ntvfs, +static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_write *wr, union smb_write *wr2, NTSTATUS status) - { union smb_lock *lck; union smb_close *cl; @@ -1027,8 +1038,9 @@ static NTSTATUS ntvfs_map_write_finish(struct smbsrv_request *req, /* NTVFS write generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *wr, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_write *wr) { union smb_write *wr2; NTSTATUS status; @@ -1038,7 +1050,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *w return NT_STATUS_NO_MEMORY; } - status = ntvfs_map_async_setup(req, ntvfs, wr, wr2, + status = ntvfs_map_async_setup(ntvfs, req, wr, wr2, (second_stage_t)ntvfs_map_write_finish); if (!NT_STATUS_IS_OK(status)) { return status; @@ -1099,8 +1111,8 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct smbsrv_request *req, union smb_write *w /* NTVFS read generic to any mapper - finish the out mapping */ -static NTSTATUS ntvfs_map_read_finish(struct smbsrv_request *req, - struct ntvfs_module_context *ntvfs, +static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_read *rd, union smb_read *rd2, NTSTATUS status) @@ -1125,8 +1137,9 @@ static NTSTATUS ntvfs_map_read_finish(struct smbsrv_request *req, /* NTVFS read* to readx mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_read *rd) { union smb_read *rd2; union smb_lock *lck; @@ -1138,7 +1151,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct smbsrv_request *req, union smb_read *rd, return NT_STATUS_NO_MEMORY; } - status = ntvfs_map_async_setup(req, ntvfs, rd, rd2, + status = ntvfs_map_async_setup(ntvfs, req, rd, rd2, (second_stage_t)ntvfs_map_read_finish); if (!NT_STATUS_IS_OK(status)) { return status; @@ -1209,8 +1222,9 @@ done: /* NTVFS close generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_close(struct smbsrv_request *req, union smb_close *cl, - struct ntvfs_module_context *ntvfs) +_PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_close *cl) { union smb_close *cl2; diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index a3a605c0c8..2be3170bd8 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -24,7 +24,7 @@ #include "ntvfs/ntvfs.h" /* connect/disconnect */ -_PUBLIC_ NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharename) +_PUBLIC_ NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->connect) { @@ -33,21 +33,42 @@ _PUBLIC_ NTSTATUS ntvfs_connect(struct smbsrv_request *req, const char *sharenam return ntvfs->ops->connect(ntvfs, req, sharename); } -_PUBLIC_ NTSTATUS ntvfs_disconnect(struct smbsrv_tcon *tcon) +_PUBLIC_ NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx) { struct ntvfs_module_context *ntvfs; - if (tcon->ntvfs_ctx == NULL) { + if (ntvfs_ctx == NULL) { return NT_STATUS_INVALID_CONNECTION; } - ntvfs = tcon->ntvfs_ctx->modules; + ntvfs = ntvfs_ctx->modules; if (!ntvfs->ops->disconnect) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->disconnect(ntvfs, tcon); + return ntvfs->ops->disconnect(ntvfs); +} + +/* async setup - called by a backend that wants to setup any state for + a async request */ +_PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->async_setup) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->async_setup(ntvfs, req, private); +} + +/* filesystem operations */ +_PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) +{ + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + if (!ntvfs->ops->fsinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->ops->fsinfo(ntvfs, req, fs); } /* path operations */ -_PUBLIC_ NTSTATUS ntvfs_unlink(struct smbsrv_request *req, struct smb_unlink *unl) +_PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, struct smb_unlink *unl) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->unlink) { @@ -56,7 +77,7 @@ _PUBLIC_ NTSTATUS ntvfs_unlink(struct smbsrv_request *req, struct smb_unlink *un return ntvfs->ops->unlink(ntvfs, req, unl); } -_PUBLIC_ NTSTATUS ntvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath *cp) +_PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, struct smb_chkpath *cp) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->chkpath) { @@ -65,7 +86,7 @@ _PUBLIC_ NTSTATUS ntvfs_chkpath(struct smbsrv_request *req, struct smb_chkpath * return ntvfs->ops->chkpath(ntvfs, req, cp); } -_PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo *st) +_PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo *st) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->qpathinfo) { @@ -74,7 +95,7 @@ _PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct smbsrv_request *req, union smb_fileinfo return ntvfs->ops->qpathinfo(ntvfs, req, st); } -_PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfileinfo *st) +_PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfileinfo *st) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->setpathinfo) { @@ -83,16 +104,16 @@ _PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct smbsrv_request *req, union smb_setfil return ntvfs->ops->setpathinfo(ntvfs, req, st); } -_PUBLIC_ NTSTATUS ntvfs_openfile(struct smbsrv_request *req, union smb_open *oi) +_PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->openfile) { + if (!ntvfs->ops->open) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->openfile(ntvfs, req, oi); + return ntvfs->ops->open(ntvfs, req, oi); } -_PUBLIC_ NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) +_PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->mkdir) { @@ -101,7 +122,7 @@ _PUBLIC_ NTSTATUS ntvfs_mkdir(struct smbsrv_request *req, union smb_mkdir *md) return ntvfs->ops->mkdir(ntvfs, req, md); } -_PUBLIC_ NTSTATUS ntvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) +_PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->rmdir) { @@ -110,7 +131,7 @@ _PUBLIC_ NTSTATUS ntvfs_rmdir(struct smbsrv_request *req, struct smb_rmdir *rd) return ntvfs->ops->rmdir(ntvfs, req, rd); } -_PUBLIC_ NTSTATUS ntvfs_rename(struct smbsrv_request *req, union smb_rename *ren) +_PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->rename) { @@ -119,7 +140,7 @@ _PUBLIC_ NTSTATUS ntvfs_rename(struct smbsrv_request *req, union smb_rename *ren return ntvfs->ops->rename(ntvfs, req, ren); } -_PUBLIC_ NTSTATUS ntvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) +_PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->copy) { @@ -129,7 +150,7 @@ _PUBLIC_ NTSTATUS ntvfs_copy(struct smbsrv_request *req, struct smb_copy *cp) } /* directory search */ -_PUBLIC_ NTSTATUS ntvfs_search_first(struct smbsrv_request *req, union smb_search_first *io, void *private, +_PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private, BOOL ntvfs_callback(void *private, union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; @@ -139,7 +160,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_first(struct smbsrv_request *req, union smb_searc return ntvfs->ops->search_first(ntvfs, req, io, private, ntvfs_callback); } -_PUBLIC_ NTSTATUS ntvfs_search_next(struct smbsrv_request *req, union smb_search_next *io, void *private, +_PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private, BOOL ntvfs_callback(void *private, union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; @@ -149,7 +170,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_next(struct smbsrv_request *req, union smb_search return ntvfs->ops->search_next(ntvfs, req, io, private, ntvfs_callback); } -_PUBLIC_ NTSTATUS ntvfs_search_close(struct smbsrv_request *req, union smb_search_close *io) +_PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search_close *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->search_close) { @@ -159,7 +180,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_close(struct smbsrv_request *req, union smb_searc } /* operations on open files */ -_PUBLIC_ NTSTATUS ntvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) +_PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->ioctl) { @@ -168,7 +189,7 @@ _PUBLIC_ NTSTATUS ntvfs_ioctl(struct smbsrv_request *req, union smb_ioctl *io) return ntvfs->ops->ioctl(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_read(struct smbsrv_request *req, union smb_read *io) +_PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->read) { @@ -177,7 +198,7 @@ _PUBLIC_ NTSTATUS ntvfs_read(struct smbsrv_request *req, union smb_read *io) return ntvfs->ops->read(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_write(struct smbsrv_request *req, union smb_write *io) +_PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->write) { @@ -186,7 +207,7 @@ _PUBLIC_ NTSTATUS ntvfs_write(struct smbsrv_request *req, union smb_write *io) return ntvfs->ops->write(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_seek(struct smbsrv_request *req, struct smb_seek *io) +_PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, struct smb_seek *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->seek) { @@ -195,7 +216,8 @@ _PUBLIC_ NTSTATUS ntvfs_seek(struct smbsrv_request *req, struct smb_seek *io) return ntvfs->ops->seek(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_flush(struct smbsrv_request *req, struct smb_flush *flush) +_PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, + struct smb_flush *flush) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->flush) { @@ -204,25 +226,7 @@ _PUBLIC_ NTSTATUS ntvfs_flush(struct smbsrv_request *req, struct smb_flush *flus return ntvfs->ops->flush(ntvfs, req, flush); } -_PUBLIC_ NTSTATUS ntvfs_close(struct smbsrv_request *req, union smb_close *io) -{ - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->close) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return ntvfs->ops->close(ntvfs, req, io); -} - -_PUBLIC_ NTSTATUS ntvfs_exit(struct smbsrv_request *req) -{ - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->exit) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return ntvfs->ops->exit(ntvfs, req); -} - -_PUBLIC_ NTSTATUS ntvfs_lock(struct smbsrv_request *req, union smb_lock *lck) +_PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->lock) { @@ -231,46 +235,45 @@ _PUBLIC_ NTSTATUS ntvfs_lock(struct smbsrv_request *req, union smb_lock *lck) return ntvfs->ops->lock(ntvfs, req, lck); } -_PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct smbsrv_request *req, union smb_setfileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo *info) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->setfileinfo) { + if (!ntvfs->ops->qfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->setfileinfo(ntvfs, req, info); + return ntvfs->ops->qfileinfo(ntvfs, req, info); } -_PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct smbsrv_request *req, union smb_fileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfileinfo *info) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->qfileinfo) { + if (!ntvfs->ops->setfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->qfileinfo(ntvfs, req, info); + return ntvfs->ops->setfileinfo(ntvfs, req, info); } -/* filesystem operations */ -_PUBLIC_ NTSTATUS ntvfs_fsinfo(struct smbsrv_request *req, union smb_fsinfo *fs) +_PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->fsinfo) { + if (!ntvfs->ops->close) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->fsinfo(ntvfs, req, fs); + return ntvfs->ops->close(ntvfs, req, io); } -/* printing specific operations */ -_PUBLIC_ NTSTATUS ntvfs_lpq(struct smbsrv_request *req, union smb_lpq *lpq) +/* trans interface - used by IPC backend for pipes and RAP calls */ +_PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *trans) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->lpq) { + if (!ntvfs->ops->trans) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->lpq(ntvfs, req, lpq); + return ntvfs->ops->trans(ntvfs, req, trans); } /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ -_PUBLIC_ NTSTATUS ntvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *trans2) +_PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *trans2) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->trans2) { @@ -279,18 +282,18 @@ _PUBLIC_ NTSTATUS ntvfs_trans2(struct smbsrv_request *req, struct smb_trans2 *tr return ntvfs->ops->trans2(ntvfs, req, trans2); } -/* trans interface - used by IPC backend for pipes and RAP calls */ -_PUBLIC_ NTSTATUS ntvfs_trans(struct smbsrv_request *req, struct smb_trans2 *trans) +/* printing specific operations */ +_PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->trans) { + if (!ntvfs->ops->lpq) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->trans(ntvfs, req, trans); + return ntvfs->ops->lpq(ntvfs, req, lpq); } /* logoff - called when a vuid is closed */ -_PUBLIC_ NTSTATUS ntvfs_logoff(struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->logoff) { @@ -299,47 +302,42 @@ _PUBLIC_ NTSTATUS ntvfs_logoff(struct smbsrv_request *req) return ntvfs->ops->logoff(ntvfs, req); } -/* async setup - called by a backend that wants to setup any state for - a async request */ -_PUBLIC_ NTSTATUS ntvfs_async_setup(struct smbsrv_request *req, void *private) +_PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->async_setup) { + if (!ntvfs->ops->exit) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->async_setup(ntvfs, req, private); + return ntvfs->ops->exit(ntvfs, req); } - /* - cancel an outstanding async request + change notify request */ -_PUBLIC_ NTSTATUS ntvfs_cancel(struct smbsrv_request *req) +_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, struct smb_notify *info) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->cancel) { + if (!ntvfs->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->cancel(ntvfs, req); + return ntvfs->ops->notify(ntvfs, req, info); } - /* - change notify request + cancel an outstanding async request */ -_PUBLIC_ NTSTATUS ntvfs_notify(struct smbsrv_request *req, struct smb_notify *info) +_PUBLIC_ NTSTATUS ntvfs_cancel(struct ntvfs_request *req) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; - if (!ntvfs->ops->notify) { + if (!ntvfs->ops->cancel) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->ops->notify(ntvfs, req, info); + return ntvfs->ops->cancel(ntvfs, req); } - /* initial setup */ _PUBLIC_ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { if (!ntvfs->next || !ntvfs->next->ops->connect) { return NT_STATUS_NOT_IMPLEMENTED; @@ -347,18 +345,40 @@ _PUBLIC_ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->connect(ntvfs->next, req, sharename); } -_PUBLIC_ NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +_PUBLIC_ NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs) { if (!ntvfs->next || !ntvfs->next->ops->disconnect) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->disconnect(ntvfs->next, tcon); + return ntvfs->next->ops->disconnect(ntvfs->next); +} + +/* async_setup - called when setting up for a async request */ +_PUBLIC_ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *private) +{ + if (!ntvfs->next || !ntvfs->next->ops->async_setup) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->async_setup(ntvfs->next, req, private); +} + +/* filesystem operations */ +_PUBLIC_ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fsinfo *fs) +{ + if (!ntvfs->next || !ntvfs->next->ops->fsinfo) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->fsinfo(ntvfs->next, req, fs); } /* path operations */ _PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + struct smb_unlink *unl) { if (!ntvfs->next || !ntvfs->next->ops->unlink) { return NT_STATUS_NOT_IMPLEMENTED; @@ -367,7 +387,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, + struct smb_chkpath *cp) { if (!ntvfs->next || !ntvfs->next->ops->chkpath) { return NT_STATUS_NOT_IMPLEMENTED; @@ -376,7 +397,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *st) + struct ntvfs_request *req, + union smb_fileinfo *st) { if (!ntvfs->next || !ntvfs->next->ops->qpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; @@ -385,7 +407,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) + struct ntvfs_request *req, + union smb_setfileinfo *st) { if (!ntvfs->next || !ntvfs->next->ops->setpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; @@ -393,17 +416,9 @@ _PUBLIC_ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st); } -_PUBLIC_ NTSTATUS ntvfs_next_openfile(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *oi) -{ - if (!ntvfs->next || !ntvfs->next->ops->openfile) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return ntvfs->next->ops->openfile(ntvfs->next, req, oi); -} - _PUBLIC_ NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, + union smb_mkdir *md) { if (!ntvfs->next || !ntvfs->next->ops->mkdir) { return NT_STATUS_NOT_IMPLEMENTED; @@ -412,7 +427,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, + struct smb_rmdir *rd) { if (!ntvfs->next || !ntvfs->next->ops->rmdir) { return NT_STATUS_NOT_IMPLEMENTED; @@ -421,7 +437,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, + union smb_rename *ren) { if (!ntvfs->next || !ntvfs->next->ops->rename) { return NT_STATUS_NOT_IMPLEMENTED; @@ -430,7 +447,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) + struct ntvfs_request *req, + struct smb_copy *cp) { if (!ntvfs->next || !ntvfs->next->ops->copy) { return NT_STATUS_NOT_IMPLEMENTED; @@ -438,9 +456,21 @@ _PUBLIC_ NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->copy(ntvfs->next, req, cp); } +_PUBLIC_ NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_open *oi) +{ + if (!ntvfs->next || !ntvfs->next->ops->open) { + return NT_STATUS_NOT_IMPLEMENTED; + } + return ntvfs->next->ops->open(ntvfs->next, req, oi); +} + + /* directory search */ _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, void *private, + struct ntvfs_request *req, + union smb_search_first *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_first) { @@ -450,7 +480,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, void *private, + struct ntvfs_request *req, + union smb_search_next *io, void *private, BOOL (*callback)(void *private, union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_next) { @@ -460,7 +491,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) + struct ntvfs_request *req, + union smb_search_close *io) { if (!ntvfs->next || !ntvfs->next->ops->search_close) { return NT_STATUS_NOT_IMPLEMENTED; @@ -470,7 +502,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, /* operations on open files */ _PUBLIC_ NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, + union smb_ioctl *io) { if (!ntvfs->next || !ntvfs->next->ops->ioctl) { return NT_STATUS_NOT_IMPLEMENTED; @@ -479,7 +512,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *io) + struct ntvfs_request *req, + union smb_read *io) { if (!ntvfs->next || !ntvfs->next->ops->read) { return NT_STATUS_NOT_IMPLEMENTED; @@ -488,7 +522,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *io) + struct ntvfs_request *req, + union smb_write *io) { if (!ntvfs->next || !ntvfs->next->ops->write) { return NT_STATUS_NOT_IMPLEMENTED; @@ -497,7 +532,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct ntvfs_request *req, + struct smb_seek *io) { if (!ntvfs->next || !ntvfs->next->ops->seek) { return NT_STATUS_NOT_IMPLEMENTED; @@ -506,7 +542,8 @@ _PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *flush) + struct ntvfs_request *req, + struct smb_flush *flush) { if (!ntvfs->next || !ntvfs->next->ops->flush) { return NT_STATUS_NOT_IMPLEMENTED; @@ -514,26 +551,9 @@ _PUBLIC_ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->flush(ntvfs->next, req, flush); } -_PUBLIC_ NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) -{ - if (!ntvfs->next || !ntvfs->next->ops->close) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return ntvfs->next->ops->close(ntvfs->next, req, io); -} - -_PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) -{ - if (!ntvfs->next || !ntvfs->next->ops->exit) { - return NT_STATUS_NOT_IMPLEMENTED; - } - return ntvfs->next->ops->exit(ntvfs->next, req); -} - _PUBLIC_ NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) + struct ntvfs_request *req, + union smb_lock *lck) { if (!ntvfs->next || !ntvfs->next->ops->lock) { return NT_STATUS_NOT_IMPLEMENTED; @@ -541,47 +561,51 @@ _PUBLIC_ NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->lock(ntvfs->next, req, lck); } -_PUBLIC_ NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_fileinfo *info) { - if (!ntvfs->next || !ntvfs->next->ops->setfileinfo) { + if (!ntvfs->next || !ntvfs->next->ops->qfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info); + return ntvfs->next->ops->qfileinfo(ntvfs->next, req, info); } -_PUBLIC_ NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) +_PUBLIC_ NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *info) { - if (!ntvfs->next || !ntvfs->next->ops->qfileinfo) { + if (!ntvfs->next || !ntvfs->next->ops->setfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->qfileinfo(ntvfs->next, req, info); + return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info); } -/* filesystem operations */ -_PUBLIC_ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) +_PUBLIC_ NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_close *io) { - if (!ntvfs->next || !ntvfs->next->ops->fsinfo) { + if (!ntvfs->next || !ntvfs->next->ops->close) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->fsinfo(ntvfs->next, req, fs); + return ntvfs->next->ops->close(ntvfs->next, req, io); } -/* printing specific operations */ -_PUBLIC_ NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) +/* trans interface - used by IPC backend for pipes and RAP calls */ +_PUBLIC_ NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_trans2 *trans) { - if (!ntvfs->next || !ntvfs->next->ops->lpq) { + if (!ntvfs->next || !ntvfs->next->ops->trans) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->lpq(ntvfs->next, req, lpq); + return ntvfs->next->ops->trans(ntvfs->next, req, trans); } /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, + struct smb_trans2 *trans2) { if (!ntvfs->next || !ntvfs->next->ops->trans2) { return NT_STATUS_NOT_IMPLEMENTED; @@ -589,55 +613,56 @@ _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->trans2(ntvfs->next, req, trans2); } -/* trans interface - used by IPC backend for pipes and RAP calls */ -_PUBLIC_ NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans) +/* + change notify request +*/ +_PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_notify *info) { - if (!ntvfs->next || !ntvfs->next->ops->trans) { + if (!ntvfs->next || !ntvfs->next->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->trans(ntvfs->next, req, trans); + return ntvfs->next->ops->notify(ntvfs, req, info); } -/* logoff - called when a vuid is closed */ -_PUBLIC_ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) +/* cancel - called to cancel an outstanding async request */ +_PUBLIC_ NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) { - if (!ntvfs->next || !ntvfs->next->ops->logoff) { + if (!ntvfs->next || !ntvfs->next->ops->cancel) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->logoff(ntvfs->next, req); + return ntvfs->next->ops->cancel(ntvfs->next, req); } -/* async_setup - called when setting up for a async request */ -_PUBLIC_ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, - void *private) +/* printing specific operations */ +_PUBLIC_ NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_lpq *lpq) { - if (!ntvfs->next || !ntvfs->next->ops->async_setup) { + if (!ntvfs->next || !ntvfs->next->ops->lpq) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->async_setup(ntvfs->next, req, private); + return ntvfs->next->ops->lpq(ntvfs->next, req, lpq); } -/* cancel - called to cancel an outstanding async request */ -_PUBLIC_ NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + +/* logoff - called when a vuid is closed */ +_PUBLIC_ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) { - if (!ntvfs->next || !ntvfs->next->ops->cancel) { + if (!ntvfs->next || !ntvfs->next->ops->logoff) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->cancel(ntvfs->next, req); + return ntvfs->next->ops->logoff(ntvfs->next, req); } -/* - change notify request -*/ -_PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_notify *info) +_PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) { - if (!ntvfs->next || !ntvfs->next->ops->notify) { + if (!ntvfs->next || !ntvfs->next->ops->exit) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->notify(ntvfs, req, info); + return ntvfs->next->ops->exit(ntvfs->next, req); } diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 861f266271..c7b99d3d24 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -27,10 +27,10 @@ #include "ntvfs/ntvfs.h" -_PUBLIC_ NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, +_PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, void *private_data, - void (*send_fn)(struct smbsrv_request *), - struct ntvfs_module_context *ntvfs) + void (*send_fn)(struct ntvfs_request *)) { struct ntvfs_async_state *async; @@ -51,7 +51,7 @@ _PUBLIC_ NTSTATUS ntvfs_async_state_push(struct smbsrv_request *req, return NT_STATUS_OK; } -_PUBLIC_ void ntvfs_async_state_pop(struct smbsrv_request *req) +_PUBLIC_ void ntvfs_async_state_pop(struct ntvfs_request *req) { struct ntvfs_async_state *async; diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index a5cd919ba3..a03499b733 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -63,7 +63,7 @@ static void pvfs_translate_generic_bits(struct security_acl *acl) setup a default ACL for a file */ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, int fd, struct xattr_NTACL *acl) { @@ -183,7 +183,7 @@ static void normalise_sd_flags(struct security_descriptor *sd, uint32_t secinfo_ answer a setfileinfo for an ACL */ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, int fd, uint32_t access_mask, union smb_setfileinfo *info) @@ -281,7 +281,7 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, answer a fileinfo query for the ACL */ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, int fd, union smb_fileinfo *info) { @@ -325,7 +325,7 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, specific NT ACL */ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, uint32_t *access_mask) { @@ -358,7 +358,7 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, *access_mask is modified with the access actually granted */ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, uint32_t *access_mask) { @@ -410,7 +410,7 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, do not take or return an access check mask */ NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, uint32_t access_needed) { @@ -424,7 +424,7 @@ NTSTATUS pvfs_access_check_simple(struct pvfs_state *pvfs, access check for creating a new file/directory */ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, uint32_t *access_mask) { @@ -452,7 +452,7 @@ NTSTATUS pvfs_access_check_create(struct pvfs_state *pvfs, access check for creating a new file/directory - no access mask supplied */ NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, uint32_t access_mask) { @@ -578,7 +578,7 @@ static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, as the default ACL applies anyway */ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, int fd) { diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 5c1132db19..bf6e23d520 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -40,7 +40,7 @@ static void pvfs_flush_file(struct pvfs_state *pvfs, struct pvfs_file *f) flush a fnum */ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) + struct ntvfs_request *req, struct smb_flush *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index be87599b87..6b8f0504f2 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -79,7 +79,7 @@ static NTSTATUS pvfs_cache_base_fs_uuid(struct pvfs_state *pvfs, struct stat *st return filesystem space info */ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) + struct ntvfs_request *req, union smb_fsinfo *fs) { NTSTATUS status; struct pvfs_state *pvfs = ntvfs->private_data; diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index b35a98fa87..aaa9db9986 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -28,7 +28,7 @@ old ioctl interface */ static NTSTATUS pvfs_ioctl_old(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { return NT_STATUS_DOS(ERRSRV, ERRerror); } @@ -37,7 +37,7 @@ static NTSTATUS pvfs_ioctl_old(struct ntvfs_module_context *ntvfs, nt ioctl interface */ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; @@ -62,7 +62,7 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, ioctl interface */ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { NTSTATUS status = NT_STATUS_UNSUCCESSFUL; diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 5031e4cef7..d2317c1852 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -53,7 +53,7 @@ struct pvfs_pending_lock { struct pvfs_state *pvfs; union smb_lock *lck; struct pvfs_file *f; - struct smbsrv_request *req; + struct ntvfs_request *req; int pending_lock; void *wait_handle; struct timeval end_time; @@ -64,7 +64,7 @@ struct pvfs_pending_lock { the locks we did get and send an error */ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_file *f, struct smb_lock_entry *locks, int i, @@ -96,7 +96,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas struct pvfs_pending_lock *pending = private; struct pvfs_state *pvfs = pending->pvfs; struct pvfs_file *f = pending->f; - struct smbsrv_request *req = pending->req; + struct ntvfs_request *req = pending->req; union smb_lock *lck = pending->lck; struct smb_lock_entry *locks; enum brl_type rw; @@ -234,7 +234,7 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) /* cancel a set of locks */ -static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct smbsrv_request *req, union smb_lock *lck, +static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request *req, union smb_lock *lck, struct pvfs_file *f) { struct pvfs_pending_lock *p; @@ -271,7 +271,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct smbsrv_request lock or unlock a byte range */ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) + struct ntvfs_request *req, union smb_lock *lck) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; @@ -282,7 +282,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (lck->generic.level != RAW_LOCK_GENERIC) { - return ntvfs_map_lock(req, lck, ntvfs); + return ntvfs_map_lock(ntvfs, req, lck); } f = pvfs_find_fd(pvfs, req, lck->lockx.in.fnum); diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 591ec7ca84..fe2c5d0467 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -29,7 +29,7 @@ create a directory with EAs */ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { NTSTATUS status; struct pvfs_filename *name; @@ -90,7 +90,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, create a directory */ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; @@ -142,7 +142,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, remove a directory */ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, struct smb_rmdir *rd) { struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index e24887ca96..618ddf141b 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -39,7 +39,7 @@ find open file handle given fnum */ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, - struct smbsrv_request *req, uint16_t fnum) + struct ntvfs_request *req, uint16_t fnum) { struct pvfs_file *f; @@ -123,7 +123,7 @@ static int pvfs_dir_fnum_destructor(void *p) setup any EAs and the ACL on newly created files/directories */ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, int fd, int fnum, union smb_open *io) @@ -186,7 +186,7 @@ static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, open a directory */ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, union smb_open *io) { @@ -537,7 +537,7 @@ static NTSTATUS pvfs_brl_locking_key(struct pvfs_filename *name, create a new file */ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, union smb_open *io) { @@ -743,7 +743,7 @@ cleanup_delete: */ struct pvfs_open_retry { struct ntvfs_module_context *ntvfs; - struct smbsrv_request *req; + struct ntvfs_request *req; union smb_open *io; void *wait_handle; DATA_BLOB odb_locking_key; @@ -772,7 +772,7 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) { struct pvfs_open_retry *r = private; struct ntvfs_module_context *ntvfs = r->ntvfs; - struct smbsrv_request *req = r->req; + struct ntvfs_request *req = r->req; union smb_open *io = r->io; NTSTATUS status; @@ -828,7 +828,7 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) open processing continues. */ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io, + struct ntvfs_request *req, union smb_open *io, struct pvfs_file *f, struct odb_lock *lck) { struct pvfs_state *pvfs = ntvfs->private_data; @@ -904,7 +904,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, setup for a open retry after a sharing violation */ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, union smb_open *io, struct pvfs_file *f, struct odb_lock *lck) @@ -964,7 +964,7 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, open a file */ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) + struct ntvfs_request *req, union smb_open *io) { struct pvfs_state *pvfs = ntvfs->private_data; int flags; @@ -982,7 +982,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, different open calls. */ if (io->generic.level != RAW_OPEN_GENERIC && io->generic.level != RAW_OPEN_NTTRANS_CREATE) { - return ntvfs_map_open(req, io, ntvfs); + return ntvfs_map_open(ntvfs, req, io); } /* resolve the cifs name to a posix name */ @@ -1264,7 +1264,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, close a file */ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) + struct ntvfs_request *req, union smb_close *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; @@ -1275,7 +1275,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, } if (io->generic.level != RAW_CLOSE_CLOSE) { - return ntvfs_map_close(req, io, ntvfs); + return ntvfs_map_close(ntvfs, req, io); } f = pvfs_find_fd(pvfs, req, io->close.in.fnum); @@ -1303,7 +1303,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, logoff - close all file descriptors open by a vuid */ NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f, *next; @@ -1323,7 +1323,7 @@ NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, exit - close files for the current pid */ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f, *next; @@ -1343,7 +1343,7 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, change the delete on close flag on an already open file */ NTSTATUS pvfs_set_delete_on_close(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_file *f, BOOL del_on_close) { struct odb_lock *lck; @@ -1382,7 +1382,7 @@ NTSTATUS pvfs_set_delete_on_close(struct pvfs_state *pvfs, already open file */ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, struct odb_lock **lckp) { @@ -1427,7 +1427,7 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, already open file */ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, struct odb_lock **lckp) { @@ -1467,7 +1467,7 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, already open file */ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name) { NTSTATUS status; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index ca26331373..5d908cbee2 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -126,7 +126,7 @@ static NTSTATUS pvfs_query_all_eas(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, approximately map a struct pvfs_filename to a generic fileinfo struct */ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, union smb_fileinfo *info, int fd) { @@ -282,7 +282,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, return info on a pathname */ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_filename *name; @@ -318,7 +318,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, query info on a open file */ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index fb656470b8..93a8060926 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -28,7 +28,7 @@ read from a file */ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) + struct ntvfs_request *req, union smb_read *rd) { struct pvfs_state *pvfs = ntvfs->private_data; ssize_t ret; @@ -38,7 +38,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, uint32_t mask; if (rd->generic.level != RAW_READ_READX) { - return ntvfs_map_read(req, rd, ntvfs); + return ntvfs_map_read(ntvfs, req, rd); } f = pvfs_find_fd(pvfs, req, rd->readx.in.fnum); diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 7f1f43e719..81f6ef1bf7 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -121,7 +121,7 @@ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, rename one file from a wildcard set */ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, const char *dir_path, const char *fname1, const char *fname2, @@ -190,7 +190,7 @@ failed: rename a set of files with wildcards */ static NTSTATUS pvfs_rename_wildcard(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, union smb_rename *ren, struct pvfs_filename *name1, struct pvfs_filename *name2) @@ -244,7 +244,7 @@ static NTSTATUS pvfs_rename_wildcard(struct pvfs_state *pvfs, rename a set of files - SMBmv interface */ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; @@ -309,7 +309,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, rename a set of files - ntrename interface */ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; @@ -408,7 +408,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, rename a set of files - ntrename interface */ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { switch (ren->generic.level) { case RAW_RENAME_RENAME: diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index db197c7b62..6aa9163f1e 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -323,7 +323,7 @@ static void pvfs_search_cleanup(struct pvfs_state *pvfs) list files in a directory matching a wildcard pattern - old SMBsearch interface */ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, + struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -411,7 +411,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, /* continue a old style search */ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, + struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -455,7 +455,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, list files in a directory matching a wildcard pattern */ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, + struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -554,7 +554,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, /* continue a search */ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, + struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -619,7 +619,7 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, /* close a search */ NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) + struct ntvfs_request *req, union smb_search_close *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index c4dd30bd85..33656e4004 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -27,7 +27,7 @@ seek in a file */ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct ntvfs_request *req, struct smb_seek *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 69c9cd5e4a..db03149642 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -69,7 +69,7 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) rename_information level */ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, struct smb_rename_information *r) { @@ -238,7 +238,7 @@ NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, set info on a open file */ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, union smb_setfileinfo *info) { struct pvfs_state *pvfs = ntvfs->private_data; @@ -425,7 +425,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, set info on a pathname */ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *info) + struct ntvfs_request *req, union smb_setfileinfo *info) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_filename *name; diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 8eea2c47b8..ee90adba45 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -28,7 +28,7 @@ unlink a stream */ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct pvfs_filename *name, uint16_t attrib) { @@ -58,7 +58,7 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, unlink one file */ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, const char *unix_path, const char *fname, uint32_t attrib) { @@ -113,7 +113,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, struct smb_unlink *unl) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_dir *dir; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index c363388408..241382ba0b 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -37,7 +37,7 @@ struct pvfs_wait { int msg_type; struct messaging_context *msg_ctx; struct event_context *ev; - struct smbsrv_request *req; + struct ntvfs_request *req; enum pvfs_wait_notice reason; }; @@ -47,7 +47,7 @@ struct pvfs_wait { previous ntvfs handlers in the chain (such as security context) */ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, void *private) + struct ntvfs_request *req, void *private) { struct pvfs_wait *pwait = private; pwait->handler(pwait->private, pwait->reason); @@ -61,7 +61,7 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin uint32_t src, DATA_BLOB *data) { struct pvfs_wait *pwait = private; - struct smbsrv_request *req; + struct ntvfs_request *req; /* we need to check that this one is for us. See messaging_send_ptr() for the other side of this. @@ -90,7 +90,7 @@ static void pvfs_wait_timeout(struct event_context *ev, struct timed_event *te, struct timeval t, void *private) { struct pvfs_wait *pwait = talloc_get_type(private, struct pvfs_wait); - struct smbsrv_request *req = pwait->req; + struct ntvfs_request *req = pwait->req; pwait->reason = PVFS_WAIT_TIMEOUT; @@ -118,8 +118,8 @@ static int pvfs_wait_destructor(void *ptr) the return value is a handle. To stop waiting talloc_free this handle. */ - void *pvfs_wait_message(struct pvfs_state *pvfs, - struct smbsrv_request *req, +void *pvfs_wait_message(struct pvfs_state *pvfs, + struct ntvfs_request *req, int msg_type, struct timeval end_time, void (*fn)(void *, enum pvfs_wait_notice), @@ -167,7 +167,7 @@ static int pvfs_wait_destructor(void *ptr) /* cancel an outstanding async request */ -NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) +NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_wait *pwait; diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 025ea3f3eb..d206e3b830 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -29,7 +29,7 @@ write to a file */ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) + struct ntvfs_request *req, union smb_write *wr) { struct pvfs_state *pvfs = ntvfs->private_data; ssize_t ret; @@ -37,7 +37,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (wr->generic.level != RAW_WRITE_WRITEX) { - return ntvfs_map_write(req, wr, ntvfs); + return ntvfs_map_write(ntvfs, req, wr); } f = pvfs_find_fd(pvfs, req, wr->writex.in.fnum); diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e600be446a..66fbc4bb4c 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -112,7 +112,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) that comes later) */ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; struct pvfs_state *pvfs; @@ -194,8 +194,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS pvfs_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +static NTSTATUS pvfs_disconnect(struct ntvfs_module_context *ntvfs) { return NT_STATUS_OK; } @@ -204,7 +203,7 @@ static NTSTATUS pvfs_disconnect(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, struct smb_chkpath *cp) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_filename *name; @@ -229,7 +228,7 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs, copy a set of files */ static NTSTATUS pvfs_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) + struct ntvfs_request *req, struct smb_copy *cp) { DEBUG(0,("pvfs_copy not implemented\n")); return NT_STATUS_NOT_SUPPORTED; @@ -239,14 +238,14 @@ static NTSTATUS pvfs_copy(struct ntvfs_module_context *ntvfs, return print queue info */ static NTSTATUS pvfs_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) + struct ntvfs_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } /* SMBtrans - not used on file shares */ static NTSTATUS pvfs_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } @@ -270,7 +269,7 @@ NTSTATUS ntvfs_posix_init(void) ops.chkpath = pvfs_chkpath; ops.qpathinfo = pvfs_qpathinfo; ops.setpathinfo = pvfs_setpathinfo; - ops.openfile = pvfs_open; + ops.open = pvfs_open; ops.mkdir = pvfs_mkdir; ops.rmdir = pvfs_rmdir; ops.rename = pvfs_rename; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 3219631ebb..a22b55198c 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -195,16 +195,6 @@ struct pvfs_dir; /* types of notification for pvfs wait events */ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; - -/* putting this prototype here avoids us having to expose this whole header in the - rest of Samba */ -void *pvfs_wait_message(struct pvfs_state *pvfs, - struct smbsrv_request *req, - int msg_type, - struct timeval end_time, - void (*fn)(void *, enum pvfs_wait_notice), - void *private); - #include "ntvfs/posix/vfs_posix_proto.h" #endif /* _VFS_POSIX_H_ */ diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index b0c34b2abe..1c7699566d 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -33,7 +33,7 @@ is available */ static NTSTATUS print_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { struct smbsrv_tcon *tcon = req->tcon; @@ -49,8 +49,7 @@ static NTSTATUS print_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS print_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +static NTSTATUS print_disconnect(struct ntvfs_module_context *ntvfs) { return NT_STATUS_OK; } @@ -59,7 +58,7 @@ static NTSTATUS print_disconnect(struct ntvfs_module_context *ntvfs, lots of operations are not allowed on printing shares - mostly return NT_STATUS_ACCESS_DENIED */ static NTSTATUS print_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, struct smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } @@ -69,7 +68,7 @@ static NTSTATUS print_unlink(struct ntvfs_module_context *ntvfs, ioctl - used for job query */ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { char *p; diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index ab1eccc551..0a9701f8b3 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -35,7 +35,7 @@ convert a windows path to a unix path - don't do any manging or case sensitive handling */ char *svfs_unix_path(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *name) + struct ntvfs_request *req, const char *name) { struct svfs_private *private = ntvfs->private_data; char *ret; @@ -58,7 +58,7 @@ char *svfs_unix_path(struct ntvfs_module_context *ntvfs, returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, const char *unix_path) +struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, const char *unix_path) { char *p, *mask; struct svfs_dir *dir; @@ -141,7 +141,7 @@ struct svfs_dir *svfs_list_unix(TALLOC_CTX *mem_ctx, struct smbsrv_request *req, returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *svfs_list(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req, const char *pattern) +struct svfs_dir *svfs_list(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *pattern) { struct svfs_private *private = ntvfs->private_data; char *unix_path; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index ce14877277..be9a680d5b 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -49,7 +49,7 @@ that comes later) */ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { struct stat st; struct smbsrv_tcon *tcon = req->tcon; @@ -82,8 +82,7 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs) { return NT_STATUS_OK; } @@ -107,7 +106,7 @@ static struct svfs_file *find_fd(struct svfs_private *private, int fd) The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, struct smb_unlink *unl) { char *unix_path; @@ -128,7 +127,7 @@ static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, ioctl interface - we don't do any */ static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { return NT_STATUS_INVALID_PARAMETER; } @@ -137,7 +136,7 @@ static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, struct smb_chkpath *cp) { char *unix_path; struct stat st; @@ -170,7 +169,7 @@ static uint64_t svfs_file_id(struct stat *st) approximately map a struct stat to a generic fileinfo struct */ static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info, + struct ntvfs_request *req, union smb_fileinfo *info, struct stat *st, const char *unix_path) { struct svfs_dir *dir = NULL; @@ -246,14 +245,14 @@ static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, return info on a pathname */ static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { char *unix_path; struct stat st; DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level)); if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qpathinfo(req, info, ntvfs); + return ntvfs_map_qpathinfo(ntvfs, req, info); } unix_path = svfs_unix_path(ntvfs, req, info->generic.in.fname); @@ -270,14 +269,14 @@ static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, query info on a open file */ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; struct stat st; if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qfileinfo(req, info, ntvfs); + return ntvfs_map_qfileinfo(ntvfs, req, info); } f = find_fd(private, info->generic.in.fnum); @@ -297,7 +296,7 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, open a file */ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) + struct ntvfs_request *req, union smb_open *io) { struct svfs_private *private = ntvfs->private_data; char *unix_path; @@ -307,7 +306,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, int create_flags, rdwr_flags; if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(req, io, ntvfs); + return ntvfs_map_open(ntvfs, req, io); } if (lp_readonly(req->tcon->service)) { @@ -400,7 +399,7 @@ do_open: create a directory */ static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { char *unix_path; @@ -423,7 +422,7 @@ static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, remove a directory */ static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, struct smb_rmdir *rd) { char *unix_path; @@ -442,7 +441,7 @@ static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, rename a set of files */ static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { char *unix_path1, *unix_path2; @@ -466,7 +465,7 @@ static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, copy a set of files */ static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) + struct ntvfs_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -475,7 +474,7 @@ static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, read from a file */ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) + struct ntvfs_request *req, union smb_read *rd) { ssize_t ret; @@ -502,12 +501,12 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, write to a file */ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) + struct ntvfs_request *req, union smb_write *wr) { ssize_t ret; if (wr->generic.level != RAW_WRITE_WRITEX) { - return ntvfs_map_write(req, wr, ntvfs); + return ntvfs_map_write(ntvfs, req, wr); } CHECK_READ_ONLY(req); @@ -530,7 +529,7 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, seek in a file */ static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct ntvfs_request *req, struct smb_seek *io) { return NT_STATUS_NOT_SUPPORTED; } @@ -539,7 +538,7 @@ static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) + struct ntvfs_request *req, struct smb_flush *io) { fsync(io->in.fnum); return NT_STATUS_OK; @@ -549,7 +548,7 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, close a file */ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) + struct ntvfs_request *req, union smb_close *io) { struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; @@ -579,7 +578,7 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, exit - closing files */ static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { return NT_STATUS_NOT_SUPPORTED; } @@ -588,7 +587,7 @@ static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, logoff - closing files */ static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { return NT_STATUS_NOT_SUPPORTED; } @@ -597,7 +596,7 @@ static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, setup for an async call */ static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, void *private) { return NT_STATUS_OK; @@ -606,7 +605,7 @@ static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, /* cancel an async call */ -static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_request *req) +static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { return NT_STATUS_UNSUCCESSFUL; } @@ -615,7 +614,7 @@ static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct smbsrv_re lock a byte range */ static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) + struct ntvfs_request *req, union smb_lock *lck) { DEBUG(0,("REWRITE: not doing byte range locking!\n")); return NT_STATUS_OK; @@ -625,7 +624,7 @@ static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, set info on a pathname */ static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) + struct ntvfs_request *req, union smb_setfileinfo *st) { CHECK_READ_ONLY(req); @@ -636,7 +635,7 @@ static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, set info on a open file */ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, union smb_setfileinfo *info) { struct utimbuf unix_times; @@ -684,13 +683,13 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, return filesystem space info */ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) + struct ntvfs_request *req, union smb_fsinfo *fs) { struct svfs_private *private = ntvfs->private_data; struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { - return ntvfs_map_fsinfo(req, fs, ntvfs); + return ntvfs_map_fsinfo(ntvfs, req, fs); } if (sys_fsusage(private->connectpath, @@ -726,13 +725,13 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, return filesystem attribute info */ static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsattr *fs) + struct ntvfs_request *req, union smb_fsattr *fs) { struct stat st; struct svfs_private *private = ntvfs->private_data; if (fs->generic.level != RAW_FSATTR_GENERIC) { - return ntvfs_map_fsattr(req, fs, ntvfs); + return ntvfs_map_fsattr(ntvfs, req, fs); } if (stat(private->connectpath, &st) == -1) { @@ -758,7 +757,7 @@ static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, return print queue info */ static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) + struct ntvfs_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -767,7 +766,7 @@ static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, list files in a directory matching a wildcard pattern */ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, + struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -837,7 +836,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, /* continue a search */ static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, + struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -925,7 +924,7 @@ found: /* close a search */ static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) + struct ntvfs_request *req, union smb_search_close *io) { struct svfs_private *private = ntvfs->private_data; struct search_state *search; @@ -947,7 +946,7 @@ static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, /* SMBtrans - not used on file shares */ static NTSTATUS svfs_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } @@ -970,7 +969,7 @@ NTSTATUS ntvfs_simple_init(void) ops.chkpath = svfs_chkpath; ops.qpathinfo = svfs_qpathinfo; ops.setpathinfo = svfs_setpathinfo; - ops.openfile = svfs_open; + ops.open = svfs_open; ops.mkdir = svfs_mkdir; ops.rmdir = svfs_rmdir; ops.rename = svfs_rename; diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index df627bd2d1..3b36a6a891 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -96,7 +96,7 @@ static NTSTATUS set_unix_security(struct unix_sec_ctx *sec) form a unix_sec_ctx from the current security_token */ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, struct security_token *token, struct unix_sec_ctx **sec) { @@ -143,7 +143,7 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, setup our unix security context according to the session authentication info */ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct unix_sec_ctx **sec) + struct ntvfs_request *req, struct unix_sec_ctx **sec) { struct unixuid_private *private = ntvfs->private_data; struct security_token *token; @@ -202,7 +202,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, const char *sharename) + struct ntvfs_request *req, const char *sharename) { struct unixuid_private *private; NTSTATUS status; @@ -232,8 +232,7 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs, - struct smbsrv_tcon *tcon) +static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs) { struct unixuid_private *private = ntvfs->private_data; NTSTATUS status; @@ -241,7 +240,7 @@ static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs, talloc_free(private); ntvfs->private_data = NULL; - status = ntvfs_next_disconnect(ntvfs, tcon); + status = ntvfs_next_disconnect(ntvfs); return status; } @@ -251,7 +250,7 @@ static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs, delete a file */ static NTSTATUS unixuid_unlink(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, struct smb_unlink *unl) { NTSTATUS status; @@ -264,7 +263,7 @@ static NTSTATUS unixuid_unlink(struct ntvfs_module_context *ntvfs, ioctl interface */ static NTSTATUS unixuid_ioctl(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { NTSTATUS status; @@ -277,7 +276,7 @@ static NTSTATUS unixuid_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS unixuid_chkpath(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, struct smb_chkpath *cp) { NTSTATUS status; @@ -290,7 +289,7 @@ static NTSTATUS unixuid_chkpath(struct ntvfs_module_context *ntvfs, return info on a pathname */ static NTSTATUS unixuid_qpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { NTSTATUS status; @@ -303,7 +302,7 @@ static NTSTATUS unixuid_qpathinfo(struct ntvfs_module_context *ntvfs, query info on a open file */ static NTSTATUS unixuid_qfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { NTSTATUS status; @@ -317,7 +316,7 @@ static NTSTATUS unixuid_qfileinfo(struct ntvfs_module_context *ntvfs, set info on a pathname */ static NTSTATUS unixuid_setpathinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_setfileinfo *st) + struct ntvfs_request *req, union smb_setfileinfo *st) { NTSTATUS status; @@ -329,12 +328,12 @@ static NTSTATUS unixuid_setpathinfo(struct ntvfs_module_context *ntvfs, /* open a file */ -static NTSTATUS unixuid_openfile(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_open *io) +static NTSTATUS unixuid_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io) { NTSTATUS status; - PASS_THRU_REQ(ntvfs, req, openfile, (ntvfs, req, io)); + PASS_THRU_REQ(ntvfs, req, open, (ntvfs, req, io)); return status; } @@ -343,7 +342,7 @@ static NTSTATUS unixuid_openfile(struct ntvfs_module_context *ntvfs, create a directory */ static NTSTATUS unixuid_mkdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { NTSTATUS status; @@ -356,7 +355,7 @@ static NTSTATUS unixuid_mkdir(struct ntvfs_module_context *ntvfs, remove a directory */ static NTSTATUS unixuid_rmdir(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, struct smb_rmdir *rd) { NTSTATUS status; @@ -369,7 +368,7 @@ static NTSTATUS unixuid_rmdir(struct ntvfs_module_context *ntvfs, rename a set of files */ static NTSTATUS unixuid_rename(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { NTSTATUS status; @@ -382,7 +381,7 @@ static NTSTATUS unixuid_rename(struct ntvfs_module_context *ntvfs, copy a set of files */ static NTSTATUS unixuid_copy(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_copy *cp) + struct ntvfs_request *req, struct smb_copy *cp) { NTSTATUS status; @@ -395,7 +394,7 @@ static NTSTATUS unixuid_copy(struct ntvfs_module_context *ntvfs, read from a file */ static NTSTATUS unixuid_read(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_read *rd) + struct ntvfs_request *req, union smb_read *rd) { NTSTATUS status; @@ -408,7 +407,7 @@ static NTSTATUS unixuid_read(struct ntvfs_module_context *ntvfs, write to a file */ static NTSTATUS unixuid_write(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_write *wr) + struct ntvfs_request *req, union smb_write *wr) { NTSTATUS status; @@ -421,7 +420,7 @@ static NTSTATUS unixuid_write(struct ntvfs_module_context *ntvfs, seek in a file */ static NTSTATUS unixuid_seek(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_seek *io) + struct ntvfs_request *req, struct smb_seek *io) { NTSTATUS status; @@ -434,7 +433,7 @@ static NTSTATUS unixuid_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS unixuid_flush(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_flush *io) + struct ntvfs_request *req, struct smb_flush *io) { NTSTATUS status; @@ -447,7 +446,7 @@ static NTSTATUS unixuid_flush(struct ntvfs_module_context *ntvfs, close a file */ static NTSTATUS unixuid_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_close *io) + struct ntvfs_request *req, union smb_close *io) { NTSTATUS status; @@ -460,7 +459,7 @@ static NTSTATUS unixuid_close(struct ntvfs_module_context *ntvfs, exit - closing files */ static NTSTATUS unixuid_exit(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { NTSTATUS status; @@ -473,7 +472,7 @@ static NTSTATUS unixuid_exit(struct ntvfs_module_context *ntvfs, logoff - closing files */ static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { struct unixuid_private *private = ntvfs->private_data; NTSTATUS status; @@ -489,7 +488,7 @@ static NTSTATUS unixuid_logoff(struct ntvfs_module_context *ntvfs, async setup */ static NTSTATUS unixuid_async_setup(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, void *private) { NTSTATUS status; @@ -503,7 +502,7 @@ static NTSTATUS unixuid_async_setup(struct ntvfs_module_context *ntvfs, cancel an async request */ static NTSTATUS unixuid_cancel(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req) + struct ntvfs_request *req) { NTSTATUS status; @@ -516,7 +515,7 @@ static NTSTATUS unixuid_cancel(struct ntvfs_module_context *ntvfs, lock a byte range */ static NTSTATUS unixuid_lock(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lock *lck) + struct ntvfs_request *req, union smb_lock *lck) { NTSTATUS status; @@ -529,7 +528,7 @@ static NTSTATUS unixuid_lock(struct ntvfs_module_context *ntvfs, set info on a open file */ static NTSTATUS unixuid_setfileinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, + struct ntvfs_request *req, union smb_setfileinfo *info) { NTSTATUS status; @@ -544,7 +543,7 @@ static NTSTATUS unixuid_setfileinfo(struct ntvfs_module_context *ntvfs, return filesystem space info */ static NTSTATUS unixuid_fsinfo(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_fsinfo *fs) + struct ntvfs_request *req, union smb_fsinfo *fs) { NTSTATUS status; @@ -557,7 +556,7 @@ static NTSTATUS unixuid_fsinfo(struct ntvfs_module_context *ntvfs, return print queue info */ static NTSTATUS unixuid_lpq(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_lpq *lpq) + struct ntvfs_request *req, union smb_lpq *lpq) { NTSTATUS status; @@ -570,7 +569,7 @@ static NTSTATUS unixuid_lpq(struct ntvfs_module_context *ntvfs, list files in a directory matching a wildcard pattern */ static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_first *io, + struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -583,7 +582,7 @@ static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs, /* continue a search */ static NTSTATUS unixuid_search_next(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_next *io, + struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { @@ -596,7 +595,7 @@ static NTSTATUS unixuid_search_next(struct ntvfs_module_context *ntvfs, /* close a search */ static NTSTATUS unixuid_search_close(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, union smb_search_close *io) + struct ntvfs_request *req, union smb_search_close *io) { NTSTATUS status; @@ -607,7 +606,7 @@ static NTSTATUS unixuid_search_close(struct ntvfs_module_context *ntvfs, /* SMBtrans - not used on file shares */ static NTSTATUS unixuid_trans(struct ntvfs_module_context *ntvfs, - struct smbsrv_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, struct smb_trans2 *trans2) { NTSTATUS status; @@ -633,7 +632,7 @@ NTSTATUS ntvfs_unixuid_init(void) ops.chkpath = unixuid_chkpath; ops.qpathinfo = unixuid_qpathinfo; ops.setpathinfo = unixuid_setpathinfo; - ops.openfile = unixuid_openfile; + ops.open = unixuid_open; ops.mkdir = unixuid_mkdir; ops.rmdir = unixuid_rmdir; ops.rename = unixuid_rename; -- cgit From 307e43bb5628e8b53a930c2928279af994281ba5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Mar 2006 20:49:20 +0000 Subject: r14173: change smb interface structures to always use a union smb_file, to abtract - const char *path fot qpathinfo and setpathinfo - uint16_t fnum for SMB - smb2_handle handle for SMB2 the idea is to later add a struct ntvfs_handle *ntvfs so that the ntvfs subsystem don't need to know the difference between SMB and SMB2 metze (This used to be commit 2ef3f5970901b5accdb50f0d0115b5d46b0c788f) --- source4/ntvfs/cifs/vfs_cifs.c | 19 ++++++++------ source4/ntvfs/ipc/vfs_ipc.c | 22 ++++++++++------- source4/ntvfs/nbench/vfs_nbench.c | 44 ++++++++++++++++++--------------- source4/ntvfs/ntvfs.h | 10 ++++---- source4/ntvfs/ntvfs_generic.c | 48 ++++++++++++++++++------------------ source4/ntvfs/ntvfs_interface.c | 20 +++++++-------- source4/ntvfs/posix/pvfs_acl.c | 2 +- source4/ntvfs/posix/pvfs_flush.c | 7 +++--- source4/ntvfs/posix/pvfs_ioctl.c | 5 ++-- source4/ntvfs/posix/pvfs_lock.c | 4 +-- source4/ntvfs/posix/pvfs_open.c | 10 ++++---- source4/ntvfs/posix/pvfs_qfileinfo.c | 4 +-- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_seek.c | 15 +++++------ source4/ntvfs/posix/pvfs_unlink.c | 11 +++++---- source4/ntvfs/posix/pvfs_write.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 5 ++-- source4/ntvfs/print/vfs_print.c | 3 ++- source4/ntvfs/simple/vfs_simple.c | 39 ++++++++++++++++------------- source4/ntvfs/unixuid/vfs_unixuid.c | 12 ++++++--- 20 files changed, 156 insertions(+), 128 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index f6a8da14e7..2741e97d2d 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -237,7 +237,7 @@ static void async_simple(struct smbcli_request *c_req) The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, union smb_unlink *unl) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -292,7 +292,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, union smb_chkpath *cp) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -583,7 +583,8 @@ static void async_seek(struct smbcli_request *c_req) seek in a file */ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_seek *io) + struct ntvfs_request *req, + union smb_seek *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -603,7 +604,8 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_flush *io) + struct ntvfs_request *req, + union smb_flush *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -844,7 +846,8 @@ static void async_trans2(struct smbcli_request *c_req) /* raw trans2 */ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, + struct smb_trans2 *trans2) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -863,7 +866,8 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, /* SMBtrans - not used on file shares */ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_trans2 *trans2) + struct ntvfs_request *req, + struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; } @@ -881,7 +885,8 @@ static void async_changenotify(struct smbcli_request *c_req) /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_notify *info) + struct ntvfs_request *req, + union smb_notify *info) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 36f0c9b82c..2df7ac61ab 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -117,7 +117,8 @@ static NTSTATUS ipc_disconnect(struct ntvfs_module_context *ntvfs) delete a file */ static NTSTATUS ipc_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + union smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } @@ -136,7 +137,8 @@ static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS ipc_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, + union smb_chkpath *cp) { return NT_STATUS_ACCESS_DENIED; } @@ -263,7 +265,7 @@ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs, } ZERO_STRUCT(oi->ntcreatex.out); - oi->ntcreatex.out.fnum = p->fnum; + oi->ntcreatex.file.fnum = p->fnum; oi->ntcreatex.out.ipc_state = p->ipc_state; oi->ntcreatex.out.file_type = FILE_TYPE_MESSAGE_MODE_PIPE; @@ -286,7 +288,7 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, } ZERO_STRUCT(oi->openx.out); - oi->openx.out.fnum = p->fnum; + oi->openx.file.fnum = p->fnum; oi->openx.out.ftype = 2; oi->openx.out.devstate = p->ipc_state; @@ -380,7 +382,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(ntvfs, req, rd); } - fnum = rd->readx.in.fnum; + fnum = rd->readx.file.fnum; p = pipe_state_find(private, fnum); if (!p) { @@ -423,7 +425,7 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(ntvfs, req, wr); } - fnum = wr->writex.in.fnum; + fnum = wr->writex.file.fnum; data.data = discard_const_p(void, wr->writex.in.data); data.length = wr->writex.in.count; @@ -447,7 +449,8 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, seek in a file */ static NTSTATUS ipc_seek(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_seek *io) + struct ntvfs_request *req, + union smb_seek *io) { return NT_STATUS_ACCESS_DENIED; } @@ -456,7 +459,8 @@ static NTSTATUS ipc_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS ipc_flush(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_flush *io) + struct ntvfs_request *req, + union smb_flush *io) { return NT_STATUS_ACCESS_DENIED; } @@ -474,7 +478,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(ntvfs, req, io); } - p = pipe_state_find(private, io->close.in.fnum); + p = pipe_state_find(private, io->close.file.fnum); if (!p) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 9647666360..b6bce60b08 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -141,17 +141,18 @@ static NTSTATUS nbench_disconnect(struct ntvfs_module_context *ntvfs) */ static void nbench_unlink_send(struct ntvfs_request *req) { - struct smb_unlink *unl = req->async_states->private_data; + union smb_unlink *unl = req->async_states->private_data; nbench_log(req, "Unlink \"%s\" 0x%x %s\n", - unl->in.pattern, unl->in.attrib, + unl->unlink.in.pattern, unl->unlink.in.attrib, get_nt_error_c_code(req->async_states->status)); PASS_THRU_REP_POST(req); } static NTSTATUS nbench_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + union smb_unlink *unl) { NTSTATUS status; @@ -185,17 +186,18 @@ static NTSTATUS nbench_ioctl(struct ntvfs_module_context *ntvfs, */ static void nbench_chkpath_send(struct ntvfs_request *req) { - struct smb_chkpath *cp = req->async_states->private_data; + union smb_chkpath *cp = req->async_states->private_data; nbench_log(req, "Chkpath \"%s\" %s\n", - cp->in.path, + cp->chkpath.in.path, get_nt_error_c_code(req->async_states->status)); PASS_THRU_REP_POST(req); } static NTSTATUS nbench_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, + union smb_chkpath *cp) { NTSTATUS status; @@ -212,7 +214,7 @@ static void nbench_qpathinfo_send(struct ntvfs_request *req) union smb_fileinfo *info = req->async_states->private_data; nbench_log(req, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", - info->generic.in.fname, + info->generic.file.path, info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -237,7 +239,7 @@ static void nbench_qfileinfo_send(struct ntvfs_request *req) union smb_fileinfo *info = req->async_states->private_data; nbench_log(req, "QUERY_FILE_INFORMATION %d %d %s\n", - info->generic.in.fnum, + info->generic.file.fnum, info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -262,7 +264,7 @@ static void nbench_setpathinfo_send(struct ntvfs_request *req) union smb_setfileinfo *st = req->async_states->private_data; nbench_log(req, "SET_PATH_INFORMATION \"%s\" %d %s\n", - st->generic.file.fname, + st->generic.file.path, st->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -295,7 +297,7 @@ static void nbench_open_send(struct ntvfs_request *req) io->ntcreatex.in.fname, io->ntcreatex.in.create_options, io->ntcreatex.in.open_disposition, - io->ntcreatex.out.fnum, + io->ntcreatex.file.fnum, get_nt_error_c_code(req->async_states->status)); break; @@ -429,7 +431,7 @@ static void nbench_read_send(struct ntvfs_request *req) ZERO_STRUCT(rd->readx.out); } nbench_log(req, "ReadX %d %d %d %d %s\n", - rd->readx.in.fnum, + rd->readx.file.fnum, (int)rd->readx.in.offset, rd->readx.in.maxcnt, rd->readx.out.nread, @@ -467,7 +469,7 @@ static void nbench_write_send(struct ntvfs_request *req) ZERO_STRUCT(wr->writex.out); } nbench_log(req, "WriteX %d %d %d %d %s\n", - wr->writex.in.fnum, + wr->writex.file.fnum, (int)wr->writex.in.offset, wr->writex.in.count, wr->writex.out.nwritten, @@ -479,7 +481,7 @@ static void nbench_write_send(struct ntvfs_request *req) ZERO_STRUCT(wr->write.out); } nbench_log(req, "Write %d %d %d %d %s\n", - wr->write.in.fnum, + wr->write.file.fnum, wr->write.in.offset, wr->write.in.count, wr->write.out.nwritten, @@ -516,7 +518,8 @@ static void nbench_seek_send(struct ntvfs_request *req) } static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_seek *io) + struct ntvfs_request *req, + union smb_seek *io) { NTSTATUS status; @@ -530,17 +533,18 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, */ static void nbench_flush_send(struct ntvfs_request *req) { - struct smb_flush *io = req->async_states->private_data; + union smb_flush *io = req->async_states->private_data; nbench_log(req, "Flush %d %s\n", - io->in.fnum, + io->flush.file.fnum, get_nt_error_c_code(req->async_states->status)); PASS_THRU_REP_POST(req); } static NTSTATUS nbench_flush(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_flush *io) + struct ntvfs_request *req, + union smb_flush *io) { NTSTATUS status; @@ -559,7 +563,7 @@ static void nbench_close_send(struct ntvfs_request *req) switch (io->generic.level) { case RAW_CLOSE_CLOSE: nbench_log(req, "Close %d %s\n", - io->close.in.fnum, + io->close.file.fnum, get_nt_error_c_code(req->async_states->status)); break; @@ -674,14 +678,14 @@ static void nbench_lock_send(struct ntvfs_request *req) lck->lockx.in.lock_cnt == 1 && lck->lockx.in.ulock_cnt == 0) { nbench_log(req, "LockX %d %d %d %s\n", - lck->lockx.in.fnum, + lck->lockx.file.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); } else if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.ulock_cnt == 1) { nbench_log(req, "UnlockX %d %d %d %s\n", - lck->lockx.in.fnum, + lck->lockx.file.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 46d288c853..b9b09890f9 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -57,10 +57,10 @@ struct ntvfs_ops { /* path operations */ NTSTATUS (*unlink)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_unlink *unl); + union smb_unlink *unl); NTSTATUS (*chkpath)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_chkpath *cp); + union smb_chkpath *cp); NTSTATUS (*qpathinfo)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *st); @@ -108,10 +108,10 @@ struct ntvfs_ops { union smb_write *io); NTSTATUS (*seek)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_seek *io); + union smb_seek *io); NTSTATUS (*flush)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_flush *flush); + union smb_flush *flush); NTSTATUS (*lock)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lock *lck); @@ -138,7 +138,7 @@ struct ntvfs_ops { /* change notify request */ NTSTATUS (*notify)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info); + union smb_notify *info); /* cancel - cancels any pending async request */ NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 5133f63268..e373c7a28e 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -155,7 +155,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, switch (io->generic.level) { case RAW_OPEN_OPEN: - io->openold.out.fnum = io2->generic.out.fnum; + io->openold.file.fnum = io2->generic.file.fnum; io->openold.out.attrib = io2->generic.out.attrib; io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openold.out.size = io2->generic.out.size; @@ -163,7 +163,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, break; case RAW_OPEN_OPENX: - io->openx.out.fnum = io2->generic.out.fnum; + io->openx.file.fnum = io2->generic.file.fnum; io->openx.out.attrib = io2->generic.out.attrib; io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openx.out.size = io2->generic.out.size; @@ -183,7 +183,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, break; case RAW_OPEN_T2OPEN: - io->t2open.out.fnum = io2->generic.out.fnum; + io->t2open.file.fnum = io2->generic.file.fnum; io->t2open.out.attrib = io2->generic.out.attrib; io->t2open.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->t2open.out.size = io2->generic.out.size; @@ -196,14 +196,14 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_MKNEW: case RAW_OPEN_CREATE: - io->mknew.out.fnum = io2->generic.out.fnum; + io->mknew.file.fnum = io2->generic.file.fnum; write_time = io->mknew.in.write_time; break; case RAW_OPEN_CTEMP: - io->ctemp.out.fnum = io2->generic.out.fnum; - io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + - strlen(io->ctemp.in.directory) + 1); + io->ctemp.file.fnum = io2->generic.file.fnum; + io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + + strlen(io->ctemp.in.directory) + 1); NT_STATUS_HAVE_NO_MEMORY(io->ctemp.out.name); break; @@ -220,7 +220,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, sf = talloc(req, union smb_setfileinfo); NT_STATUS_HAVE_NO_MEMORY(sf); sf->generic.level = RAW_SFILEINFO_STANDARD; - sf->generic.file.fnum = io2->generic.out.fnum; + sf->generic.file.fnum = io2->generic.file.fnum; sf->standard.in.create_time = 0; sf->standard.in.write_time = write_time; sf->standard.in.access_time = 0; @@ -231,7 +231,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, sf = talloc(req, union smb_setfileinfo); NT_STATUS_HAVE_NO_MEMORY(sf); sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; - sf->generic.file.fnum = io2->generic.out.fnum; + sf->generic.file.fnum = io2->generic.file.fnum; sf->end_of_file_info.in.size = set_size; status = ntvfs->ops->setfileinfo(ntvfs, req, sf); if (NT_STATUS_IS_OK(status)) { @@ -861,7 +861,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs, /* ask the backend for the generic info */ info2->generic.level = RAW_FILEINFO_GENERIC; - info2->generic.in.fnum = info->generic.in.fnum; + info2->generic.file.fnum = info->generic.file.fnum; /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; @@ -894,7 +894,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs, /* ask the backend for the generic info */ info2->generic.level = RAW_FILEINFO_GENERIC; - info2->generic.in.fname = info->generic.in.fname; + info2->generic.file.path = info->generic.file.path; /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; @@ -943,7 +943,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, } lck2->generic.level = RAW_LOCK_GENERIC; - lck2->generic.in.fnum = lck->lock.in.fnum; + lck2->generic.file.fnum = lck->lock.file.fnum; lck2->generic.in.mode = 0; lck2->generic.in.timeout = 0; lck2->generic.in.locks = locks; @@ -991,7 +991,7 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, } lck->unlock.level = RAW_LOCK_UNLOCK; - lck->unlock.in.fnum = wr->writeunlock.in.fnum; + lck->unlock.file.fnum = wr->writeunlock.file.fnum; lck->unlock.in.count = wr->writeunlock.in.count; lck->unlock.in.offset = wr->writeunlock.in.offset; @@ -1013,7 +1013,7 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, } cl->close.level = RAW_CLOSE_CLOSE; - cl->close.in.fnum = wr->writeclose.in.fnum; + cl->close.file.fnum = wr->writeclose.file.fnum; cl->close.in.write_time = wr->writeclose.in.mtime; if (wr2->generic.in.count != 0) { @@ -1064,7 +1064,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITE: - wr2->writex.in.fnum = wr->write.in.fnum; + wr2->writex.file.fnum = wr->write.file.fnum; wr2->writex.in.offset = wr->write.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = wr->write.in.remaining; @@ -1074,7 +1074,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITEUNLOCK: - wr2->writex.in.fnum = wr->writeunlock.in.fnum; + wr2->writex.file.fnum = wr->writeunlock.file.fnum; wr2->writex.in.offset = wr->writeunlock.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = wr->writeunlock.in.remaining; @@ -1084,7 +1084,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITECLOSE: - wr2->writex.in.fnum = wr->writeclose.in.fnum; + wr2->writex.file.fnum = wr->writeclose.file.fnum; wr2->writex.in.offset = wr->writeclose.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = 0; @@ -1094,7 +1094,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_SPLWRITE: - wr2->writex.in.fnum = wr->splwrite.in.fnum; + wr2->writex.file.fnum = wr->splwrite.file.fnum; wr2->writex.in.offset = 0; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = 0; @@ -1165,7 +1165,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, break; case RAW_READ_READ: - rd2->readx.in.fnum = rd->read.in.fnum; + rd2->readx.file.fnum = rd->read.file.fnum; rd2->readx.in.offset = rd->read.in.offset; rd2->readx.in.mincnt = rd->read.in.count; rd2->readx.in.maxcnt = rd->read.in.count; @@ -1175,7 +1175,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, break; case RAW_READ_READBRAW: - rd2->readx.in.fnum = rd->readbraw.in.fnum; + rd2->readx.file.fnum = rd->readbraw.file.fnum; rd2->readx.in.offset = rd->readbraw.in.offset; rd2->readx.in.mincnt = rd->readbraw.in.mincnt; rd2->readx.in.maxcnt = rd->readbraw.in.maxcnt; @@ -1195,13 +1195,13 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, goto done; } lck->lock.level = RAW_LOCK_LOCK; - lck->lock.in.fnum = rd->lockread.in.fnum; + lck->lock.file.fnum = rd->lockread.file.fnum; lck->lock.in.count = rd->lockread.in.count; lck->lock.in.offset = rd->lockread.in.offset; status = ntvfs->ops->lock(ntvfs, req, lck); req->async_states->state = state; - rd2->readx.in.fnum = rd->lockread.in.fnum; + rd2->readx.file.fnum = rd->lockread.file.fnum; rd2->readx.in.offset = rd->lockread.in.offset; rd2->readx.in.mincnt = rd->lockread.in.count; rd2->readx.in.maxcnt = rd->lockread.in.count; @@ -1238,8 +1238,8 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; case RAW_CLOSE_SPLCLOSE: - cl2->close.level = RAW_CLOSE_CLOSE; - cl2->close.in.fnum = cl->splclose.in.fnum; + cl2->close.level = RAW_CLOSE_CLOSE; + cl2->close.file.fnum = cl->splclose.file.fnum; break; } diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 2be3170bd8..68166e5132 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -68,7 +68,7 @@ _PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) } /* path operations */ -_PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, struct smb_unlink *unl) +_PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->unlink) { @@ -77,7 +77,7 @@ _PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, struct smb_unlink *unl return ntvfs->ops->unlink(ntvfs, req, unl); } -_PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, struct smb_chkpath *cp) +_PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->chkpath) { @@ -207,7 +207,7 @@ _PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) return ntvfs->ops->write(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, struct smb_seek *io) +_PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->seek) { @@ -217,7 +217,7 @@ _PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, struct smb_seek *io) } _PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, - struct smb_flush *flush) + union smb_flush *flush) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->flush) { @@ -314,7 +314,7 @@ _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) /* change notify request */ -_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, struct smb_notify *info) +_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) { struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; if (!ntvfs->ops->notify) { @@ -378,7 +378,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, /* path operations */ _PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_unlink *unl) + union smb_unlink *unl) { if (!ntvfs->next || !ntvfs->next->ops->unlink) { return NT_STATUS_NOT_IMPLEMENTED; @@ -388,7 +388,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, _PUBLIC_ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_chkpath *cp) + union smb_chkpath *cp) { if (!ntvfs->next || !ntvfs->next->ops->chkpath) { return NT_STATUS_NOT_IMPLEMENTED; @@ -533,7 +533,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, _PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_seek *io) + union smb_seek *io) { if (!ntvfs->next || !ntvfs->next->ops->seek) { return NT_STATUS_NOT_IMPLEMENTED; @@ -543,7 +543,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, _PUBLIC_ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_flush *flush) + union smb_flush *flush) { if (!ntvfs->next || !ntvfs->next->ops->flush) { return NT_STATUS_NOT_IMPLEMENTED; @@ -618,7 +618,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, */ _PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info) + union smb_notify *info) { if (!ntvfs->next || !ntvfs->next->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index a03499b733..246290ae91 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -310,7 +310,7 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, return NT_STATUS_INVALID_ACL; } - normalise_sd_flags(sd, info->query_secdesc.secinfo_flags); + normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags); info->query_secdesc.out.sd = sd; diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index bf6e23d520..f0ab02f96b 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -40,13 +40,14 @@ static void pvfs_flush_file(struct pvfs_state *pvfs, struct pvfs_file *f) flush a fnum */ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_flush *io) + struct ntvfs_request *req, + union smb_flush *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - if (io->in.fnum != 0xFFFF) { - f = pvfs_find_fd(pvfs, req, io->in.fnum); + if (io->flush.file.fnum != 0xFFFF) { + f = pvfs_find_fd(pvfs, req, io->flush.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index aaa9db9986..032aec1d8d 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -42,7 +42,7 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - f = pvfs_find_fd(pvfs, req, io->ntioctl.in.fnum); + f = pvfs_find_fd(pvfs, req, io->ntioctl.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } @@ -62,7 +62,8 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, ioctl interface */ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_ioctl *io) + struct ntvfs_request *req, + union smb_ioctl *io) { NTSTATUS status = NT_STATUS_UNSUCCESSFUL; diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index d2317c1852..b9b9832d51 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -243,7 +243,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request * /* check if the lock request matches exactly - you can only cancel with exact matches */ if (p->lck->lockx.in.ulock_cnt == lck->lockx.in.ulock_cnt && p->lck->lockx.in.lock_cnt == lck->lockx.in.lock_cnt && - p->lck->lockx.in.fnum == lck->lockx.in.fnum && + p->lck->lockx.file.fnum == lck->lockx.file.fnum && p->lck->lockx.in.mode == (lck->lockx.in.mode & ~LOCKING_ANDX_CANCEL_LOCK)) { int i; @@ -285,7 +285,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return ntvfs_map_lock(ntvfs, req, lck); } - f = pvfs_find_fd(pvfs, req, lck->lockx.in.fnum); + f = pvfs_find_fd(pvfs, req, lck->lockx.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 618ddf141b..fcae5f8d61 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -390,7 +390,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, talloc_steal(pvfs, f); io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.out.fnum = f->fnum; + io->generic.file.fnum = f->fnum; io->generic.out.create_action = create_action; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -712,7 +712,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } else { io->generic.out.oplock_level = OPLOCK_NONE; } - io->generic.out.fnum = f->fnum; + io->generic.file.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -880,7 +880,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, name = f->handle->name; io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.out.fnum = f->fnum; + io->generic.file.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -1239,7 +1239,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } else { io->generic.out.oplock_level = OPLOCK_NONE; } - io->generic.out.fnum = f->fnum; + io->generic.file.fnum = f->fnum; io->generic.out.create_action = stream_existed? NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; @@ -1278,7 +1278,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(ntvfs, req, io); } - f = pvfs_find_fd(pvfs, req, io->close.in.fnum); + f = pvfs_find_fd(pvfs, req, io->close.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 5d908cbee2..b01b7bb649 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -289,7 +289,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, PVFS_RESOLVE_STREAMS, &name); + status = pvfs_resolve_name(pvfs, req, info->generic.file.path, PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -326,7 +326,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; uint32_t access_needed; - f = pvfs_find_fd(pvfs, req, info->generic.in.fnum); + f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 93a8060926..15c9111d61 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -41,7 +41,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(ntvfs, req, rd); } - f = pvfs_find_fd(pvfs, req, rd->readx.in.fnum); + f = pvfs_find_fd(pvfs, req, rd->readx.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index 33656e4004..1d43f2c855 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -27,14 +27,15 @@ seek in a file */ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_seek *io) + struct ntvfs_request *req, + union smb_seek *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; struct pvfs_file_handle *h; NTSTATUS status; - f = pvfs_find_fd(pvfs, req, io->in.fnum); + f = pvfs_find_fd(pvfs, req, io->lseek.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } @@ -42,22 +43,22 @@ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, status = NT_STATUS_OK; - switch (io->in.mode) { + switch (io->lseek.in.mode) { case SEEK_MODE_START: - h->seek_offset = io->in.offset; + h->seek_offset = io->lseek.in.offset; break; case SEEK_MODE_CURRENT: - h->seek_offset += io->in.offset; + h->seek_offset += io->lseek.in.offset; break; case SEEK_MODE_END: status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); - h->seek_offset = h->name->st.st_size + io->in.offset; + h->seek_offset = h->name->st.st_size + io->lseek.in.offset; break; } - io->out.offset = h->seek_offset; + io->lseek.out.offset = h->seek_offset; return status; } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index ee90adba45..76c9bc10a4 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -113,7 +113,8 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + union smb_unlink *unl) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_dir *dir; @@ -124,7 +125,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, uint_t ofs; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, unl->in.pattern, + status = pvfs_resolve_name(pvfs, req, unl->unlink.in.pattern, PVFS_RESOLVE_WILDCARD | PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; @@ -140,7 +141,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (name->stream_name) { - return pvfs_unlink_stream(pvfs, req, name, unl->in.attrib); + return pvfs_unlink_stream(pvfs, req, name, unl->unlink.in.attrib); } /* get list of matching files */ @@ -155,13 +156,13 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, while ((fname = pvfs_list_next(dir, &ofs))) { /* this seems to be a special case */ - if ((unl->in.attrib & FILE_ATTRIBUTE_DIRECTORY) && + if ((unl->unlink.in.attrib & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0)) { return NT_STATUS_OBJECT_NAME_INVALID; } - status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->in.attrib); + status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->unlink.in.attrib); if (NT_STATUS_IS_OK(status)) { total_deleted++; } diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index d206e3b830..c16b66b7cc 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -40,7 +40,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(ntvfs, req, wr); } - f = pvfs_find_fd(pvfs, req, wr->writex.in.fnum); + f = pvfs_find_fd(pvfs, req, wr->writex.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 66fbc4bb4c..ba53dc65e0 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -203,14 +203,15 @@ static NTSTATUS pvfs_disconnect(struct ntvfs_module_context *ntvfs) check if a directory exists */ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, + union smb_chkpath *cp) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_filename *name; NTSTATUS status; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name); + status = pvfs_resolve_name(pvfs, req, cp->chkpath.in.path, 0, &name); NT_STATUS_NOT_OK_RETURN(status); if (!name->exists) { diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 1c7699566d..eb17ef9c63 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -58,7 +58,8 @@ static NTSTATUS print_disconnect(struct ntvfs_module_context *ntvfs) lots of operations are not allowed on printing shares - mostly return NT_STATUS_ACCESS_DENIED */ static NTSTATUS print_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + union smb_unlink *unl) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index be9a680d5b..add0c54291 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -106,13 +106,14 @@ static struct svfs_file *find_fd(struct svfs_private *private, int fd) The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + union smb_unlink *unl) { char *unix_path; CHECK_READ_ONLY(req); - unix_path = svfs_unix_path(ntvfs, req, unl->in.pattern); + unix_path = svfs_unix_path(ntvfs, req, unl->unlink.in.pattern); /* ignoring wildcards ... */ if (unlink(unix_path) == -1) { @@ -136,12 +137,13 @@ static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, + union smb_chkpath *cp) { char *unix_path; struct stat st; - unix_path = svfs_unix_path(ntvfs, req, cp->in.path); + unix_path = svfs_unix_path(ntvfs, req, cp->chkpath.in.path); if (stat(unix_path, &st) == -1) { return map_nt_error_from_unix(errno); @@ -250,12 +252,12 @@ static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, char *unix_path; struct stat st; - DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.fname, info->generic.level)); + DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.file.path, info->generic.level)); if (info->generic.level != RAW_FILEINFO_GENERIC) { return ntvfs_map_qpathinfo(ntvfs, req, info); } - unix_path = svfs_unix_path(ntvfs, req, info->generic.in.fname); + unix_path = svfs_unix_path(ntvfs, req, info->generic.file.path); DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); if (stat(unix_path, &st) == -1) { DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); @@ -279,12 +281,12 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, return ntvfs_map_qfileinfo(ntvfs, req, info); } - f = find_fd(private, info->generic.in.fnum); + f = find_fd(private, info->generic.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (fstat(info->generic.in.fnum, &st) == -1) { + if (fstat(info->generic.file.fnum, &st) == -1) { return map_nt_error_from_unix(errno); } @@ -386,7 +388,7 @@ do_open: unix_to_nt_time(&io->generic.out.access_time, st.st_atime); unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); - io->generic.out.fnum = fd; + io->generic.file.fnum = fd; io->generic.out.alloc_size = st.st_size; io->generic.out.size = st.st_size; io->generic.out.attrib = svfs_unix_to_dos_attrib(st.st_mode); @@ -482,7 +484,7 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } - ret = pread(rd->readx.in.fnum, + ret = pread(rd->readx.file.fnum, rd->readx.out.data, rd->readx.in.maxcnt, rd->readx.in.offset); @@ -511,7 +513,7 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, CHECK_READ_ONLY(req); - ret = pwrite(wr->writex.in.fnum, + ret = pwrite(wr->writex.file.fnum, wr->writex.in.data, wr->writex.in.count, wr->writex.in.offset); @@ -529,7 +531,8 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, seek in a file */ static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_seek *io) + struct ntvfs_request *req, + union smb_seek *io) { return NT_STATUS_NOT_SUPPORTED; } @@ -538,9 +541,10 @@ static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_flush *io) + struct ntvfs_request *req, + union smb_flush *io) { - fsync(io->in.fnum); + fsync(io->flush.file.fnum); return NT_STATUS_OK; } @@ -548,7 +552,8 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, close a file */ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_close *io) + struct ntvfs_request *req, + union smb_close *io) { struct svfs_private *private = ntvfs->private_data; struct svfs_file *f; @@ -558,12 +563,12 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; } - f = find_fd(private, io->close.in.fnum); + f = find_fd(private, io->close.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (close(io->close.in.fnum) == -1) { + if (close(io->close.file.fnum) == -1) { return map_nt_error_from_unix(errno); } diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 3b36a6a891..cc7e13fde0 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -250,7 +250,8 @@ static NTSTATUS unixuid_disconnect(struct ntvfs_module_context *ntvfs) delete a file */ static NTSTATUS unixuid_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_unlink *unl) + struct ntvfs_request *req, + union smb_unlink *unl) { NTSTATUS status; @@ -276,7 +277,8 @@ static NTSTATUS unixuid_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS unixuid_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_chkpath *cp) + struct ntvfs_request *req, + union smb_chkpath *cp) { NTSTATUS status; @@ -420,7 +422,8 @@ static NTSTATUS unixuid_write(struct ntvfs_module_context *ntvfs, seek in a file */ static NTSTATUS unixuid_seek(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_seek *io) + struct ntvfs_request *req, + union smb_seek *io) { NTSTATUS status; @@ -433,7 +436,8 @@ static NTSTATUS unixuid_seek(struct ntvfs_module_context *ntvfs, flush a file */ static NTSTATUS unixuid_flush(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_flush *io) + struct ntvfs_request *req, + union smb_flush *io) { NTSTATUS status; -- cgit From e5e10ca55ce94d371dc507b2cbb23e70440c9332 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 10 Mar 2006 21:38:07 +0000 Subject: r14174: fix typos metze (This used to be commit 29240bae4488749b3f8a2b49bccad1601d1aa184) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index db03149642..5a6643bdd4 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -435,7 +435,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, uint32_t access_needed; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, + status = pvfs_resolve_name(pvfs, req, info->generic.file.path, PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; -- cgit From 32b0bb64bcb91a3f08fcaea72b89bf6409d0e67c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 11 Mar 2006 10:25:59 +0000 Subject: r14205: move smb specific stuff out of includes.h (finally!!!:-) all this changes really help ccache to speed up the samba4 build:-) metze (This used to be commit 180a79d1036e54fc0c50572b820818e9aafa28e9) --- source4/ntvfs/ipc/ipc_rap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index bc9bc6f31e..f683082d58 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "smb.h" #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" -- cgit From 7f0c7702f6b9db216fcd6c29165b2a11ea1f24a9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Mar 2006 12:58:36 +0000 Subject: r14208: removed use of req->flags2 inside the ntvfs layer. This should help metze on his quest to unify the ntvfs strucures for the smb and smb2 servers. The only place we needed flags2 inside ntvfs was for the FLAGS2_READ_PERMIT_EXECUTE bit, which only affects readx, so I added a readx.in.read_for_execute flag instead. (This used to be commit b78abbbce60ab0009da19a72dd769800c44298a2) --- source4/ntvfs/ntvfs_generic.c | 1 + source4/ntvfs/posix/pvfs_read.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index e373c7a28e..e4bc963882 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1158,6 +1158,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, } rd2->readx.level = RAW_READ_READX; + rd2->readx.in.read_for_execute = False; switch (rd->generic.level) { case RAW_READ_READX: diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 15c9111d61..a6b7cf6dd0 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -51,7 +51,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, } mask = SEC_FILE_READ_DATA; - if (req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) { + if (rd->readx.in.read_for_execute) { mask |= SEC_FILE_EXECUTE; } if (!(f->access_mask & mask)) { -- cgit From 40fe45deaab43da3400f652f8eb74e88e1202004 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 11 Mar 2006 13:06:17 +0000 Subject: r14209: don't timeout notify requests in the cifs backend, as they are intended to wait forever (This used to be commit 7d8da6611850a7eab964f02ccb1adaa8c2a4358f) --- source4/ntvfs/cifs/vfs_cifs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2741e97d2d..9f3af57016 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -890,6 +890,7 @@ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + int saved_timeout = private->transport->options.request_timeout; SETUP_PID; @@ -897,9 +898,15 @@ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return NT_STATUS_INVALID_PARAMETER; } - + + /* we must not timeout on notify requests - they wait + forever */ + private->transport->options.request_timeout = 0; + c_req = smb_raw_changenotify_send(private->tree, info); + private->transport->options.request_timeout = saved_timeout; + ASYNC_RECV_TAIL(info, async_changenotify); } -- cgit From 33647bd841c1c74e7dc50e93379e372056ac2df1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Mar 2006 13:36:08 +0000 Subject: r14240: fix summary output (step 2) we now need to explicit enable external libraries in *.m4 files again... metze (This used to be commit ca809a7910b16a248fffddc640298bbe4cdedc01) --- source4/ntvfs/posix/config.m4 | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 7cc4f8e3df..37c2b57cf1 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -30,6 +30,7 @@ AC_CHECK_FUNC_EXT(flistxattr, $XATTR_LIBS) SMB_EXT_LIB(XATTR,[${XATTR_LIBS}],[${XATTR_CFLAGS}],[${XATTR_CPPFLAGS}],[${XATTR_LDFLAGS}]) if test x"$ac_cv_func_ext_flistxattr" = x"yes"; then AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) + SMB_EXT_LIB_ENABLE(XATTR,YES) fi AC_CHECK_HEADERS(blkid/blkid.h) @@ -38,4 +39,5 @@ AC_CHECK_FUNC_EXT(blkid_get_cache, $BLKID_LIBS) SMB_EXT_LIB(BLKID,[${BLKID_LIBS}],[${BLKID_CFLAGS}],[${BLKID_CPPFLAGS}],[${BLKID_LDFLAGS}]) if test x"$ac_cv_func_ext_blkid_get_cache" = x"yes"; then AC_DEFINE(HAVE_LIBBLKID,1,[Whether we have blkid support (e2fsprogs)]) + SMB_EXT_LIB_ENABLE(BLKID,YES) fi -- cgit From a1b295ed4823ce8d06f830b8db9a5d965c934b54 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 12 Mar 2006 22:48:25 +0000 Subject: r14256: - rename smb_file -> smb_handle - move it into the in/out substructs again - allow file.path only on smb_fileinfo/smb_setfileinfo metze (This used to be commit be6d5298a2cdb7e7c61d70471bad445645af5963) --- source4/ntvfs/ipc/vfs_ipc.c | 14 +++---- source4/ntvfs/nbench/vfs_nbench.c | 24 ++++++------ source4/ntvfs/ntvfs_generic.c | 68 +++++++++++++++++----------------- source4/ntvfs/posix/pvfs_flush.c | 4 +- source4/ntvfs/posix/pvfs_ioctl.c | 2 +- source4/ntvfs/posix/pvfs_lock.c | 4 +- source4/ntvfs/posix/pvfs_open.c | 12 +++--- source4/ntvfs/posix/pvfs_qfileinfo.c | 4 +- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_seek.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 19 +++++----- source4/ntvfs/posix/pvfs_write.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 24 ++++++------ 13 files changed, 91 insertions(+), 90 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2df7ac61ab..b652b0f530 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -265,7 +265,7 @@ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs, } ZERO_STRUCT(oi->ntcreatex.out); - oi->ntcreatex.file.fnum = p->fnum; + oi->ntcreatex.out.file.fnum = p->fnum; oi->ntcreatex.out.ipc_state = p->ipc_state; oi->ntcreatex.out.file_type = FILE_TYPE_MESSAGE_MODE_PIPE; @@ -288,9 +288,9 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, } ZERO_STRUCT(oi->openx.out); - oi->openx.file.fnum = p->fnum; - oi->openx.out.ftype = 2; - oi->openx.out.devstate = p->ipc_state; + oi->openx.out.file.fnum = p->fnum; + oi->openx.out.ftype = 2; + oi->openx.out.devstate = p->ipc_state; return status; } @@ -382,7 +382,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(ntvfs, req, rd); } - fnum = rd->readx.file.fnum; + fnum = rd->readx.in.file.fnum; p = pipe_state_find(private, fnum); if (!p) { @@ -425,7 +425,7 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(ntvfs, req, wr); } - fnum = wr->writex.file.fnum; + fnum = wr->writex.in.file.fnum; data.data = discard_const_p(void, wr->writex.in.data); data.length = wr->writex.in.count; @@ -478,7 +478,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(ntvfs, req, io); } - p = pipe_state_find(private, io->close.file.fnum); + p = pipe_state_find(private, io->close.in.file.fnum); if (!p) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index b6bce60b08..6dcf58182a 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -214,7 +214,7 @@ static void nbench_qpathinfo_send(struct ntvfs_request *req) union smb_fileinfo *info = req->async_states->private_data; nbench_log(req, "QUERY_PATH_INFORMATION \"%s\" %d %s\n", - info->generic.file.path, + info->generic.in.file.path, info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -239,7 +239,7 @@ static void nbench_qfileinfo_send(struct ntvfs_request *req) union smb_fileinfo *info = req->async_states->private_data; nbench_log(req, "QUERY_FILE_INFORMATION %d %d %s\n", - info->generic.file.fnum, + info->generic.in.file.fnum, info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -264,7 +264,7 @@ static void nbench_setpathinfo_send(struct ntvfs_request *req) union smb_setfileinfo *st = req->async_states->private_data; nbench_log(req, "SET_PATH_INFORMATION \"%s\" %d %s\n", - st->generic.file.path, + st->generic.in.file.path, st->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -297,7 +297,7 @@ static void nbench_open_send(struct ntvfs_request *req) io->ntcreatex.in.fname, io->ntcreatex.in.create_options, io->ntcreatex.in.open_disposition, - io->ntcreatex.file.fnum, + io->ntcreatex.out.file.fnum, get_nt_error_c_code(req->async_states->status)); break; @@ -431,7 +431,7 @@ static void nbench_read_send(struct ntvfs_request *req) ZERO_STRUCT(rd->readx.out); } nbench_log(req, "ReadX %d %d %d %d %s\n", - rd->readx.file.fnum, + rd->readx.in.file.fnum, (int)rd->readx.in.offset, rd->readx.in.maxcnt, rd->readx.out.nread, @@ -469,7 +469,7 @@ static void nbench_write_send(struct ntvfs_request *req) ZERO_STRUCT(wr->writex.out); } nbench_log(req, "WriteX %d %d %d %d %s\n", - wr->writex.file.fnum, + wr->writex.in.file.fnum, (int)wr->writex.in.offset, wr->writex.in.count, wr->writex.out.nwritten, @@ -481,7 +481,7 @@ static void nbench_write_send(struct ntvfs_request *req) ZERO_STRUCT(wr->write.out); } nbench_log(req, "Write %d %d %d %d %s\n", - wr->write.file.fnum, + wr->write.in.file.fnum, wr->write.in.offset, wr->write.in.count, wr->write.out.nwritten, @@ -536,7 +536,7 @@ static void nbench_flush_send(struct ntvfs_request *req) union smb_flush *io = req->async_states->private_data; nbench_log(req, "Flush %d %s\n", - io->flush.file.fnum, + io->flush.in.file.fnum, get_nt_error_c_code(req->async_states->status)); PASS_THRU_REP_POST(req); @@ -563,7 +563,7 @@ static void nbench_close_send(struct ntvfs_request *req) switch (io->generic.level) { case RAW_CLOSE_CLOSE: nbench_log(req, "Close %d %s\n", - io->close.file.fnum, + io->close.in.file.fnum, get_nt_error_c_code(req->async_states->status)); break; @@ -678,14 +678,14 @@ static void nbench_lock_send(struct ntvfs_request *req) lck->lockx.in.lock_cnt == 1 && lck->lockx.in.ulock_cnt == 0) { nbench_log(req, "LockX %d %d %d %s\n", - lck->lockx.file.fnum, + lck->lockx.in.file.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); } else if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.ulock_cnt == 1) { nbench_log(req, "UnlockX %d %d %d %s\n", - lck->lockx.file.fnum, + lck->lockx.in.file.fnum, (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); @@ -714,7 +714,7 @@ static void nbench_setfileinfo_send(struct ntvfs_request *req) union smb_setfileinfo *info = req->async_states->private_data; nbench_log(req, "SET_FILE_INFORMATION %d %d %s\n", - info->generic.file.fnum, + info->generic.in.file.fnum, info->generic.level, get_nt_error_c_code(req->async_states->status)); diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index e4bc963882..51b03606fb 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -155,7 +155,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, switch (io->generic.level) { case RAW_OPEN_OPEN: - io->openold.file.fnum = io2->generic.file.fnum; + io->openold.out.file.fnum = io2->generic.out.file.fnum; io->openold.out.attrib = io2->generic.out.attrib; io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openold.out.size = io2->generic.out.size; @@ -163,7 +163,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, break; case RAW_OPEN_OPENX: - io->openx.file.fnum = io2->generic.file.fnum; + io->openx.out.file.fnum = io2->generic.out.file.fnum; io->openx.out.attrib = io2->generic.out.attrib; io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openx.out.size = io2->generic.out.size; @@ -183,7 +183,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, break; case RAW_OPEN_T2OPEN: - io->t2open.file.fnum = io2->generic.file.fnum; + io->t2open.out.file.fnum = io2->generic.out.file.fnum; io->t2open.out.attrib = io2->generic.out.attrib; io->t2open.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->t2open.out.size = io2->generic.out.size; @@ -196,14 +196,14 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_MKNEW: case RAW_OPEN_CREATE: - io->mknew.file.fnum = io2->generic.file.fnum; - write_time = io->mknew.in.write_time; + io->mknew.out.file.fnum = io2->generic.out.file.fnum; + write_time = io->mknew.in.write_time; break; case RAW_OPEN_CTEMP: - io->ctemp.file.fnum = io2->generic.file.fnum; - io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + - strlen(io->ctemp.in.directory) + 1); + io->ctemp.out.file.fnum = io2->generic.out.file.fnum; + io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + + strlen(io->ctemp.in.directory) + 1); NT_STATUS_HAVE_NO_MEMORY(io->ctemp.out.name); break; @@ -220,7 +220,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, sf = talloc(req, union smb_setfileinfo); NT_STATUS_HAVE_NO_MEMORY(sf); sf->generic.level = RAW_SFILEINFO_STANDARD; - sf->generic.file.fnum = io2->generic.file.fnum; + sf->generic.in.file.fnum = io2->generic.out.file.fnum; sf->standard.in.create_time = 0; sf->standard.in.write_time = write_time; sf->standard.in.access_time = 0; @@ -231,7 +231,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, sf = talloc(req, union smb_setfileinfo); NT_STATUS_HAVE_NO_MEMORY(sf); sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; - sf->generic.file.fnum = io2->generic.file.fnum; + sf->generic.in.file.fnum = io2->generic.out.file.fnum; sf->end_of_file_info.in.size = set_size; status = ntvfs->ops->setfileinfo(ntvfs, req, sf); if (NT_STATUS_IS_OK(status)) { @@ -861,7 +861,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs, /* ask the backend for the generic info */ info2->generic.level = RAW_FILEINFO_GENERIC; - info2->generic.file.fnum = info->generic.file.fnum; + info2->generic.in.file.fnum = info->generic.in.file.fnum; /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; @@ -893,8 +893,8 @@ _PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs, } /* ask the backend for the generic info */ - info2->generic.level = RAW_FILEINFO_GENERIC; - info2->generic.file.path = info->generic.file.path; + info2->generic.level = RAW_FILEINFO_GENERIC; + info2->generic.in.file.path = info->generic.in.file.path; /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; @@ -943,7 +943,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, } lck2->generic.level = RAW_LOCK_GENERIC; - lck2->generic.file.fnum = lck->lock.file.fnum; + lck2->generic.in.file.fnum = lck->lock.in.file.fnum; lck2->generic.in.mode = 0; lck2->generic.in.timeout = 0; lck2->generic.in.locks = locks; @@ -990,10 +990,10 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - lck->unlock.level = RAW_LOCK_UNLOCK; - lck->unlock.file.fnum = wr->writeunlock.file.fnum; - lck->unlock.in.count = wr->writeunlock.in.count; - lck->unlock.in.offset = wr->writeunlock.in.offset; + lck->unlock.level = RAW_LOCK_UNLOCK; + lck->unlock.in.file.fnum= wr->writeunlock.in.file.fnum; + lck->unlock.in.count = wr->writeunlock.in.count; + lck->unlock.in.offset = wr->writeunlock.in.offset; if (lck->unlock.in.count != 0) { /* do the lock sync for now */ @@ -1012,9 +1012,9 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - cl->close.level = RAW_CLOSE_CLOSE; - cl->close.file.fnum = wr->writeclose.file.fnum; - cl->close.in.write_time = wr->writeclose.in.mtime; + cl->close.level = RAW_CLOSE_CLOSE; + cl->close.in.file.fnum = wr->writeclose.in.file.fnum; + cl->close.in.write_time = wr->writeclose.in.mtime; if (wr2->generic.in.count != 0) { /* do the close sync for now */ @@ -1064,7 +1064,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITE: - wr2->writex.file.fnum = wr->write.file.fnum; + wr2->writex.in.file.fnum = wr->write.in.file.fnum; wr2->writex.in.offset = wr->write.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = wr->write.in.remaining; @@ -1074,7 +1074,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITEUNLOCK: - wr2->writex.file.fnum = wr->writeunlock.file.fnum; + wr2->writex.in.file.fnum = wr->writeunlock.in.file.fnum; wr2->writex.in.offset = wr->writeunlock.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = wr->writeunlock.in.remaining; @@ -1084,7 +1084,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITECLOSE: - wr2->writex.file.fnum = wr->writeclose.file.fnum; + wr2->writex.in.file.fnum = wr->writeclose.in.file.fnum; wr2->writex.in.offset = wr->writeclose.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = 0; @@ -1094,7 +1094,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_SPLWRITE: - wr2->writex.file.fnum = wr->splwrite.file.fnum; + wr2->writex.in.file.fnum = wr->splwrite.in.file.fnum; wr2->writex.in.offset = 0; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = 0; @@ -1166,7 +1166,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, break; case RAW_READ_READ: - rd2->readx.file.fnum = rd->read.file.fnum; + rd2->readx.in.file.fnum = rd->read.in.file.fnum; rd2->readx.in.offset = rd->read.in.offset; rd2->readx.in.mincnt = rd->read.in.count; rd2->readx.in.maxcnt = rd->read.in.count; @@ -1176,7 +1176,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, break; case RAW_READ_READBRAW: - rd2->readx.file.fnum = rd->readbraw.file.fnum; + rd2->readx.in.file.fnum = rd->readbraw.in.file.fnum; rd2->readx.in.offset = rd->readbraw.in.offset; rd2->readx.in.mincnt = rd->readbraw.in.mincnt; rd2->readx.in.maxcnt = rd->readbraw.in.maxcnt; @@ -1195,14 +1195,14 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, status = NT_STATUS_NO_MEMORY; goto done; } - lck->lock.level = RAW_LOCK_LOCK; - lck->lock.file.fnum = rd->lockread.file.fnum; - lck->lock.in.count = rd->lockread.in.count; - lck->lock.in.offset = rd->lockread.in.offset; + lck->lock.level = RAW_LOCK_LOCK; + lck->lock.in.file.fnum = rd->lockread.in.file.fnum; + lck->lock.in.count = rd->lockread.in.count; + lck->lock.in.offset = rd->lockread.in.offset; status = ntvfs->ops->lock(ntvfs, req, lck); req->async_states->state = state; - rd2->readx.file.fnum = rd->lockread.file.fnum; + rd2->readx.in.file.fnum = rd->lockread.in.file.fnum; rd2->readx.in.offset = rd->lockread.in.offset; rd2->readx.in.mincnt = rd->lockread.in.count; rd2->readx.in.maxcnt = rd->lockread.in.count; @@ -1239,8 +1239,8 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; case RAW_CLOSE_SPLCLOSE: - cl2->close.level = RAW_CLOSE_CLOSE; - cl2->close.file.fnum = cl->splclose.file.fnum; + cl2->close.level = RAW_CLOSE_CLOSE; + cl2->close.in.file.fnum = cl->splclose.in.file.fnum; break; } diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index f0ab02f96b..ad87ed623b 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -46,8 +46,8 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - if (io->flush.file.fnum != 0xFFFF) { - f = pvfs_find_fd(pvfs, req, io->flush.file.fnum); + if (io->flush.in.file.fnum != 0xFFFF) { + f = pvfs_find_fd(pvfs, req, io->flush.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 032aec1d8d..829da47a12 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -42,7 +42,7 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - f = pvfs_find_fd(pvfs, req, io->ntioctl.file.fnum); + f = pvfs_find_fd(pvfs, req, io->ntioctl.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index b9b9832d51..4dbb13cb42 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -243,7 +243,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request * /* check if the lock request matches exactly - you can only cancel with exact matches */ if (p->lck->lockx.in.ulock_cnt == lck->lockx.in.ulock_cnt && p->lck->lockx.in.lock_cnt == lck->lockx.in.lock_cnt && - p->lck->lockx.file.fnum == lck->lockx.file.fnum && + p->lck->lockx.in.file.fnum == lck->lockx.in.file.fnum && p->lck->lockx.in.mode == (lck->lockx.in.mode & ~LOCKING_ANDX_CANCEL_LOCK)) { int i; @@ -285,7 +285,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return ntvfs_map_lock(ntvfs, req, lck); } - f = pvfs_find_fd(pvfs, req, lck->lockx.file.fnum); + f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index fcae5f8d61..d4b2d0b30a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -144,7 +144,7 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, if (io->ntcreatex.in.sec_desc) { union smb_setfileinfo set; - set.set_secdesc.file.fnum = fnum; + set.set_secdesc.in.file.fnum = fnum; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; @@ -390,7 +390,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, talloc_steal(pvfs, f); io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.file.fnum = f->fnum; + io->generic.out.file.fnum = f->fnum; io->generic.out.create_action = create_action; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -712,7 +712,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } else { io->generic.out.oplock_level = OPLOCK_NONE; } - io->generic.file.fnum = f->fnum; + io->generic.out.file.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -880,7 +880,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, name = f->handle->name; io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.file.fnum = f->fnum; + io->generic.out.file.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -1239,7 +1239,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } else { io->generic.out.oplock_level = OPLOCK_NONE; } - io->generic.file.fnum = f->fnum; + io->generic.out.file.fnum = f->fnum; io->generic.out.create_action = stream_existed? NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; @@ -1278,7 +1278,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(ntvfs, req, io); } - f = pvfs_find_fd(pvfs, req, io->close.file.fnum); + f = pvfs_find_fd(pvfs, req, io->close.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index b01b7bb649..c23a3c8348 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -289,7 +289,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.file.path, PVFS_RESOLVE_STREAMS, &name); + status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -326,7 +326,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; uint32_t access_needed; - f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); + f = pvfs_find_fd(pvfs, req, info->generic.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index a6b7cf6dd0..c88f49d116 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -41,7 +41,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(ntvfs, req, rd); } - f = pvfs_find_fd(pvfs, req, rd->readx.file.fnum); + f = pvfs_find_fd(pvfs, req, rd->readx.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index 1d43f2c855..dbfb4e1c3d 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -35,7 +35,7 @@ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, struct pvfs_file_handle *h; NTSTATUS status; - f = pvfs_find_fd(pvfs, req, io->lseek.file.fnum); + f = pvfs_find_fd(pvfs, req, io->lseek.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 5a6643bdd4..45edaa5b94 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -71,14 +71,14 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, struct ntvfs_request *req, struct pvfs_filename *name, - struct smb_rename_information *r) + union smb_setfileinfo *info) { NTSTATUS status; struct pvfs_filename *name2; char *new_name, *p; /* renames are only allowed within a directory */ - if (strchr_m(r->new_name, '\\')) { + if (strchr_m(info->rename_information.in.new_name, '\\')) { return NT_STATUS_NOT_SUPPORTED; } @@ -93,7 +93,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } /* w2k3 does not appear to allow relative rename */ - if (r->root_fid != 0) { + if (info->rename_information.in.root_fid != 0) { return NT_STATUS_INVALID_PARAMETER; } @@ -108,7 +108,8 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } *p = 0; - new_name = talloc_asprintf(req, "%s\\%s", new_name, r->new_name); + new_name = talloc_asprintf(req, "%s\\%s", new_name, + info->rename_information.in.new_name); if (new_name == NULL) { return NT_STATUS_NO_MEMORY; } @@ -128,7 +129,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_OK; } - if (!r->overwrite) { + if (!info->rename_information.in.overwrite) { return NT_STATUS_OBJECT_NAME_COLLISION; } @@ -249,7 +250,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; uint32_t access_needed; - f = pvfs_find_fd(pvfs, req, info->generic.file.fnum); + f = pvfs_find_fd(pvfs, req, info->generic.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } @@ -358,7 +359,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_RENAME_INFORMATION: return pvfs_setfileinfo_rename(pvfs, req, h->name, - &info->rename_information.in); + info); case RAW_SFILEINFO_SEC_DESC: return pvfs_acl_set(pvfs, req, h->name, h->fd, f->access_mask, info); @@ -435,7 +436,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, uint32_t access_needed; /* resolve the cifs name to a posix name */ - status = pvfs_resolve_name(pvfs, req, info->generic.file.path, + status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, PVFS_RESOLVE_STREAMS, &name); if (!NT_STATUS_IS_OK(status)) { return status; @@ -534,7 +535,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_RENAME_INFORMATION: return pvfs_setfileinfo_rename(pvfs, req, name, - &info->rename_information.in); + info); case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index c16b66b7cc..6930a0ba41 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -40,7 +40,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(ntvfs, req, wr); } - f = pvfs_find_fd(pvfs, req, wr->writex.file.fnum); + f = pvfs_find_fd(pvfs, req, wr->writex.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index add0c54291..fe43776dcc 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -252,12 +252,12 @@ static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, char *unix_path; struct stat st; - DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.file.path, info->generic.level)); + DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.file.path, info->generic.level)); if (info->generic.level != RAW_FILEINFO_GENERIC) { return ntvfs_map_qpathinfo(ntvfs, req, info); } - unix_path = svfs_unix_path(ntvfs, req, info->generic.file.path); + unix_path = svfs_unix_path(ntvfs, req, info->generic.in.file.path); DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); if (stat(unix_path, &st) == -1) { DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); @@ -281,12 +281,12 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, return ntvfs_map_qfileinfo(ntvfs, req, info); } - f = find_fd(private, info->generic.file.fnum); + f = find_fd(private, info->generic.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (fstat(info->generic.file.fnum, &st) == -1) { + if (fstat(info->generic.in.file.fnum, &st) == -1) { return map_nt_error_from_unix(errno); } @@ -388,7 +388,7 @@ do_open: unix_to_nt_time(&io->generic.out.access_time, st.st_atime); unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); - io->generic.file.fnum = fd; + io->generic.out.file.fnum = fd; io->generic.out.alloc_size = st.st_size; io->generic.out.size = st.st_size; io->generic.out.attrib = svfs_unix_to_dos_attrib(st.st_mode); @@ -484,7 +484,7 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } - ret = pread(rd->readx.file.fnum, + ret = pread(rd->readx.in.file.fnum, rd->readx.out.data, rd->readx.in.maxcnt, rd->readx.in.offset); @@ -513,7 +513,7 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, CHECK_READ_ONLY(req); - ret = pwrite(wr->writex.file.fnum, + ret = pwrite(wr->writex.in.file.fnum, wr->writex.in.data, wr->writex.in.count, wr->writex.in.offset); @@ -544,7 +544,7 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_flush *io) { - fsync(io->flush.file.fnum); + fsync(io->flush.in.file.fnum); return NT_STATUS_OK; } @@ -563,12 +563,12 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; } - f = find_fd(private, io->close.file.fnum); + f = find_fd(private, io->close.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (close(io->close.file.fnum) == -1) { + if (close(io->close.in.file.fnum) == -1) { return map_nt_error_from_unix(errno); } @@ -651,7 +651,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, switch (info->generic.level) { case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: - if (ftruncate(info->end_of_file_info.file.fnum, + if (ftruncate(info->end_of_file_info.in.file.fnum, info->end_of_file_info.in.size) == -1) { return map_nt_error_from_unix(errno); } @@ -659,7 +659,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_SETATTRE: unix_times.actime = info->setattre.in.access_time; unix_times.modtime = info->setattre.in.write_time; - fd = info->setattre.file.fnum; + fd = info->setattre.in.file.fnum; if (unix_times.actime == 0 && unix_times.modtime == 0) { break; -- cgit From e153a8099e9a187e6bcac6507ed4b1ddfe7cb764 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 13 Mar 2006 16:32:44 +0000 Subject: r14327: Replace MAJOR_VERSION/MINOR_VERSION/RELEASE_VERSION with two parameters: - VERSION: should contain the current version. Will be made part of the filename. - SO_VERSION: should contain the latest version that this on is compatible to. Will be used for setting the soname of the shared library. Fix sonames and use them on platforms that support them Remove symlinking code. ldconfig will take care of creating the symlinks now that we set the soname. (This used to be commit 7871b07e21c85c63d0ecac4c31b98dc112d18af5) --- source4/ntvfs/config.mk | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 4ed2bcf7c3..e365d73631 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -66,11 +66,10 @@ OBJ_FILES = \ # Start SUBSYSTEM NTVFS [LIBRARY::ntvfs] PUBLIC_HEADERS = ntvfs.h -MAJOR_VERSION = 0 -MINOR_VERSION = 0 +VERSION = 0.0.1 +SO_VERSION = 0.0.1 DESCRIPTION = Virtual File System with NTFS semantics PRIVATE_PROTO_HEADER = ntvfs_proto.h -RELEASE_VERSION = 1 OBJ_FILES = \ ntvfs_base.o \ ntvfs_generic.o \ -- cgit From e3f2414cf9e582a4e4deecc662b64a7bb2679a34 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 14 Mar 2006 15:03:25 +0000 Subject: r14380: Reduce the size of structs.h (This used to be commit 1a16a6f1dfa66499af43a6b88b3ea69a6a75f1fe) --- source4/ntvfs/ipc/vfs_ipc.c | 1 + source4/ntvfs/ntvfs.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b652b0f530..ad5c9594d5 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -29,6 +29,7 @@ #include "dlinklist.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" +#include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" #include "rpc_server/dcerpc_server.h" diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index b9b09890f9..0e15ee1542 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -213,4 +213,6 @@ struct ntvfs_critical_sizes { int sizeof_ntvfs_request; }; +struct messaging_context; + #include "ntvfs/ntvfs_proto.h" -- cgit From 3f6ede84dae170478dd1d8205e99c5f5c0921e28 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Mar 2006 11:27:40 +0000 Subject: r14440: demonstrate that the smbpid is attached to a session (vuid), so SMBexit() only closes files for the given user session and the given PID can someone check if samba3 passes this test, please? metze (This used to be commit fd291ff003ed934b2163d9ad93af9ef2dd631e11) --- source4/ntvfs/posix/pvfs_open.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index d4b2d0b30a..174cab51ec 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1330,7 +1330,8 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, for (f=pvfs->open_files;f;f=next) { next = f->next; - if (f->smbpid == req->smbpid) { + if (f->session == req->session && + f->smbpid == req->smbpid) { talloc_free(f); } } -- cgit From 2e7df84576d26bc37eb87b7e3c79fcb3fb358d68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Mar 2006 17:28:46 +0000 Subject: r14456: don't access the smbsrv_tcon inside the ntvfs modules metze (This used to be commit 5709c1c4e1a561dd9af98cfefbbbdac9b18765b7) --- source4/ntvfs/cifs/vfs_cifs.c | 37 +++++++++-------- source4/ntvfs/ipc/vfs_ipc.c | 9 ++--- source4/ntvfs/ntvfs.h | 27 ++++++++++++- source4/ntvfs/ntvfs_base.c | 26 ++++++------ source4/ntvfs/ntvfs_interface.c | 81 +++++++++++++++++++++++--------------- source4/ntvfs/posix/pvfs_dirlist.c | 2 +- source4/ntvfs/posix/pvfs_fsinfo.c | 2 +- source4/ntvfs/posix/pvfs_search.c | 2 +- source4/ntvfs/posix/pvfs_wait.c | 4 +- source4/ntvfs/posix/vfs_posix.c | 27 ++++++------- source4/ntvfs/posix/vfs_posix.h | 2 +- source4/ntvfs/print/vfs_print.c | 14 +++---- source4/ntvfs/simple/vfs_simple.c | 28 +++++++------ 13 files changed, 158 insertions(+), 103 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9f3af57016..806585f8e9 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -38,7 +38,7 @@ struct cvfs_private { struct smbcli_tree *tree; struct smbcli_transport *transport; - struct smbsrv_tcon *tcon; + struct ntvfs_module_context *ntvfs; struct async_info *pending; BOOL map_generic; }; @@ -62,9 +62,12 @@ struct async_info { static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) { struct cvfs_private *private = p_private; - + NTSTATUS status; + DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); - return req_send_oplock_break(private->tcon, fnum, level); + status = ntvfs_send_oplock_break(private->ntvfs, fnum, level); + if (!NT_STATUS_IS_OK(status)) return False; + return True; } /* @@ -73,12 +76,12 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *sharename) { - struct smbsrv_tcon *tcon = req->tcon; NTSTATUS status; struct cvfs_private *private; const char *host, *user, *pass, *domain, *remote_share; struct smb_composite_connect io; struct composite_context *creq; + int snum = ntvfs->ctx->config.snum; struct cli_credentials *credentials; BOOL machine_account; @@ -87,16 +90,16 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. */ - host = lp_parm_string(req->tcon->service, "cifs", "server"); - user = lp_parm_string(req->tcon->service, "cifs", "user"); - pass = lp_parm_string(req->tcon->service, "cifs", "password"); - domain = lp_parm_string(req->tcon->service, "cifs", "domain"); - remote_share = lp_parm_string(req->tcon->service, "cifs", "share"); + host = lp_parm_string(snum, "cifs", "server"); + user = lp_parm_string(snum, "cifs", "user"); + pass = lp_parm_string(snum, "cifs", "password"); + domain = lp_parm_string(snum, "cifs", "domain"); + remote_share = lp_parm_string(snum, "cifs", "share"); if (!remote_share) { remote_share = sharename; } - machine_account = lp_parm_bool(req->tcon->service, "cifs", "use_machine_account", False); + machine_account = lp_parm_bool(snum, "cifs", "use_machine_account", False); private = talloc_zero(ntvfs, struct cvfs_private); if (!private) { @@ -151,7 +154,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.service = remote_share; io.in.service_type = "?????"; - creq = smb_composite_connect_send(&io, private, tcon->smb_conn->connection->event.ctx); + creq = smb_composite_connect_send(&io, private, ntvfs->ctx->event_ctx); status = smb_composite_connect_recv(creq, private); NT_STATUS_NOT_OK_RETURN(status); @@ -159,15 +162,17 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, private->transport = private->tree->session->transport; SETUP_PID; - private->tcon = req->tcon; + private->ntvfs = ntvfs; + + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); - tcon->fs_type = talloc_strdup(tcon, "NTFS"); - tcon->dev_type = talloc_strdup(tcon, "A:"); - /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); - private->map_generic = lp_parm_bool(req->tcon->service, + private->map_generic = lp_parm_bool(ntvfs->ctx->config.snum, "cifs", "mapgeneric", False); return NT_STATUS_OK; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index ad5c9594d5..7a572268d4 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -79,14 +79,13 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *sharename) { NTSTATUS status; - struct smbsrv_tcon *tcon = req->tcon; struct ipc_private *private; - tcon->fs_type = talloc_strdup(tcon, "IPC"); - NT_STATUS_HAVE_NO_MEMORY(tcon->fs_type); + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "IPC"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); - tcon->dev_type = talloc_strdup(tcon, "IPC"); - NT_STATUS_HAVE_NO_MEMORY(tcon->dev_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "IPC"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); /* prepare the private state for this connection */ private = talloc(ntvfs, struct ipc_private); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 0e15ee1542..2f43f5df20 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -158,17 +158,40 @@ struct ntvfs_ops { struct ntvfs_module_context { struct ntvfs_module_context *prev, *next; - void *private_data; - const struct ntvfs_ops *ops; + struct ntvfs_context *ctx; int depth; + const struct ntvfs_ops *ops; + void *private_data; }; struct ntvfs_context { enum ntvfs_type type; + + /* the reported filesystem type */ + char *fs_type; + + /* the reported device type */ + char *dev_type; + + enum protocol_types protocol; + /* * linked list of module contexts */ struct ntvfs_module_context *modules; + + struct { + int snum; + } config; + + uint32_t server_id; + struct event_context *event_ctx; + struct messaging_context *msg_ctx; + + struct { + void *private_data; + NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level); + } oplock; }; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 7351d6b2a6..5abf449b8c 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -118,9 +118,12 @@ _PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) /* initialise a connection structure to point at a NTVFS backend */ -NTSTATUS ntvfs_init_connection(struct ntvfs_request *req, enum ntvfs_type type) +NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, int snum, enum ntvfs_type type, + enum protocol_types protocol, + struct event_context *ev, struct messaging_context *msg, + uint32_t server_id, struct ntvfs_context **_ctx) { - const char **handlers = lp_ntvfs_handler(req->tcon->service); + const char **handlers = lp_ntvfs_handler(snum); int i; struct ntvfs_context *ctx; @@ -128,19 +131,21 @@ NTSTATUS ntvfs_init_connection(struct ntvfs_request *req, enum ntvfs_type type) return NT_STATUS_INTERNAL_ERROR; } - ctx = talloc(req->tcon, struct ntvfs_context); + ctx = talloc_zero(mem_ctx, struct ntvfs_context); NT_STATUS_HAVE_NO_MEMORY(ctx); - ctx->type = type; - ctx->modules = NULL; + ctx->protocol = protocol; + ctx->type = type; + ctx->config.snum = snum; + ctx->event_ctx = ev; + ctx->msg_ctx = msg; + ctx->server_id = server_id; for (i=0; handlers[i]; i++) { struct ntvfs_module_context *ntvfs; - ntvfs = talloc(ctx, struct ntvfs_module_context); + ntvfs = talloc_zero(ctx, struct ntvfs_module_context); NT_STATUS_HAVE_NO_MEMORY(ntvfs); - - ntvfs->private_data = NULL; - + ntvfs->ctx = ctx; ntvfs->ops = ntvfs_backend_byname(handlers[i], ctx->type); if (!ntvfs->ops) { DEBUG(1,("ntvfs_init_connection: failed to find backend=%s, type=%d\n", @@ -155,8 +160,7 @@ NTSTATUS ntvfs_init_connection(struct ntvfs_request *req, enum ntvfs_type type) return NT_STATUS_INTERNAL_ERROR; } - req->tcon->ntvfs_ctx = ctx; - + *_ctx = ctx; return NT_STATUS_OK; } diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 68166e5132..0888991877 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -26,7 +26,7 @@ /* connect/disconnect */ _PUBLIC_ NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->connect) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -50,7 +50,7 @@ _PUBLIC_ NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx) a async request */ _PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->async_setup) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -60,7 +60,7 @@ _PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) /* filesystem operations */ _PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->fsinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -70,7 +70,7 @@ _PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) /* path operations */ _PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->unlink) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -79,7 +79,7 @@ _PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) _PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->chkpath) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -88,7 +88,7 @@ _PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp _PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo *st) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->qpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -97,7 +97,7 @@ _PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo _PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfileinfo *st) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->setpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -106,7 +106,7 @@ _PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfile _PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->open) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -115,7 +115,7 @@ _PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) _PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->mkdir) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -124,7 +124,7 @@ _PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) _PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->rmdir) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -133,7 +133,7 @@ _PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) _PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->rename) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -142,7 +142,7 @@ _PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->copy) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -153,7 +153,7 @@ _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private, BOOL ntvfs_callback(void *private, union smb_search_data *file)) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->search_first) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -163,7 +163,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private, BOOL ntvfs_callback(void *private, union smb_search_data *file)) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->search_next) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -172,7 +172,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_ _PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search_close *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->search_close) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -182,7 +182,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search /* operations on open files */ _PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->ioctl) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -191,7 +191,7 @@ _PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) _PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->read) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -200,7 +200,7 @@ _PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) _PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->write) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -209,7 +209,7 @@ _PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) _PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->seek) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -219,7 +219,7 @@ _PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) _PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, union smb_flush *flush) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->flush) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -228,7 +228,7 @@ _PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, _PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->lock) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -237,7 +237,7 @@ _PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) _PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo *info) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->qfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -246,7 +246,7 @@ _PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo _PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfileinfo *info) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->setfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -255,7 +255,7 @@ _PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfile _PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->close) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -265,7 +265,7 @@ _PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) /* trans interface - used by IPC backend for pipes and RAP calls */ _PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *trans) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->trans) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -275,7 +275,7 @@ _PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *tran /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ _PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *trans2) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->trans2) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -285,7 +285,7 @@ _PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *tra /* printing specific operations */ _PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->lpq) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -295,7 +295,7 @@ _PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) /* logoff - called when a vuid is closed */ _PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->logoff) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -304,7 +304,7 @@ _PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req) _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->exit) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -316,7 +316,7 @@ _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) */ _PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -328,7 +328,7 @@ _PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info */ _PUBLIC_ NTSTATUS ntvfs_cancel(struct ntvfs_request *req) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs_ctx->modules; + struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; if (!ntvfs->ops->cancel) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -666,3 +666,22 @@ _PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, } return ntvfs->next->ops->exit(ntvfs->next, req); } + +_PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs, + NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level), + void *private_data) +{ + ntvfs->oplock.handler = handler; + ntvfs->oplock.private_data = private_data; + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs, + uint16_t fnum, uint8_t level) +{ + if (!ntvfs->ctx->oplock.handler) { + return NT_STATUS_OK; + } + + return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, fnum, level); +} diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 9838072080..a61fc458b3 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -177,7 +177,7 @@ static void dcache_add(struct pvfs_dir *dir, const char *name) const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) { struct dirent *de; - enum protocol_types protocol = dir->pvfs->tcon->smb_conn->negotiate.protocol; + enum protocol_types protocol = dir->pvfs->ntvfs->ctx->protocol; /* non-wildcard searches are easy */ if (dir->no_wildcard) { diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 6b8f0504f2..553681a3d4 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -169,7 +169,7 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, case RAW_QFS_ATTRIBUTE_INFORMATION: fs->attribute_info.out.fs_attr = pvfs->fs_attribs; fs->attribute_info.out.max_file_component_length = 255; - fs->attribute_info.out.fs_type.s = req->tcon->fs_type; + fs->attribute_info.out.fs_type.s = ntvfs->ctx->fs_type; return NT_STATUS_OK; case RAW_QFS_QUOTA_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 6aa9163f1e..c74bac5a3d 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -72,7 +72,7 @@ static void pvfs_search_timer(struct event_context *ev, struct timed_event *te, */ static void pvfs_search_setup_timer(struct pvfs_search_state *search) { - struct event_context *ev = search->pvfs->tcon->smb_conn->connection->event.ctx; + struct event_context *ev = search->pvfs->ntvfs->ctx->event_ctx; talloc_free(search->te); search->te = event_add_timed(ev, search, timeval_current_ofs(search->pvfs->search_inactivity_time, 0), diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 241382ba0b..9b2f478633 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -134,8 +134,8 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, pwait->private = private; pwait->handler = fn; - pwait->msg_ctx = pvfs->tcon->smb_conn->connection->msg_ctx; - pwait->ev = req->tcon->smb_conn->connection->event.ctx; + pwait->msg_ctx = pvfs->ntvfs->ctx->msg_ctx; + pwait->ev = pvfs->ntvfs->ctx->event_ctx; pwait->msg_type = msg_type; pwait->req = talloc_reference(pwait, req); pwait->pvfs = pvfs; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ba53dc65e0..31588fdf78 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -38,7 +38,7 @@ */ static void pvfs_setup_options(struct pvfs_state *pvfs) { - int snum = pvfs->tcon->service; + int snum = pvfs->ntvfs->ctx->config.snum; const char *eadb; if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; @@ -114,23 +114,22 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *sharename) { - struct smbsrv_tcon *tcon = req->tcon; struct pvfs_state *pvfs; struct stat st; char *base_directory; NTSTATUS status; - pvfs = talloc_zero(tcon, struct pvfs_state); + pvfs = talloc_zero(ntvfs, struct pvfs_state); NT_STATUS_HAVE_NO_MEMORY(pvfs); /* for simplicity of path construction, remove any trailing slash now */ - base_directory = talloc_strdup(pvfs, lp_pathname(tcon->service)); + base_directory = talloc_strdup(pvfs, lp_pathname(ntvfs->ctx->config.snum)); NT_STATUS_HAVE_NO_MEMORY(base_directory); if (strcmp(base_directory, "/") != 0) { trim_string(base_directory, NULL, "/"); } - pvfs->tcon = tcon; + pvfs->ntvfs = ntvfs; pvfs->base_directory = base_directory; /* the directory must exist. Note that we deliberately don't @@ -141,25 +140,25 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_BAD_NETWORK_NAME; } - tcon->fs_type = talloc_strdup(tcon, "NTFS"); - NT_STATUS_HAVE_NO_MEMORY(tcon->fs_type); + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); - tcon->dev_type = talloc_strdup(tcon, "A:"); - NT_STATUS_HAVE_NO_MEMORY(tcon->dev_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); ntvfs->private_data = pvfs; pvfs->brl_context = brl_init(pvfs, - pvfs->tcon->smb_conn->connection->server_id, - pvfs->tcon->service, - pvfs->tcon->smb_conn->connection->msg_ctx); + pvfs->ntvfs->ctx->server_id, + pvfs->ntvfs->ctx->config.snum, + pvfs->ntvfs->ctx->msg_ctx); if (pvfs->brl_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } pvfs->odb_context = odb_init(pvfs, - pvfs->tcon->smb_conn->connection->server_id, - pvfs->tcon->smb_conn->connection->msg_ctx); + pvfs->ntvfs->ctx->server_id, + pvfs->ntvfs->ctx->msg_ctx); if (pvfs->odb_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index a22b55198c..84828fb3ce 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -31,7 +31,7 @@ /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ struct pvfs_state { - struct smbsrv_tcon *tcon; + struct ntvfs_module_context *ntvfs; const char *base_directory; struct GUID *base_fs_uuid; diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index eb17ef9c63..bd1615d603 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -35,13 +35,11 @@ static NTSTATUS print_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *sharename) { - struct smbsrv_tcon *tcon = req->tcon; + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); - tcon->fs_type = talloc_strdup(tcon, "NTFS"); - NT_STATUS_HAVE_NO_MEMORY(tcon->fs_type); - - tcon->dev_type = talloc_strdup(tcon, "LPT1:"); - NT_STATUS_HAVE_NO_MEMORY(tcon->dev_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "LPT1:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); return NT_STATUS_OK; } @@ -78,6 +76,8 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, } if (io->ioctl.in.request == IOCTL_QUERY_JOB_INFO) { + int snum = ntvfs->ctx->config.snum; + /* a request for the print job id of an open print job */ io->ioctl.out.blob = data_blob_talloc(req, NULL, 32); @@ -86,7 +86,7 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); push_string(p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); - push_string(p+18, lp_servicename(req->tcon->service), 13, STR_TERMINATE|STR_ASCII); + push_string(p+18, lp_servicename(snum), 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index fe43776dcc..2f5a8af8f5 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -40,7 +40,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (lp_readonly(req->tcon->service)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (lp_readonly(ntvfs->ctx->config.snum)) return NT_STATUS_ACCESS_DENIED; } while (0) /* connect to a share - used when a tree_connect operation comes @@ -52,13 +52,13 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *sharename) { struct stat st; - struct smbsrv_tcon *tcon = req->tcon; struct svfs_private *private; + int snum = ntvfs->ctx->config.snum; private = talloc(ntvfs, struct svfs_private); private->next_search_handle = 0; - private->connectpath = talloc_strdup(private, lp_pathname(tcon->service)); + private->connectpath = talloc_strdup(private, lp_pathname(snum)); private->open_files = NULL; private->search = NULL; @@ -69,8 +69,10 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_BAD_NETWORK_NAME; } - tcon->fs_type = talloc_strdup(tcon, "NTFS"); - tcon->dev_type = talloc_strdup(tcon, "A:"); + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); ntvfs->private_data = private; @@ -306,12 +308,14 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, int fd, flags; struct svfs_file *f; int create_flags, rdwr_flags; + BOOL readonly; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(ntvfs, req, io); } - if (lp_readonly(req->tcon->service)) { + readonly = lp_readonly(ntvfs->ctx->config.snum); + if (readonly) { create_flags = 0; rdwr_flags = O_RDONLY; } else { @@ -345,7 +349,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { flags = O_RDONLY | O_DIRECTORY; - if (lp_readonly(req->tcon->service)) { + if (readonly) { goto do_open; } switch (io->generic.in.open_disposition) { @@ -376,9 +380,11 @@ do_open: return map_nt_error_from_unix(errno); } - f = talloc(req->tcon, struct svfs_file); + f = talloc(ntvfs, struct svfs_file); + NT_STATUS_HAVE_NO_MEMORY(f); f->fd = fd; - f->name = talloc_strdup(req->tcon, unix_path); + f->name = talloc_strdup(f, unix_path); + NT_STATUS_HAVE_NO_MEMORY(f->name); DLIST_ADD(private->open_files, f); @@ -719,8 +725,8 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(req->tcon->service)); - fs->generic.out.fs_type = req->tcon->fs_type; + fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(ntvfs->ctx->config.snum)); + fs->generic.out.fs_type = ntvfs->ctx->fs_type; return NT_STATUS_OK; } -- cgit From 8528016978b084213ef53d66e1b6e831b1a01acc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 00:23:11 +0000 Subject: r14464: Don't include ndr_BASENAME.h files unless strictly required, instead try to include just the BASENAME.h files (containing only structs) (This used to be commit 3dd477ca5147f28a962b8437e2611a8222d706bd) --- source4/ntvfs/common/sidmap.c | 1 + source4/ntvfs/ipc/rap_server.c | 2 +- source4/ntvfs/posix/pvfs_acl.c | 2 +- source4/ntvfs/posix/pvfs_fsinfo.c | 2 +- source4/ntvfs/posix/pvfs_mkdir.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_search.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_streams.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 2 +- source4/ntvfs/posix/pvfs_xattr.c | 1 + source4/ntvfs/posix/vfs_posix.c | 2 +- source4/ntvfs/posix/vfs_posix.h | 2 +- 16 files changed, 16 insertions(+), 14 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index 70f7dea955..c22d29a723 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -28,6 +28,7 @@ #include "libcli/ldap/ldap.h" #include "db_wrap.h" #include "libcli/security/proto.h" +#include "librpc/gen_ndr/ndr_security.h" /* these are used for the fallback local uid/gid to sid mapping diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index a593999693..8ec62dff8b 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -21,7 +21,7 @@ #include "includes.h" #include "libcli/rap/rap.h" -#include "librpc/gen_ndr/ndr_srvsvc.h" +#include "librpc/gen_ndr/srvsvc.h" #include "rpc_server/common/common.h" /* At this moment these are just dummy functions, but you might get the diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 246290ae91..84ad62fcc8 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -23,7 +23,7 @@ #include "includes.h" #include "auth/auth.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_xattr.h" +#include "librpc/gen_ndr/xattr.h" #include "libcli/security/proto.h" diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 553681a3d4..72293fb746 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_xattr.h" +#include "librpc/gen_ndr/xattr.h" /* We use libblkid out of e2fsprogs to identify UUID of a volume */ #ifdef HAVE_LIBBLKID diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index fe2c5d0467..047b6f45a7 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -23,7 +23,7 @@ #include "includes.h" #include "system/dir.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/security.h" /* create a directory with EAs diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 174cab51ec..4f0615087a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -26,7 +26,7 @@ #include "system/time.h" #include "dlinklist.h" #include "messaging/messaging.h" -#include "librpc/gen_ndr/ndr_xattr.h" +#include "librpc/gen_ndr/xattr.h" /* create file handles with convenient numbers for sniffers diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index c23a3c8348..fb1b0aa3f9 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_xattr.h" +#include "librpc/gen_ndr/xattr.h" /* diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index c88f49d116..411fbd9c27 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/security.h" /* read from a file diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 81f6ef1bf7..8629ecabf2 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/security.h" /* resolve a wildcard rename pattern. This works on one component of the name diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index c74bac5a3d..7ee64887fb 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -23,7 +23,7 @@ #include "includes.h" #include "vfs_posix.h" #include "system/time.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/security.h" #include "smbd/service_stream.h" #include "lib/events/events.h" diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 45edaa5b94..4997207a8b 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -23,7 +23,7 @@ #include "includes.h" #include "vfs_posix.h" #include "system/time.h" -#include "librpc/gen_ndr/ndr_xattr.h" +#include "librpc/gen_ndr/xattr.h" /* diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 3910baadd0..159cf7470d 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_xattr.h" +#include "librpc/gen_ndr/xattr.h" /* diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 6930a0ba41..9c23b3e4fd 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/security.h" /* diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index d0894a735e..cf38d3c1cb 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -23,6 +23,7 @@ #include "includes.h" #include "vfs_posix.h" #include "util/unix_privs.h" +#include "librpc/gen_ndr/ndr_xattr.h" /* pull a xattr as a blob diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 31588fdf78..3f1c676df3 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -26,7 +26,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/ndr_security.h" +#include "librpc/gen_ndr/security.h" #include "smbd/service_stream.h" #include "lib/tdb/include/tdb.h" #include "db_wrap.h" diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 84828fb3ce..71120965c2 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -23,7 +23,7 @@ #ifndef _VFS_POSIX_H_ #define _VFS_POSIX_H_ -#include "librpc/gen_ndr/ndr_xattr.h" +#include "librpc/gen_ndr/xattr.h" #include "system/filesys.h" #include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" -- cgit From a949db7c6d4bd35df59ba066111e6566172d4814 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Mar 2006 18:46:49 +0000 Subject: r14486: remove the need of a stream_connection on a dcesrv_connection, and let the transport set callbacks for getting the own and peer socket_address metze (This used to be commit 56fac3ddbbeecb834e5c7a439df344e11fe12a7b) --- source4/ntvfs/ipc/vfs_ipc.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7a572268d4..24ee1451d6 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -32,6 +32,7 @@ #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" #include "rpc_server/dcerpc_server.h" +#include "smbd/service_stream.h" #define IPC_BASE_FNUM 0x400 @@ -41,6 +42,8 @@ struct ipc_private { struct idr_context *idtree_fnum; + struct stream_connection *stream_conn; + struct dcesrv_context *dcesrv; /* a list of open pipes */ @@ -95,6 +98,8 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, private->pipe_list = NULL; + private->stream_conn = req->smb_conn->connection; + private->idtree_fnum = idr_init(private); NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum); @@ -173,6 +178,19 @@ static int ipc_fd_destructor(void *ptr) return 0; } +static struct socket_address *ipc_get_my_addr(struct dcesrv_connection *dce_conn, TALLOC_CTX *mem_ctx) +{ + struct ipc_private *private = dce_conn->transport.private_data; + + return socket_get_my_addr(private->stream_conn->socket, mem_ctx); +} + +static struct socket_address *ipc_get_peer_addr(struct dcesrv_connection *dce_conn, TALLOC_CTX *mem_ctx) +{ + struct ipc_private *private = dce_conn->transport.private_data; + + return socket_get_peer_addr(private->stream_conn->socket, mem_ctx); +} /* open a file backend - used for MSRPC pipes @@ -227,7 +245,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p, ep_description, req->session->session_info, - srv_conn, + srv_conn->event.ctx, 0, &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { @@ -235,6 +253,11 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, return status; } + p->dce_conn->transport.private_data = private; + p->dce_conn->transport.report_output_data = NULL; + p->dce_conn->transport.get_my_addr = ipc_get_my_addr; + p->dce_conn->transport.get_peer_addr = ipc_get_peer_addr; + DLIST_ADD(private->pipe_list, p); p->smbpid = req->smbpid; -- cgit From d3087451c4ec25171ba956fe2cd4e1d0f64f7edc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 16 Mar 2006 18:54:19 +0000 Subject: r14487: split smbsrv_request into two parts, one will be moved to ntvfs_request but I don't to get the commit to large, to I'll do this tomorrow... metze (This used to be commit 10e627032d7d04f1ebf6efed248c426614f5aa6f) --- source4/ntvfs/cifs/vfs_cifs.c | 10 ++-- source4/ntvfs/ipc/vfs_ipc.c | 58 ++++++++++++----------- source4/ntvfs/ntvfs.h | 6 +++ source4/ntvfs/ntvfs_generic.c | 2 +- source4/ntvfs/ntvfs_interface.c | 93 ++++++++++++++++++++++++------------- source4/ntvfs/posix/pvfs_acl.c | 2 +- source4/ntvfs/posix/pvfs_fsinfo.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 16 +++---- source4/ntvfs/posix/pvfs_wait.c | 3 +- source4/ntvfs/posix/vfs_posix.h | 2 +- source4/ntvfs/unixuid/vfs_unixuid.c | 8 ++-- 11 files changed, 123 insertions(+), 79 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 806585f8e9..ee831de665 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -53,7 +53,7 @@ struct async_info { void *parms; }; -#define SETUP_PID private->tree->session->pid = SVAL(req->in.hdr, HDR_PID) +#define SETUP_PID private->tree->session->pid = req->smbpid /* a handler for oplock break events from the server - these need to be passed @@ -136,9 +136,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, if (!NT_STATUS_IS_OK(status)) { return status; } - } else if (req->session->session_info->credentials) { + } else if (req->session_info->credentials) { DEBUG(5, ("CIFS backend: Using delegated credentials\n")); - credentials = req->session->session_info->credentials; + credentials = req->session_info->credentials; } else { DEBUG(1,("CIFS backend: You must supply server, user and password and or have delegated credentials\n")); return NT_STATUS_INVALID_PARAMETER; @@ -698,11 +698,11 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { struct cvfs_private *private = ntvfs->private_data; + struct async_info *a; /* find the matching request */ - struct async_info *a; for (a=private->pending;a;a=a->next) { - if (SVAL(a->req->in.hdr, HDR_MID) == SVAL(req->in.hdr, HDR_MID)) { + if (a->req->smbmid == req->smbmid) { break; } } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 24ee1451d6..7b9433bcff 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -32,7 +32,6 @@ #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" #include "rpc_server/dcerpc_server.h" -#include "smbd/service_stream.h" #define IPC_BASE_FNUM 0x400 @@ -40,9 +39,9 @@ ipc$ connection. It needs to keep information about all open pipes */ struct ipc_private { - struct idr_context *idtree_fnum; + struct ntvfs_module_context *ntvfs; - struct stream_connection *stream_conn; + struct idr_context *idtree_fnum; struct dcesrv_context *dcesrv; @@ -56,22 +55,34 @@ struct ipc_private { 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; + struct auth_session_info *session_info; /* we need to remember the client pid that opened the file so SMBexit works */ uint16_t smbpid; } *pipe_list; - }; /* find a open pipe give a file descriptor */ -static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t fnum) +static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t fnum, + struct auth_session_info *session_info) { - return idr_find(private->idtree_fnum, fnum); + struct pipe_state *s; + void *p; + + p = idr_find(private->idtree_fnum, fnum); + if (!p) return NULL; + + s = talloc_get_type(p, struct pipe_state); + + if (s->session_info != session_info) { + return NULL; + } + + return s; } @@ -96,10 +107,9 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; + private->ntvfs = ntvfs; private->pipe_list = NULL; - private->stream_conn = req->smb_conn->connection; - private->idtree_fnum = idr_init(private); NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum); @@ -182,14 +192,14 @@ static struct socket_address *ipc_get_my_addr(struct dcesrv_connection *dce_conn { struct ipc_private *private = dce_conn->transport.private_data; - return socket_get_my_addr(private->stream_conn->socket, mem_ctx); + return ntvfs_get_my_addr(private->ntvfs, mem_ctx); } static struct socket_address *ipc_get_peer_addr(struct dcesrv_connection *dce_conn, TALLOC_CTX *mem_ctx) { struct ipc_private *private = dce_conn->transport.private_data; - return socket_get_peer_addr(private->stream_conn->socket, mem_ctx); + return ntvfs_get_peer_addr(private->ntvfs, mem_ctx); } /* @@ -204,11 +214,6 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, struct dcerpc_binding *ep_description; struct ipc_private *private = ntvfs->private_data; int fnum; - struct stream_connection *srv_conn = req->smb_conn->connection; - - if (!req->session || !req->session->session_info) { - return NT_STATUS_ACCESS_DENIED; - } p = talloc(req, struct pipe_state); NT_STATUS_HAVE_NO_MEMORY(p); @@ -244,8 +249,8 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, status = dcesrv_endpoint_search_connect(private->dcesrv, p, ep_description, - req->session->session_info, - srv_conn->event.ctx, + req->session_info, + ntvfs->ctx->event_ctx, 0, &p->dce_conn); if (!NT_STATUS_IS_OK(status)) { @@ -261,7 +266,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, DLIST_ADD(private->pipe_list, p); p->smbpid = req->smbpid; - p->session = req->session; + p->session_info = req->session_info; p->private = private; *ps = p; @@ -407,7 +412,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, fnum = rd->readx.in.file.fnum; - p = pipe_state_find(private, fnum); + p = pipe_state_find(private, fnum, req->session_info); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -452,7 +457,7 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, data.data = discard_const_p(void, wr->writex.in.data); data.length = wr->writex.in.count; - p = pipe_state_find(private, fnum); + p = pipe_state_find(private, fnum, req->session_info); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -501,7 +506,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(ntvfs, req, io); } - p = pipe_state_find(private, io->close.in.file.fnum); + p = pipe_state_find(private, io->close.in.file.fnum, req->session_info); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -522,7 +527,8 @@ static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs, for (p=private->pipe_list; p; p=next) { next = p->next; - if (p->smbpid == req->smbpid) { + if (p->session_info == req->session_info && + p->smbpid == req->smbpid) { talloc_free(p); } } @@ -541,7 +547,7 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, for (p=private->pipe_list; p; p=next) { next = p->next; - if (p->session == req->session) { + if (p->session_info == req->session_info) { talloc_free(p); } } @@ -671,7 +677,7 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, NTSTATUS status; /* the fnum is in setup[1] */ - p = pipe_state_find(private, trans->in.setup[1]); + p = pipe_state_find(private, trans->in.setup[1], req->session_info); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -716,7 +722,7 @@ static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, struct pipe_state *p; /* the fnum is in setup[1] */ - p = pipe_state_find(private, trans->in.setup[1]); + p = pipe_state_find(private, trans->in.setup[1], req->session_info); if (!p) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 2f43f5df20..58b95565e9 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -192,6 +192,12 @@ struct ntvfs_context { void *private_data; NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level); } oplock; + + struct { + void *private_data; + struct socket_address *(*get_my_addr)(void *private_data, TALLOC_CTX *mem_ctx); + struct socket_address *(*get_peer_addr)(void *private_data, TALLOC_CTX *mem_ctx); + } client; }; diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 51b03606fb..f74092eda0 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -534,7 +534,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs, (fs2->generic.out.blocks_free * (double)fs2->generic.out.block_size) / (bpunit * 512); /* we must return a maximum of 2G to old DOS systems, or they get very confused */ - if (bpunit > 64 && req->smb_conn->negotiate.protocol <= PROTOCOL_LANMAN2) { + if (bpunit > 64 && req->ctx->protocol <= PROTOCOL_LANMAN2) { fs->dskattr.out.blocks_per_unit = 64; fs->dskattr.out.units_total = 0xFFFF; fs->dskattr.out.units_free = 0xFFFF; diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 0888991877..f17acc9355 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -26,7 +26,7 @@ /* connect/disconnect */ _PUBLIC_ NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->connect) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -50,7 +50,7 @@ _PUBLIC_ NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx) a async request */ _PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->async_setup) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -60,7 +60,7 @@ _PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) /* filesystem operations */ _PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->fsinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -70,7 +70,7 @@ _PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) /* path operations */ _PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->unlink) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -79,7 +79,7 @@ _PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) _PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->chkpath) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -88,7 +88,7 @@ _PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp _PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo *st) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->qpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -97,7 +97,7 @@ _PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo _PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfileinfo *st) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->setpathinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -106,7 +106,7 @@ _PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfile _PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->open) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -115,7 +115,7 @@ _PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) _PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->mkdir) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -124,7 +124,7 @@ _PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) _PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->rmdir) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -133,7 +133,7 @@ _PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) _PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->rename) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -142,7 +142,7 @@ _PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->copy) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -153,7 +153,7 @@ _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private, BOOL ntvfs_callback(void *private, union smb_search_data *file)) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_first) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -163,7 +163,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private, BOOL ntvfs_callback(void *private, union smb_search_data *file)) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_next) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -172,7 +172,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_ _PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search_close *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_close) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -182,7 +182,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search /* operations on open files */ _PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->ioctl) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -191,7 +191,7 @@ _PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) _PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->read) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -200,7 +200,7 @@ _PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) _PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->write) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -209,7 +209,7 @@ _PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) _PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->seek) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -219,7 +219,7 @@ _PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) _PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, union smb_flush *flush) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->flush) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -228,7 +228,7 @@ _PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, _PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->lock) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -237,7 +237,7 @@ _PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) _PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo *info) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->qfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -246,7 +246,7 @@ _PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo _PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfileinfo *info) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->setfileinfo) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -255,7 +255,7 @@ _PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfile _PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->close) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -265,7 +265,7 @@ _PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) /* trans interface - used by IPC backend for pipes and RAP calls */ _PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *trans) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->trans) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -275,7 +275,7 @@ _PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *tran /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ _PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *trans2) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->trans2) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -285,7 +285,7 @@ _PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *tra /* printing specific operations */ _PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->lpq) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -295,7 +295,7 @@ _PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) /* logoff - called when a vuid is closed */ _PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->logoff) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -304,7 +304,7 @@ _PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req) _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->exit) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -316,7 +316,7 @@ _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) */ _PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -328,7 +328,7 @@ _PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info */ _PUBLIC_ NTSTATUS ntvfs_cancel(struct ntvfs_request *req) { - struct ntvfs_module_context *ntvfs = req->tcon->ntvfs->modules; + struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->cancel) { return NT_STATUS_NOT_IMPLEMENTED; } @@ -667,6 +667,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->exit(ntvfs->next, req); } +/* oplock helpers */ _PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs, NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level), void *private_data) @@ -685,3 +686,33 @@ _PUBLIC_ NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs, return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, fnum, level); } + +/* client connection callback */ +_PUBLIC_ NTSTATUS ntvfs_set_addr_callbacks(struct ntvfs_context *ntvfs, + struct socket_address *(*my_addr)(void *private_data, TALLOC_CTX *mem_ctx), + struct socket_address *(*peer_addr)(void *private_data, TALLOC_CTX *mem_ctx), + void *private_data) +{ + ntvfs->client.get_peer_addr = my_addr; + ntvfs->client.get_my_addr = peer_addr; + ntvfs->client.private_data = private_data; + return NT_STATUS_OK; +} + +_PUBLIC_ struct socket_address *ntvfs_get_my_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx) +{ + if (!ntvfs->ctx->client.get_my_addr) { + return NULL; + } + + return ntvfs->ctx->client.get_my_addr(ntvfs->ctx->client.private_data, mem_ctx); +} + +_PUBLIC_ struct socket_address *ntvfs_get_peer_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx) +{ + if (!ntvfs->ctx->client.get_peer_addr) { + return NULL; + } + + return ntvfs->ctx->client.get_peer_addr(ntvfs->ctx->client.private_data, mem_ctx); +} diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 84ad62fcc8..f7647ae3e4 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -362,7 +362,7 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, struct pvfs_filename *name, uint32_t *access_mask) { - struct security_token *token = req->session->session_info->security_token; + struct security_token *token = req->session_info->security_token; struct xattr_NTACL *acl; NTSTATUS status; struct security_descriptor *sd; diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 72293fb746..f86be9d29e 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -124,7 +124,7 @@ NTSTATUS pvfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->dskattr.out.units_free = (blocks_free * (double)block_size) / (bpunit * 512); /* we must return a maximum of 2G to old DOS systems, or they get very confused */ - if (bpunit > 64 && req->smb_conn->negotiate.protocol <= PROTOCOL_LANMAN2) { + if (bpunit > 64 && req->ctx->protocol <= PROTOCOL_LANMAN2) { fs->dskattr.out.blocks_per_unit = 64; fs->dskattr.out.units_total = 0xFFFF; fs->dskattr.out.units_free = 0xFFFF; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 4f0615087a..3160519f73 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -52,7 +52,7 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, smb_panic("pvfs_find_fd: idtree_fnum corruption\n"); } - if (req->session != f->session) { + if (req->session_info != f->session_info) { DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n", fnum)); return NULL; @@ -263,7 +263,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } f->fnum = fnum; - f->session = req->session; + f->session_info = req->session_info; f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; @@ -680,7 +680,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } f->fnum = fnum; - f->session = req->session; + f->session_info = req->session_info; f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; @@ -847,7 +847,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, */ for (f2=pvfs->open_files;f2;f2=f2->next) { if (f2 != f && - f2->session == req->session && + f2->session_info == req->session_info && f2->smbpid == req->smbpid && (f2->handle->create_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | @@ -936,7 +936,7 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, f->handle->odb_locking_key.data, f->handle->odb_locking_key.length); - end_time = timeval_add(&req->request_time, 0, pvfs->sharing_violation_delay); + end_time = timeval_add(&req->statistics.request_time, 0, pvfs->sharing_violation_delay); /* setup a pending lock */ status = odb_open_file_pending(lck, r); @@ -1105,7 +1105,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } f->fnum = fnum; - f->session = req->session; + f->session_info = req->session_info; f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; @@ -1310,7 +1310,7 @@ NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, for (f=pvfs->open_files;f;f=next) { next = f->next; - if (f->session == req->session) { + if (f->session_info == req->session_info) { talloc_free(f); } } @@ -1330,7 +1330,7 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, for (f=pvfs->open_files;f;f=next) { next = f->next; - if (f->session == req->session && + if (f->session_info == req->session_info && f->smbpid == req->smbpid) { talloc_free(f); } diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 9b2f478633..6cb24e1f92 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -171,8 +171,9 @@ NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *r { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_wait *pwait; + for (pwait=pvfs->wait_list;pwait;pwait=pwait->next) { - if (SVAL(req->in.hdr, HDR_MID) == SVAL(pwait->req->in.hdr, HDR_MID) && + if (req->smbmid == pwait->req->smbmid && req->smbpid == pwait->req->smbpid) { /* trigger a cancel on the request */ pwait->reason = PVFS_WAIT_CANCEL; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 71120965c2..f75e7d3563 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -159,7 +159,7 @@ struct pvfs_file { /* we need to remember the session it was opened on, as it is illegal to operate on someone elses fnum */ - struct smbsrv_session *session; + struct auth_session_info *session_info; /* we need to remember the client pid that opened the file so SMBexit works */ diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index cc7e13fde0..9f6a4f9cb7 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -150,18 +150,18 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, struct unix_sec_ctx *newsec; NTSTATUS status; - if (req->session == NULL) { + if (req->session_info == NULL) { return NT_STATUS_ACCESS_DENIED; } - token = req->session->session_info->security_token; + token = req->session_info->security_token; *sec = save_unix_security(req); if (*sec == NULL) { return NT_STATUS_NO_MEMORY; } - if (req->session->session_info->security_token == private->last_token) { + if (token == private->last_token) { newsec = private->last_sec_ctx; } else { status = nt_token_to_unix_security(ntvfs, req, token, &newsec); @@ -172,7 +172,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, talloc_free(private->last_sec_ctx); } private->last_sec_ctx = newsec; - private->last_token = req->session->session_info->security_token; + private->last_token = token; talloc_steal(private, newsec); } -- cgit From b785a7c40c185512207ef8da837a766933073032 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 16 Mar 2006 21:36:36 +0000 Subject: r14492: Fix shared libs - set SO_VERSION to 0 everywhere for now. (This used to be commit 4682bc5ce047d81586447b9df82c91ed1fe677cf) --- source4/ntvfs/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index e365d73631..3f05bfa7be 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -67,7 +67,7 @@ OBJ_FILES = \ [LIBRARY::ntvfs] PUBLIC_HEADERS = ntvfs.h VERSION = 0.0.1 -SO_VERSION = 0.0.1 +SO_VERSION = 0 DESCRIPTION = Virtual File System with NTFS semantics PRIVATE_PROTO_HEADER = ntvfs_proto.h OBJ_FILES = \ -- cgit From 9225c02aee19478fc4825c4b798a6757d140b5c0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 18 Mar 2006 09:07:47 +0000 Subject: r14539: get rid of a pointless union layer in struct smb_notify (This used to be commit 1e1c5593817e84c59c1a10b5a3c1957e363e5198) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/ntvfs_interface.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index ee831de665..50aa58d6fb 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -891,7 +891,7 @@ static void async_changenotify(struct smbcli_request *c_req) /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - union smb_notify *info) + struct smb_notify *info) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 58b95565e9..09c5b9bdcb 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -138,7 +138,7 @@ struct ntvfs_ops { /* change notify request */ NTSTATUS (*notify)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - union smb_notify *info); + struct smb_notify *info); /* cancel - cancels any pending async request */ NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index f17acc9355..a47c965b2a 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -314,7 +314,7 @@ _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) /* change notify request */ -_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) +_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, struct smb_notify *info) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->notify) { @@ -618,7 +618,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, */ _PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - union smb_notify *info) + struct smb_notify *info) { if (!ntvfs->next || !ntvfs->next->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; -- cgit From 75140d6150264ba50a47e104c3ce1ae40bd3f0c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 18 Mar 2006 10:38:38 +0000 Subject: r14540: fix a talloc hierachie problem, make sure file and search handles are cleaned up before anything else in the pvfs_state struct, as there destructors reply on a valid pvfs_state struct metze (This used to be commit aaa5d377b9b6145a83c0e686c7fbb7b561ae8988) --- source4/ntvfs/posix/pvfs_flush.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 62 +++++++++++++++++++-------------------- source4/ntvfs/posix/pvfs_search.c | 39 +++++++++--------------- source4/ntvfs/posix/vfs_posix.c | 34 +++++++++++++++++---- source4/ntvfs/posix/vfs_posix.h | 44 ++++++++++++++++++++------- 5 files changed, 108 insertions(+), 73 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index ad87ed623b..d21f257201 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -60,7 +60,7 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, } /* they are asking to flush all open files */ - for (f=pvfs->open_files;f;f=f->next) { + for (f=pvfs->files.list;f;f=f->next) { pvfs_flush_file(pvfs, f); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3160519f73..2724339323 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -43,7 +43,7 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, { struct pvfs_file *f; - f = idr_find(pvfs->idtree_fnum, fnum); + f = idr_find(pvfs->files.idtree, fnum); if (f == NULL) { return NULL; } @@ -114,8 +114,8 @@ static int pvfs_dir_handle_destructor(void *p) static int pvfs_dir_fnum_destructor(void *p) { struct pvfs_file *f = p; - DLIST_REMOVE(f->pvfs->open_files, f); - idr_remove(f->pvfs->idtree_fnum, f->fnum); + DLIST_REMOVE(f->pvfs->files.list, f); + idr_remove(f->pvfs->files.idtree, f->fnum); return 0; } @@ -246,7 +246,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); + fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } @@ -258,7 +258,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, status = pvfs_access_check_create(pvfs, req, name, &access_mask); } if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); return status; } @@ -295,7 +295,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* form the lock context used for opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, f->fnum); + idr_remove(pvfs->files.idtree, f->fnum); return status; } @@ -306,7 +306,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -315,7 +315,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, share_access, access_mask, del_on_close, name->full_name); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, f->fnum); + idr_remove(pvfs->files.idtree, f->fnum); talloc_free(lck); return status; } @@ -323,7 +323,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->have_opendb_entry = True; } - DLIST_ADD(pvfs->open_files, f); + DLIST_ADD(pvfs->files.list, f); /* setup destructors to avoid leaks on abnormal termination */ talloc_set_destructor(f->handle, pvfs_dir_handle_destructor); @@ -334,7 +334,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, mode_t mode = pvfs_fileperms(pvfs, attrib); if (mkdir(name->full_name, mode) == -1) { - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); return pvfs_map_errno(pvfs,errno); } @@ -353,7 +353,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* form the lock context used for opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, f->fnum); + idr_remove(pvfs->files.idtree, f->fnum); return status; } @@ -363,7 +363,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -382,7 +382,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } if (!name->exists) { - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -406,7 +406,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_OK; cleanup_delete: - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); rmdir(name->full_name); return status; } @@ -493,9 +493,9 @@ static int pvfs_fnum_destructor(void *p) { struct pvfs_file *f = p; - DLIST_REMOVE(f->pvfs->open_files, f); + DLIST_REMOVE(f->pvfs->files.list, f); pvfs_lock_close(f->pvfs, f); - idr_remove(f->pvfs->idtree_fnum, f->fnum); + idr_remove(f->pvfs->files.idtree, f->fnum); return 0; } @@ -591,7 +591,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_NEW_FNUM, UINT16_MAX); + fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_NEW_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } @@ -602,7 +602,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* create the file */ fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode); if (fd == -1) { - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); return pvfs_map_errno(pvfs, errno); } @@ -612,7 +612,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, if (name->stream_name) { status = pvfs_stream_create(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); close(fd); return status; } @@ -621,7 +621,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* re-resolve the open fd */ status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); close(fd); return status; } @@ -674,7 +674,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* bad news, we must have hit a race - we don't delete the file here as the most likely scenario is that someone else created the file at the same time */ - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); close(fd); return status; } @@ -699,7 +699,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->have_opendb_entry = True; f->handle->sticky_write_time = False; - DLIST_ADD(pvfs->open_files, f); + DLIST_ADD(pvfs->files.list, f); /* setup a destructor to avoid file descriptor leaks on abnormal termination */ @@ -731,7 +731,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_OK; cleanup_delete: - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); close(fd); unlink(name->full_name); return status; @@ -845,7 +845,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, circumstances you actually get the _same_ handle back twice, rather than a new handle. */ - for (f2=pvfs->open_files;f2;f2=f2->next) { + for (f2=pvfs->files.list;f2;f2=f2->next) { if (f2 != f && f2->session_info == req->session_info && f2->smbpid == req->smbpid && @@ -1099,7 +1099,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* allocate a fnum */ - fnum = idr_get_new_above(pvfs->idtree_fnum, f, PVFS_MIN_FILE_FNUM, UINT16_MAX); + fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_FILE_FNUM, UINT16_MAX); if (fnum == -1) { return NT_STATUS_TOO_MANY_OPENED_FILES; } @@ -1128,13 +1128,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, f->fnum); + idr_remove(pvfs->files.idtree, f->fnum); return status; } status = pvfs_brl_locking_key(name, f->handle, &f->handle->brl_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->idtree_fnum, f->fnum); + idr_remove(pvfs->files.idtree, f->fnum); return status; } @@ -1145,11 +1145,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ - idr_remove(pvfs->idtree_fnum, fnum); + idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_INTERNAL_DB_CORRUPTION; } - DLIST_ADD(pvfs->open_files, f); + DLIST_ADD(pvfs->files.list, f); /* setup a destructor to avoid file descriptor leaks on abnormal termination */ @@ -1308,7 +1308,7 @@ NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f, *next; - for (f=pvfs->open_files;f;f=next) { + for (f=pvfs->files.list;f;f=next) { next = f->next; if (f->session_info == req->session_info) { talloc_free(f); @@ -1328,7 +1328,7 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f, *next; - for (f=pvfs->open_files;f;f=next) { + for (f=pvfs->files.list;f;f=next) { next = f->next; if (f->session_info == req->session_info && f->smbpid == req->smbpid) { diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 7ee64887fb..32bef1ae53 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -26,22 +26,7 @@ #include "librpc/gen_ndr/security.h" #include "smbd/service_stream.h" #include "lib/events/events.h" - - -/* the state of a search started with pvfs_search_first() */ -struct pvfs_search_state { - struct pvfs_state *pvfs; - uint16_t handle; - uint_t current_index; - uint16_t search_attrib; - uint16_t must_attrib; - struct pvfs_dir *dir; - time_t last_used; - uint_t num_ea_names; - struct ea_name *ea_names; - struct timed_event *te; -}; - +#include "dlinklist.h" /* place a reasonable limit on old-style searches as clients tend to not send search close requests */ @@ -53,7 +38,8 @@ struct pvfs_search_state { static int pvfs_search_destructor(void *ptr) { struct pvfs_search_state *search = ptr; - idr_remove(search->pvfs->idtree_search, search->handle); + DLIST_REMOVE(search->pvfs->search.list, search); + idr_remove(search->pvfs->search.idtree, search->handle); return 0; } @@ -75,7 +61,7 @@ static void pvfs_search_setup_timer(struct pvfs_search_state *search) struct event_context *ev = search->pvfs->ntvfs->ctx->event_ctx; talloc_free(search->te); search->te = event_add_timed(ev, search, - timeval_current_ofs(search->pvfs->search_inactivity_time, 0), + timeval_current_ofs(search->pvfs->search.inactivity_time, 0), pvfs_search_timer, search); } @@ -306,7 +292,7 @@ static void pvfs_search_cleanup(struct pvfs_state *pvfs) time_t t = time(NULL); for (i=0;iidtree_search, i); + struct pvfs_search_state *search = idr_find(pvfs->search.idtree, i); if (search == NULL) return; if (pvfs_list_eos(search->dir, search->current_index) && search->last_used != 0 && @@ -371,10 +357,10 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, /* we need to give a handle back to the client so it can continue a search */ - id = idr_get_new(pvfs->idtree_search, search, MAX_OLD_SEARCHES); + id = idr_get_new(pvfs->search.idtree, search, MAX_OLD_SEARCHES); if (id == -1) { pvfs_search_cleanup(pvfs); - id = idr_get_new(pvfs->idtree_search, search, MAX_OLD_SEARCHES); + id = idr_get_new(pvfs->search.idtree, search, MAX_OLD_SEARCHES); } if (id == -1) { return NT_STATUS_INSUFFICIENT_RESOURCES; @@ -389,6 +375,8 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, search->last_used = time(NULL); search->te = NULL; + DLIST_ADD(pvfs->search.list, search); + talloc_set_destructor(search, pvfs_search_destructor); status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.level, @@ -425,7 +413,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, handle = io->search_next.in.id.handle | (io->search_next.in.id.reserved<<8); max_count = io->search_next.in.max_count; - search = idr_find(pvfs->idtree_search, handle); + search = idr_find(pvfs->search.idtree, handle); if (search == NULL) { /* we didn't find the search handle */ return NT_STATUS_INVALID_HANDLE; @@ -506,7 +494,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, return status; } - id = idr_get_new(pvfs->idtree_search, search, UINT16_MAX); + id = idr_get_new(pvfs->search.idtree, search, UINT16_MAX); if (id == -1) { return NT_STATUS_INSUFFICIENT_RESOURCES; } @@ -522,6 +510,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, search->ea_names = io->t2ffirst.in.ea_names; search->te = NULL; + DLIST_ADD(pvfs->search.list, search); talloc_set_destructor(search, pvfs_search_destructor); status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, @@ -571,7 +560,7 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, handle = io->t2fnext.in.handle; - search = idr_find(pvfs->idtree_search, handle); + search = idr_find(pvfs->search.idtree, handle); if (search == NULL) { /* we didn't find the search handle */ return NT_STATUS_INVALID_HANDLE; @@ -631,7 +620,7 @@ NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs, handle = io->findclose.in.handle; } - search = idr_find(pvfs->idtree_search, handle); + search = idr_find(pvfs->search.idtree, handle); if (search == NULL) { /* we didn't find the search handle */ return NT_STATUS_INVALID_HANDLE; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 3f1c676df3..cb441cb4c9 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -57,7 +57,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->alloc_size_rounding = lp_parm_int(snum, "posix", "allocationrounding", 512); - pvfs->search_inactivity_time = lp_parm_int(snum, + pvfs->search.inactivity_time = lp_parm_int(snum, "posix", "searchinactivity", 300); #if HAVE_XATTR_SUPPORT @@ -104,6 +104,28 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) } } +static int pvfs_state_destructor(void *ptr) +{ + struct pvfs_state *pvfs = talloc_get_type(ptr, struct pvfs_state); + struct pvfs_file *f, *fn; + struct pvfs_search_state *s, *sn; + + /* + * make sure we cleanup files and searches before anythingelse + * because there destructors need to acess the pvfs_state struct + */ + for (f=pvfs->files.list; f; f=fn) { + fn = f->next; + talloc_free(f); + } + + for (s=pvfs->search.list; s; s=sn) { + sn = s->next; + talloc_free(s); + } + + return 0; +} /* connect to a share - used when a tree_connect operation comes @@ -169,18 +191,20 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, } /* allocate the fnum id -> ptr tree */ - pvfs->idtree_fnum = idr_init(pvfs); - NT_STATUS_HAVE_NO_MEMORY(pvfs->idtree_fnum); + pvfs->files.idtree = idr_init(pvfs); + NT_STATUS_HAVE_NO_MEMORY(pvfs->files.idtree); /* allocate the search handle -> ptr tree */ - pvfs->idtree_search = idr_init(pvfs); - NT_STATUS_HAVE_NO_MEMORY(pvfs->idtree_search); + pvfs->search.idtree = idr_init(pvfs); + NT_STATUS_HAVE_NO_MEMORY(pvfs->search.idtree); status = pvfs_mangle_init(pvfs); NT_STATUS_NOT_OK_RETURN(status); pvfs_setup_options(pvfs); + talloc_set_destructor(pvfs, pvfs_state_destructor); + #ifdef SIGXFSZ /* who had the stupid idea to generate a signal on a large file write instead of just failing it!? */ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index f75e7d3563..59e4ec1abf 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -38,20 +38,12 @@ struct pvfs_state { const char *share_name; uint_t flags; - struct pvfs_file *open_files; - struct pvfs_mangle_context *mangle_ctx; struct brl_context *brl_context; struct odb_context *odb_context; struct sidmap_context *sidmap; - /* an id tree mapping open search ID to a pvfs_search_state structure */ - struct idr_context *idtree_search; - - /* an id tree mapping open file handle -> struct pvfs_file */ - struct idr_context *idtree_fnum; - /* a list of pending async requests. Needed to support ntcancel */ struct pvfs_wait *wait_list; @@ -68,9 +60,25 @@ struct pvfs_state { /* the allocation size rounding */ uint32_t alloc_size_rounding; - /* how long to keep inactive searches around for */ - uint_t search_inactivity_time; - + struct { + /* an id tree mapping open file handle -> struct pvfs_file */ + struct idr_context *idtree; + + /* the open files as DLINKLIST */ + struct pvfs_file *list; + } files; + + struct { + /* an id tree mapping open search ID to a pvfs_search_state structure */ + struct idr_context *idtree; + + /* the open searches as DLINKLIST */ + struct pvfs_search_state *list; + + /* how long to keep inactive searches around for */ + uint_t inactivity_time; + } search; + /* used to accelerate acl mapping */ struct { const struct dom_sid *creator_owner; @@ -173,6 +181,20 @@ struct pvfs_file { uint64_t lock_count; }; +/* the state of a search started with pvfs_search_first() */ +struct pvfs_search_state { + struct pvfs_search_state *prev, *next; + struct pvfs_state *pvfs; + uint16_t handle; + uint_t current_index; + uint16_t search_attrib; + uint16_t must_attrib; + struct pvfs_dir *dir; + time_t last_used; + uint_t num_ea_names; + struct ea_name *ea_names; + struct timed_event *te; +}; /* flags to pvfs_resolve_name() */ #define PVFS_RESOLVE_WILDCARD (1<<0) -- cgit From 61fa658ebcaf2856d543d376b120932ad5a082f0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 18 Mar 2006 11:10:21 +0000 Subject: r14541: separate smbsrv_request and ntvfs_request, with this it's now possible to write a ntvfs_test programm like the vfstest in samba3 also smb2 support will be possible later metze (This used to be commit 7253153691e35cd206346fbd4e9b9f95c042f602) --- source4/ntvfs/ntvfs.h | 26 ++++++++++++++++++++++++-- source4/ntvfs/ntvfs_util.c | 41 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 09c5b9bdcb..13147d5c19 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -24,8 +24,7 @@ #define NTVFS_INTERFACE_VERSION 0 struct ntvfs_module_context; - -#define ntvfs_request smbsrv_request +struct ntvfs_request; /* each backend has to be one one of the following 3 basic types. In * earlier versions of Samba backends needed to handle all types, now @@ -231,6 +230,29 @@ struct ntvfs_async_state { struct ntvfs_module_context *ntvfs; }; +struct ntvfs_request { + /* the ntvfs_context this requests belongs to */ + struct ntvfs_context *ctx; + + /* ntvfs per request async states */ + struct ntvfs_async_state *async_states; + + /* the session_info, with security_token and maybe delegated credentials */ + struct auth_session_info *session_info; + + /* the smb pid is needed for locking contexts */ + uint16_t smbpid; + + /* the smb mid is needed for matching requests */ + uint16_t smbmid; + + /* some statictics for the management tools */ + struct { + /* the system time when the request arrived */ + struct timeval request_time; + } statistics; +}; + /* this structure is used by backends to determine the size of some critical types */ struct ntvfs_critical_sizes { int interface_version; diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index c7b99d3d24..a6d1ccd3f3 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -27,6 +27,43 @@ #include "ntvfs/ntvfs.h" +_PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx, + struct auth_session_info *session_info, + uint16_t smbpid, uint16_t smbmid, + struct timeval request_time, + void *private_data, + void (*send_fn)(struct ntvfs_request *), + uint32_t state) +{ + struct ntvfs_request *req; + struct ntvfs_async_state *async; + + req = talloc(mem_ctx, struct ntvfs_request); + if (!req) return NULL; + req->ctx = ctx; + req->async_states = NULL; + req->session_info = session_info; + req->smbpid = smbpid; + req->smbmid = smbmid; + req->statistics.request_time = request_time; + + async = talloc(req, struct ntvfs_async_state); + if (!async) goto failed; + + async->state = state; + async->private_data = private_data; + async->send_fn = send_fn; + async->status = NT_STATUS_INTERNAL_ERROR; + async->ntvfs = NULL; + + DLIST_ADD(req->async_states, async); + + return req; + +failed: + return NULL; +} + _PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, void *private_data, @@ -35,9 +72,7 @@ _PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs, struct ntvfs_async_state *async; async = talloc(req, struct ntvfs_async_state); - if (!async) { - return NT_STATUS_NO_MEMORY; - } + NT_STATUS_HAVE_NO_MEMORY(async); async->state = req->async_states->state; async->private_data = private_data; -- cgit From 35349a58df5b69446607fbd742a05f57f3515319 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 18 Mar 2006 15:42:57 +0000 Subject: r14542: Remove librpc, libndr and libnbt from includes.h (This used to be commit 51b4270513752d2eafbe77f9de598de16ef84a1f) --- source4/ntvfs/ipc/ipc_rap.c | 1 + source4/ntvfs/ntvfs.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index f683082d58..3f415c9293 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -23,6 +23,7 @@ #include "smb.h" #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" +#include "librpc/ndr/libndr.h" #define NERR_Success 0 #define NERR_badpass 86 diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 13147d5c19..cfb5515203 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -265,5 +265,5 @@ struct ntvfs_critical_sizes { }; struct messaging_context; - +#include "librpc/gen_ndr/security.h" #include "ntvfs/ntvfs_proto.h" -- cgit From 4a1dd087119314a7ed3f2c3e56690a55d213fd07 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sat, 18 Mar 2006 21:13:07 +0000 Subject: r14548: fix build after generated prototypes (This used to be commit 25b93e043edc21fa40928c9166764a3a7e1b1e23) --- source4/ntvfs/posix/pvfs_fsinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index f86be9d29e..1a7ad16776 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -23,6 +23,7 @@ #include "includes.h" #include "vfs_posix.h" #include "librpc/gen_ndr/xattr.h" +#include "librpc/ndr/libndr.h" /* We use libblkid out of e2fsprogs to identify UUID of a volume */ #ifdef HAVE_LIBBLKID -- cgit From c84cfc0ecc46ef05dc7997a128ba9486516cb112 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Mar 2006 02:23:52 +0000 Subject: r14554: Write out header dependencies. This means all C files affected will be rebuilt when a header file is changed. It also means parallel builds work now. It will take a minute or so to generate all the dependency information, but there should be no need to rebuild that information later on, unless a file changes. This behaviour is only enabled when building in developer mode (--enable-developer) and requires a GNU make (or compatible). In all other cases, the file 'static_deps.mk' is included, which contains some basic hardcoded dependency information. (This used to be commit eb435386f015ce1d89eb6f7e7837622ebd9e1951) --- source4/ntvfs/posix/pvfs_xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index cf38d3c1cb..09f1c9fdc8 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "util/unix_privs.h" +#include "lib/util/unix_privs.h" #include "librpc/gen_ndr/ndr_xattr.h" /* -- cgit From 8f3a9d2b27b2519569382b13b03b0f9563418221 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 19 Mar 2006 17:57:34 +0000 Subject: r14569: Make more functions public. (This used to be commit da0a4118189d1026e04e46cb73ba90a4a94d8819) --- source4/ntvfs/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 3f05bfa7be..7a37641f91 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -46,6 +46,7 @@ OBJ_FILES = \ ipc/vfs_ipc.o \ ipc/ipc_rap.o \ ipc/rap_server.o +REQUIRED_SUBSYSTEMS = DCERPC_COMMON dcerpc_server # End MODULE ntvfs_ipc ################################################ -- cgit From 582c039ab14d79501362761811197477752372a9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Mar 2006 11:38:57 +0000 Subject: r14613: fixed ntvfs_notify_next() (This used to be commit 9bf7d322d014d0d7dc603427b233acd97fae5734) --- source4/ntvfs/ntvfs_interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index a47c965b2a..945eb232e2 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -623,7 +623,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, if (!ntvfs->next || !ntvfs->next->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; } - return ntvfs->next->ops->notify(ntvfs, req, info); + return ntvfs->next->ops->notify(ntvfs->next, req, info); } /* cancel - called to cancel an outstanding async request */ -- cgit From 580e5a1a26f9e2ec2881fef2476f9ff2d26df814 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Mar 2006 11:39:48 +0000 Subject: r14614: handle zero timers in pvfs_wait() (This used to be commit cc1f8b3ebe2dcab6f21913af9baf231f3250120e) --- source4/ntvfs/posix/pvfs_wait.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 6cb24e1f92..2d7e41c247 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -33,7 +33,6 @@ struct pvfs_wait { struct pvfs_state *pvfs; void (*handler)(void *, enum pvfs_wait_notice); void *private; - struct timed_event *te; int msg_type; struct messaging_context *msg_ctx; struct event_context *ev; @@ -140,9 +139,10 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, pwait->req = talloc_reference(pwait, req); pwait->pvfs = pvfs; - /* setup a timer */ - pwait->te = event_add_timed(pwait->ev, pwait, end_time, - pvfs_wait_timeout, pwait); + if (!timeval_is_zero(&end_time)) { + /* setup a timer */ + event_add_timed(pwait->ev, pwait, end_time, pvfs_wait_timeout, pwait); + } /* register with the messaging subsystem for this message type */ -- cgit From 830b7447107f5fe71d9947cc0f099dce4de5d53e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Mar 2006 11:40:38 +0000 Subject: r14615: add notify to unixuid ntvfs module (This used to be commit 79af976d189798bb92f5909237202ca18db1789f) --- source4/ntvfs/unixuid/vfs_unixuid.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 9f6a4f9cb7..545fe67827 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -515,6 +515,19 @@ static NTSTATUS unixuid_cancel(struct ntvfs_module_context *ntvfs, return status; } +/* + change notify +*/ +static NTSTATUS unixuid_notify(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_notify *info) +{ + NTSTATUS status; + + PASS_THRU_REQ(ntvfs, req, notify, (ntvfs, req, info)); + + return status; +} + /* lock a byte range */ @@ -660,6 +673,7 @@ NTSTATUS ntvfs_unixuid_init(void) ops.logoff = unixuid_logoff; ops.async_setup = unixuid_async_setup; ops.cancel = unixuid_cancel; + ops.notify = unixuid_notify; ops.name = "unixuid"; -- cgit From 3434cd778c975eb1bb29d257770bd6dbb2335ce9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Mar 2006 11:47:24 +0000 Subject: r14616: added notify change support to the posix backend It doesn't fully work yet, and doesn't yet have all the efficiency that is planned, but it doesn't break anything and I wanted to get the code in the tree to minimise the chance of collisions with the work metze is doing. (This used to be commit 1624ea88e6eef89caacc36e7513aa79df0d579b9) --- source4/ntvfs/common/notify.c | 402 ++++++++++++++++++++++++++++++++++++++ source4/ntvfs/config.mk | 1 + source4/ntvfs/ntvfs.h | 1 + source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_notify.c | 141 +++++++++++++ source4/ntvfs/posix/pvfs_open.c | 3 + source4/ntvfs/posix/pvfs_unlink.c | 5 + source4/ntvfs/posix/vfs_posix.c | 8 + source4/ntvfs/posix/vfs_posix.h | 4 + 9 files changed, 566 insertions(+) create mode 100644 source4/ntvfs/common/notify.c create mode 100644 source4/ntvfs/posix/pvfs_notify.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c new file mode 100644 index 0000000000..48b3559b36 --- /dev/null +++ b/source4/ntvfs/common/notify.c @@ -0,0 +1,402 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + this is the change notify database. It implements mechanisms for + storing current change notify waiters in a tdb, and checking if a + given event matches any of the stored notify waiiters. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/tdb/include/tdb.h" +#include "lib/tdb/include/tdbutil.h" +#include "messaging/messaging.h" +#include "db_wrap.h" +#include "smb_server/smb_server.h" +#include "lib/messaging/irpc.h" +#include "librpc/gen_ndr/ndr_notify.h" +#include "dlinklist.h" + +struct notify_context { + struct tdb_wrap *w; + uint32_t server; + struct messaging_context *messaging_ctx; + struct notify_list *list; + struct notify_array *array; +}; + + +struct notify_list { + struct notify_list *next, *prev; + void *private; + void (*callback)(void *, const struct notify_event *); +}; + +#define NOTIFY_KEY "notify array" + +static NTSTATUS notify_remove_all(struct notify_context *notify); +static void notify_handler(struct messaging_context *msg_ctx, void *private, + uint32_t msg_type, uint32_t server_id, DATA_BLOB *data); + +/* + destroy the notify context +*/ +static int notify_destructor(void *p) +{ + struct notify_context *notify = talloc_get_type(p, struct notify_context); + messaging_deregister(notify->messaging_ctx, MSG_PVFS_NOTIFY, notify); + notify_remove_all(notify); + return 0; +} + +/* + Open up the notify.tdb database. You should close it down using + talloc_free(). We need the messaging_ctx to allow for notifications + via internal messages +*/ +struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, + struct messaging_context *messaging_ctx) +{ + char *path; + struct notify_context *notify; + + notify = talloc(mem_ctx, struct notify_context); + if (notify == NULL) { + return NULL; + } + + path = smbd_tmp_path(notify, "notify.tdb"); + notify->w = tdb_wrap_open(notify, path, 0, + TDB_DEFAULT, + O_RDWR|O_CREAT, 0600); + talloc_free(path); + if (notify->w == NULL) { + talloc_free(notify); + return NULL; + } + + notify->server = server; + notify->messaging_ctx = messaging_ctx; + notify->list = NULL; + notify->array = NULL; + + talloc_set_destructor(notify, notify_destructor); + + /* register with the messaging subsystem for the notify + message type */ + messaging_register(notify->messaging_ctx, notify, + MSG_PVFS_NOTIFY, notify_handler); + + return notify; +} + +/* + load the notify array +*/ +static NTSTATUS notify_load(struct notify_context *notify) +{ + TDB_DATA dbuf; + DATA_BLOB blob; + NTSTATUS status; + + talloc_free(notify->array); + notify->array = talloc_zero(notify, struct notify_array); + NT_STATUS_HAVE_NO_MEMORY(notify->array); + + dbuf = tdb_fetch_bystring(notify->w->tdb, NOTIFY_KEY); + if (dbuf.dptr == NULL) { + return NT_STATUS_OK; + } + + blob.data = dbuf.dptr; + blob.length = dbuf.dsize; + + status = ndr_pull_struct_blob(&blob, notify->array, notify->array, + (ndr_pull_flags_fn_t)ndr_pull_notify_array); + free(dbuf.dptr); + + return status; +} + + +/* + save the notify array +*/ +static NTSTATUS notify_save(struct notify_context *notify) +{ + TDB_DATA dbuf; + DATA_BLOB blob; + NTSTATUS status; + int ret; + TALLOC_CTX *tmp_ctx; + + if (notify->array->num_entries == 0) { + ret = tdb_delete_bystring(notify->w->tdb, NOTIFY_KEY); + if (ret != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return NT_STATUS_OK; + } + + tmp_ctx = talloc_new(notify); + + status = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, + (ndr_push_flags_fn_t)ndr_push_notify_array); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + + dbuf.dptr = blob.data; + dbuf.dsize = blob.length; + + ret = tdb_store_bystring(notify->w->tdb, NOTIFY_KEY, dbuf, TDB_REPLACE); + talloc_free(tmp_ctx); + if (ret != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + return NT_STATUS_OK; +} + + +/* + handle incoming notify messages +*/ +static void notify_handler(struct messaging_context *msg_ctx, void *private, + uint32_t msg_type, uint32_t server_id, DATA_BLOB *data) +{ + struct notify_context *notify = talloc_get_type(private, struct notify_context); + NTSTATUS status; + struct notify_event ev; + TALLOC_CTX *tmp_ctx = talloc_new(notify); + struct notify_list *listel; + + status = ndr_pull_struct_blob(data, tmp_ctx, &ev, + (ndr_pull_flags_fn_t)ndr_pull_notify_event); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + + for (listel=notify->list;listel;listel=listel->next) { + if (listel->private == ev.private) { + listel->callback(listel->private, &ev); + break; + } + } + + talloc_free(tmp_ctx); +} + +/* + add a notify watch. This is called when a notify is first setup on a open + directory handle. +*/ +NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, + void (*callback)(void *, const struct notify_event *), + void *private) +{ + NTSTATUS status; + struct notify_list *listel; + + status = notify_load(notify); + NT_STATUS_NOT_OK_RETURN(status); + + notify->array->entries = talloc_realloc(notify->array, notify->array->entries, + struct notify_entry, + notify->array->num_entries+1); + + if (notify->array->entries == NULL) { + return NT_STATUS_NO_MEMORY; + } + + notify->array->entries[notify->array->num_entries] = *e; + notify->array->entries[notify->array->num_entries].private = private; + notify->array->entries[notify->array->num_entries].server = notify->server; + notify->array->num_entries++; + + status = notify_save(notify); + NT_STATUS_NOT_OK_RETURN(status); + + listel = talloc(notify, struct notify_list); + NT_STATUS_HAVE_NO_MEMORY(listel); + + listel->private = private; + listel->callback = callback; + DLIST_ADD(notify->list, listel); + + return status; +} + +/* + remove a notify watch. Called when the directory handle is closed +*/ +NTSTATUS notify_remove(struct notify_context *notify, void *private) +{ + NTSTATUS status; + struct notify_list *listel; + int i; + + for (listel=notify->list;listel;listel=listel->next) { + if (listel->private == private) { + DLIST_REMOVE(notify->list, listel); + break; + } + } + if (listel == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + status = notify_load(notify); + NT_STATUS_NOT_OK_RETURN(status); + + for (i=0;iarray->num_entries;i++) { + if (notify->server == notify->array->entries[i].server && + private == notify->array->entries[i].private) { + break; + } + } + if (i == notify->array->num_entries) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (i < notify->array->num_entries-1) { + memmove(¬ify->array->entries[i], ¬ify->array->entries[i+1], + sizeof(notify->array->entries[i])*(notify->array->num_entries-(i+1))); + } + notify->array->num_entries--; + + return notify_save(notify); +} + +/* + remove all notify watches for this messaging server +*/ +static NTSTATUS notify_remove_all(struct notify_context *notify) +{ + NTSTATUS status; + int i; + + if (notify->list == NULL) { + return NT_STATUS_OK; + } + + status = notify_load(notify); + NT_STATUS_NOT_OK_RETURN(status); + + for (i=0;iarray->num_entries;i++) { + if (notify->server == notify->array->entries[i].server) { + if (i < notify->array->num_entries-1) { + memmove(¬ify->array->entries[i], ¬ify->array->entries[i+1], + sizeof(notify->array->entries[i])*(notify->array->num_entries-(i+1))); + } + i--; + notify->array->num_entries--; + } + } + + + return notify_save(notify); +} + + +/* + see if a notify event matches +*/ +static BOOL notify_match(struct notify_context *notify, struct notify_entry *e, + const char *path, uint32_t action) +{ + size_t len = strlen(e->path); + + /* TODO: check action */ + + if (strncmp(path, e->path, len) != 0) { + return False; + } + + if (path[len] == 0) { + return True; + } + if (path[len] != '/') { + return False; + } + + if (!e->recursive) { + if (strchr(&path[len+1], '/') != NULL) { + return False; + } + } + + return True; +} + + +/* + send a notify message to another messaging server +*/ +static void notify_send(struct notify_context *notify, struct notify_entry *e, + const char *path, uint32_t action) +{ + struct notify_event ev; + DATA_BLOB data; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + ev.action = action; + ev.path = path; + ev.private = e->private; + + tmp_ctx = talloc_new(notify); + + status = ndr_push_struct_blob(&data, tmp_ctx, &ev, + (ndr_push_flags_fn_t)ndr_push_notify_event); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + + status = messaging_send(notify->messaging_ctx, e->server, + MSG_PVFS_NOTIFY, &data); + talloc_free(tmp_ctx); +} + +/* + trigger a notify message for anyone waiting on a matching event +*/ +void notify_trigger(struct notify_context *notify, + uint32_t action, const char *path) +{ + NTSTATUS status; + int i; + + status = notify_load(notify); + if (!NT_STATUS_IS_OK(status)) { + return; + } + + /* this needs to be changed to a log(n) search */ + for (i=0;iarray->num_entries;i++) { + if (notify_match(notify, ¬ify->array->entries[i], path, action)) { + notify_send(notify, ¬ify->array->entries[i], path, action); + } + } +} diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 7a37641f91..8f8e47a7e6 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -78,6 +78,7 @@ OBJ_FILES = \ ntvfs_util.o \ common/brlock.o \ common/opendb.o \ + common/notify.o \ common/sidmap.o REQUIRED_SUBSYSTEMS = NDR_OPENDB # diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index cfb5515203..d0d5b7fd74 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -266,4 +266,5 @@ struct ntvfs_critical_sizes { struct messaging_context; #include "librpc/gen_ndr/security.h" +#include "librpc/gen_ndr/notify.h" #include "ntvfs/ntvfs_proto.h" diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index ccf2c2d1a9..c49fbc88b7 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -29,6 +29,7 @@ OBJ_FILES = \ pvfs_xattr.o \ pvfs_streams.o \ pvfs_acl.o \ + pvfs_notify.o \ xattr_system.o \ xattr_tdb.o REQUIRED_SUBSYSTEMS = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c new file mode 100644 index 0000000000..566b6bc0e2 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -0,0 +1,141 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - notify + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "vfs_posix.h" +#include "lib/messaging/irpc.h" +#include "messaging/messaging.h" + +/* pending notifies buffer, hung off struct pvfs_file for open directories + that have used change notify */ +struct pvfs_notify_buffer { + struct pvfs_file *f; + uint32_t num_changes; + struct notify_changes *changes; + uint32_t max_buffer_size; + uint32_t current_buffer_size; + void *wait_handle; +}; + + +/* + destroy a notify buffer. Called when the handle is closed + */ +static int pvfs_notify_destructor(void *ptr) +{ + struct pvfs_notify_buffer *n = talloc_get_type(ptr, struct pvfs_notify_buffer); + notify_remove(n->f->pvfs->notify_context, n); + n->f->notify_buffer = NULL; + return 0; +} + + +/* + called when a async notify event comes in +*/ +static void pvfs_notify_callback(void *private, const struct notify_event *ev) +{ + struct pvfs_notify_buffer *n = talloc_get_type(private, struct pvfs_notify_buffer); + DEBUG(0,("got notify for '%s'\n", ev->path)); +} + +/* + setup a notify buffer on a directory handle +*/ +static NTSTATUS pvfs_notify_setup(struct pvfs_state *pvfs, struct pvfs_file *f, + uint32_t buffer_size, uint32_t filter, BOOL recursive) +{ + NTSTATUS status; + struct notify_entry e; + + f->notify_buffer = talloc_zero(f, struct pvfs_notify_buffer); + NT_STATUS_HAVE_NO_MEMORY(f->notify_buffer); + + f->notify_buffer->max_buffer_size = buffer_size; + f->notify_buffer->f = f; + + e.filter = filter; + e.path = f->handle->name->full_name; + e.recursive = recursive; + + status = notify_add(pvfs->notify_context, &e, + pvfs_notify_callback, f->notify_buffer); + NT_STATUS_NOT_OK_RETURN(status); + + talloc_set_destructor(f->notify_buffer, pvfs_notify_destructor); + + return NT_STATUS_OK; +} + + +/* change notify request - always async. This request blocks until the + event buffer is non-empty */ +NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_notify *info) +{ + struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data, + struct pvfs_state); + struct pvfs_file *f; + NTSTATUS status; + + f = pvfs_find_fd(pvfs, req, info->in.file.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + /* this request doesn't make sense unless its async */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* its only valid for directories */ + if (f->handle->fd != -1) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + /* if the handle doesn't currently have a notify buffer then + create one */ + if (f->notify_buffer == NULL) { + status = pvfs_notify_setup(pvfs, f, + info->in.buffer_size, + info->in.completion_filter, + info->in.recursive); + NT_STATUS_NOT_OK_RETURN(status); + } + + /* if the buffer is empty then start waiting */ + if (f->notify_buffer->num_changes == 0) { + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + return NT_STATUS_OK; + } + + /* otherwise if the buffer is not empty then return its + contents immediately */ + info->out.num_changes = f->notify_buffer->num_changes; + info->out.changes = talloc_steal(req, f->notify_buffer->changes); + f->notify_buffer->num_changes = 0; + f->notify_buffer->changes = NULL; + f->notify_buffer->current_buffer_size = 0; + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 2724339323..3c3e13bc91 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -271,6 +271,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->share_access = io->generic.in.share_access; f->impersonation = io->generic.in.impersonation; f->access_mask = access_mask; + f->notify_buffer = NULL; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); @@ -688,6 +689,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->share_access = io->generic.in.share_access; f->access_mask = access_mask; f->impersonation = io->generic.in.impersonation; + f->notify_buffer = NULL; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); @@ -1113,6 +1115,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->share_access = io->generic.in.share_access; f->access_mask = access_mask; f->impersonation = io->generic.in.impersonation; + f->notify_buffer = NULL; f->handle->pvfs = pvfs; f->handle->fd = -1; diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 76c9bc10a4..3a6e4bba2f 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -103,6 +103,11 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, status = pvfs_map_errno(pvfs, errno); } + if (NT_STATUS_IS_OK(status)) { + notify_trigger(pvfs->notify_context, NOTIFY_ACTION_REMOVED, + name->full_name); + } + talloc_free(name); return status; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index cb441cb4c9..0469e54d35 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -185,6 +185,13 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + pvfs->notify_context = notify_init(pvfs, + pvfs->ntvfs->ctx->server_id, + pvfs->ntvfs->ctx->msg_ctx); + if (pvfs->notify_context == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + pvfs->sidmap = sidmap_open(pvfs); if (pvfs->sidmap == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -317,6 +324,7 @@ NTSTATUS ntvfs_posix_init(void) ops.logoff = pvfs_logoff; ops.async_setup = pvfs_async_setup; ops.cancel = pvfs_cancel; + ops.notify = pvfs_notify; /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 59e4ec1abf..aa452c6a13 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -42,6 +42,7 @@ struct pvfs_state { struct brl_context *brl_context; struct odb_context *odb_context; + struct notify_context *notify_context; struct sidmap_context *sidmap; /* a list of pending async requests. Needed to support @@ -179,6 +180,9 @@ struct pvfs_file { /* a count of active locks - used to avoid calling brl_close on file close */ uint64_t lock_count; + + /* for directories, a buffer of pending notify events */ + struct pvfs_notify_buffer *notify_buffer; }; /* the state of a search started with pvfs_search_first() */ -- cgit From 97f49de55e2d12d249d608a91bddcd3cd1ffa452 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 22 Mar 2006 13:40:58 +0000 Subject: r14640: Fix dependency (This used to be commit 009b56a3234b28e212fe5b2cda4f068c9a2f8707) --- source4/ntvfs/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 8f8e47a7e6..eb675c38e3 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -80,7 +80,7 @@ OBJ_FILES = \ common/opendb.o \ common/notify.o \ common/sidmap.o -REQUIRED_SUBSYSTEMS = NDR_OPENDB +REQUIRED_SUBSYSTEMS = NDR_OPENDB NDR_NOTIFY # # End SUBSYSTEM NTVFS ################################################ -- cgit From aba2ae4784993d1f40ef9295e0f3f11934d9faec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 23 Mar 2006 11:13:19 +0000 Subject: r14672: the async_info desctructor needs access to the private struct, so free async info explicit... I hope to find a generic way later, so that the ntvfs modules doesn't need to take care that much... metze (This used to be commit ba3bf34a850fca52f5d6297315e33df14f62373b) --- source4/ntvfs/cifs/vfs_cifs.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 50aa58d6fb..26b9831acc 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -184,6 +184,14 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) { struct cvfs_private *private = ntvfs->private_data; + struct async_info *a, *an; + + /* first cleanup pending requests */ + for (a=private->pending; a; a = an) { + an = a->next; + smbcli_request_destroy(a->c_req); + talloc_free(a); + } talloc_free(private); ntvfs->private_data = NULL; @@ -211,6 +219,7 @@ static void async_simple(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smbcli_request_simple_recv(c_req); + talloc_free(async); req->async_states->send_fn(req); } @@ -268,6 +277,7 @@ static void async_ioctl(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -321,6 +331,7 @@ static void async_qpathinfo(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -352,6 +363,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -405,6 +417,7 @@ static void async_open(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_open_recv(c_req, req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -509,6 +522,7 @@ static void async_read(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_read_recv(c_req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -545,6 +559,7 @@ static void async_write(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_write_recv(c_req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -581,6 +596,7 @@ static void async_seek(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_seek_recv(c_req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -767,6 +783,7 @@ static void async_fsinfo(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -846,6 +863,7 @@ static void async_trans2(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } @@ -885,6 +903,7 @@ static void async_changenotify(struct smbcli_request *c_req) struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; req->async_states->status = smb_raw_changenotify_recv(c_req, req, async->parms); + talloc_free(async); req->async_states->send_fn(req); } -- cgit From ad06a8bd651e3a8b598c92a356ac1ce4117ae72e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 26 Mar 2006 01:23:40 +0000 Subject: r14736: - the ntvfs subsystem should not know about smb_server.h - the process module subsystem should not know about smb_server.h - the smb_server module should not know about process models metze (This used to be commit bac95bb8f4ad35a31ee666f5916ff9b2f292d964) --- source4/ntvfs/cifs/vfs_cifs.c | 2 -- source4/ntvfs/common/notify.c | 1 - source4/ntvfs/common/opendb.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 1 - source4/ntvfs/nbench/vfs_nbench.c | 1 - source4/ntvfs/ntvfs.h | 2 ++ source4/ntvfs/ntvfs_base.c | 1 - source4/ntvfs/ntvfs_generic.c | 1 - source4/ntvfs/ntvfs_interface.c | 1 - source4/ntvfs/ntvfs_util.c | 1 - source4/ntvfs/posix/vfs_posix.c | 1 - source4/ntvfs/posix/vfs_posix.h | 1 - source4/ntvfs/print/vfs_print.c | 1 - source4/ntvfs/simple/svfs_util.c | 1 - source4/ntvfs/simple/vfs_simple.c | 1 - source4/ntvfs/unixuid/vfs_unixuid.c | 1 - 16 files changed, 3 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 26b9831acc..25fe4cb2a4 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -28,8 +28,6 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/smb_composite/smb_composite.h" -#include "smb_server/smb_server.h" -#include "smbd/service_stream.h" #include "auth/auth.h" #include "ntvfs/ntvfs.h" #include "include/dlinklist.h" diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 48b3559b36..604b6a1a2d 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -30,7 +30,6 @@ #include "lib/tdb/include/tdbutil.h" #include "messaging/messaging.h" #include "db_wrap.h" -#include "smb_server/smb_server.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_notify.h" #include "dlinklist.h" diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 1faa6387b7..0890bb112d 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -44,9 +44,9 @@ #include "messaging/messaging.h" #include "librpc/gen_ndr/ndr_security.h" #include "db_wrap.h" -#include "smb_server/smb_server.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" +#include "smb.h" struct odb_context { struct tdb_wrap *w; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 7b9433bcff..b6b931eccd 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -27,7 +27,6 @@ #include "includes.h" #include "dlinklist.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 6dcf58182a..b93e5f3c44 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -26,7 +26,6 @@ #include "includes.h" #include "system/filesys.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" /* this is stored in ntvfs_private */ diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index d0d5b7fd74..ec1f741fa8 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -19,6 +19,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "libcli/raw/interfaces.h" + /* modules can use the following to determine if the interface has changed */ /* version 1 -> 0 - make module stacking easier -- metze */ #define NTVFS_INTERFACE_VERSION 0 diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 5abf449b8c..b1efb44ec7 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -25,7 +25,6 @@ #include "includes.h" #include "dlinklist.h" -#include "smb_server/smb_server.h" #include "build.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index f74092eda0..fdc186c710 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -32,7 +32,6 @@ */ #include "includes.h" -#include "smb_server/smb_server.h" #include "librpc/gen_ndr/ndr_security.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 945eb232e2..c26832d96e 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" /* connect/disconnect */ diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index a6d1ccd3f3..52f03430ce 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -23,7 +23,6 @@ #include "includes.h" #include "dlinklist.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 0469e54d35..28cf2cc6cd 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -27,7 +27,6 @@ #include "includes.h" #include "vfs_posix.h" #include "librpc/gen_ndr/security.h" -#include "smbd/service_stream.h" #include "lib/tdb/include/tdb.h" #include "db_wrap.h" #include "libcli/security/proto.h" diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index aa452c6a13..00ae92a95a 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -25,7 +25,6 @@ #include "librpc/gen_ndr/xattr.h" #include "system/filesys.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" /* this is the private structure for the posix vfs backend. It is used diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index bd1615d603..1aa38a59c2 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -24,7 +24,6 @@ #include "includes.h" #include "libcli/raw/ioctl.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" /* diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index 0a9701f8b3..c3c0412f4b 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -28,7 +28,6 @@ #include "svfs.h" #include "system/time.h" #include "system/dir.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" /* diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 2f5a8af8f5..2347f31bde 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -32,7 +32,6 @@ #include "svfs.h" #include "system/time.h" #include "dlinklist.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" #include "ntvfs/simple/proto.h" diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 545fe67827..9d8b058b7a 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -25,7 +25,6 @@ #include "system/filesys.h" #include "system/passwd.h" #include "auth/auth.h" -#include "smb_server/smb_server.h" #include "ntvfs/ntvfs.h" struct unixuid_private { -- cgit From 57bde8631fc65f9b8e10eee7f948e5690412bead Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Mar 2006 13:31:30 +0000 Subject: r14755: the change notify code now passes most of the RAW-NOTIFY test. Still more work to do though (This used to be commit 4d234b37e528137b5c00f6bbb84c2d6939fea324) --- source4/ntvfs/common/notify.c | 7 ++- source4/ntvfs/posix/pvfs_mkdir.c | 6 +++ source4/ntvfs/posix/pvfs_notify.c | 89 +++++++++++++++++++++++++++++++++------ source4/ntvfs/posix/pvfs_wait.c | 17 +++++--- 4 files changed, 98 insertions(+), 21 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 604b6a1a2d..bc04c830f1 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -332,9 +332,6 @@ static BOOL notify_match(struct notify_context *notify, struct notify_entry *e, return False; } - if (path[len] == 0) { - return True; - } if (path[len] != '/') { return False; } @@ -395,7 +392,9 @@ void notify_trigger(struct notify_context *notify, /* this needs to be changed to a log(n) search */ for (i=0;iarray->num_entries;i++) { if (notify_match(notify, ¬ify->array->entries[i], path, action)) { - notify_send(notify, ¬ify->array->entries[i], path, action); + notify_send(notify, ¬ify->array->entries[i], + path + strlen(notify->array->entries[i].path) + 1, + action); } } } diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 047b6f45a7..5ec7df3b9d 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -83,6 +83,8 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return status; } + notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name); + return NT_STATUS_OK; } @@ -135,6 +137,8 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return status; } + notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name); + return NT_STATUS_OK; } @@ -172,5 +176,7 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } + notify_trigger(pvfs->notify_context, NOTIFY_ACTION_REMOVED, name->full_name); + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 566b6bc0e2..55a9767863 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -33,10 +33,13 @@ struct pvfs_notify_buffer { struct notify_changes *changes; uint32_t max_buffer_size; uint32_t current_buffer_size; - void *wait_handle; + + /* these last two are only present when a notify request is + pending */ + struct ntvfs_request *req; + struct smb_notify *info; }; - /* destroy a notify buffer. Called when the handle is closed */ @@ -48,6 +51,34 @@ static int pvfs_notify_destructor(void *ptr) return 0; } +/* + send a reply to a pending notify request +*/ +static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer) +{ + struct ntvfs_request *req = notify_buffer->req; + struct smb_notify *info = notify_buffer->info; + + info->out.num_changes = notify_buffer->num_changes; + info->out.changes = talloc_steal(req, notify_buffer->changes); + notify_buffer->num_changes = 0; + notify_buffer->changes = NULL; + notify_buffer->current_buffer_size = 0; + + notify_buffer->req = NULL; + notify_buffer->info = NULL; + + DEBUG(0,("sending %d changes\n", info->out.num_changes)); + + if (info->out.num_changes == 0) { + req->async_states->status = NT_STATUS_CANCELLED; + } else { + req->async_states->status = NT_STATUS_OK; + } + req->async_states->send_fn(req); +} + + /* called when a async notify event comes in @@ -55,7 +86,17 @@ static int pvfs_notify_destructor(void *ptr) static void pvfs_notify_callback(void *private, const struct notify_event *ev) { struct pvfs_notify_buffer *n = talloc_get_type(private, struct pvfs_notify_buffer); - DEBUG(0,("got notify for '%s'\n", ev->path)); + + n->changes = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1); + n->changes[n->num_changes].action = ev->action; + n->changes[n->num_changes].name.s = talloc_strdup(n->changes, ev->path); + n->num_changes++; + + DEBUG(0,("got notify for '%s' action=%d\n", ev->path, ev->action)); + + if (n->req != NULL) { + pvfs_notify_send(n); + } } /* @@ -86,6 +127,22 @@ static NTSTATUS pvfs_notify_setup(struct pvfs_state *pvfs, struct pvfs_file *f, return NT_STATUS_OK; } +/* + called from the pvfs_wait code when either an event has come in, or + the notify request has been cancelled +*/ +static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason) +{ + struct pvfs_notify_buffer *notify_buffer = talloc_get_type(private, struct pvfs_notify_buffer); + struct ntvfs_request *req = notify_buffer->req; + + if (req == NULL) { + /* nothing to do, nobody is waiting */ + return; + } + + pvfs_notify_send(notify_buffer); +} /* change notify request - always async. This request blocks until the event buffer is non-empty */ @@ -110,7 +167,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, /* its only valid for directories */ if (f->handle->fd != -1) { - return NT_STATUS_NOT_A_DIRECTORY; + return NT_STATUS_INVALID_PARAMETER; } /* if the handle doesn't currently have a notify buffer then @@ -123,19 +180,27 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); } + req->async_states->status = NT_STATUS_OK; + + if (f->notify_buffer->req != NULL) { + DEBUG(0,("Notify already setup\n")); + pvfs_notify_send(f->notify_buffer); + } + + f->notify_buffer->req = talloc_reference(f->notify_buffer, req); + f->notify_buffer->info = info; + /* if the buffer is empty then start waiting */ if (f->notify_buffer->num_changes == 0) { - req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + void *wait_handle = + pvfs_wait_message(pvfs, req, -1, timeval_zero(), + pvfs_notify_end, f->notify_buffer); + NT_STATUS_HAVE_NO_MEMORY(wait_handle); + talloc_steal(req, wait_handle); return NT_STATUS_OK; } - /* otherwise if the buffer is not empty then return its - contents immediately */ - info->out.num_changes = f->notify_buffer->num_changes; - info->out.changes = talloc_steal(req, f->notify_buffer->changes); - f->notify_buffer->num_changes = 0; - f->notify_buffer->changes = NULL; - f->notify_buffer->current_buffer_size = 0; + pvfs_notify_send(f->notify_buffer); return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 2d7e41c247..5750c0fe08 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -105,7 +105,9 @@ static void pvfs_wait_timeout(struct event_context *ev, static int pvfs_wait_destructor(void *ptr) { struct pvfs_wait *pwait = ptr; - messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); + if (pwait->msg_type != -1) { + messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); + } DLIST_REMOVE(pwait->pvfs->wait_list, pwait); return 0; } @@ -116,6 +118,9 @@ static int pvfs_wait_destructor(void *ptr) the return value is a handle. To stop waiting talloc_free this handle. + + if msg_type == -1 then no message is registered, and it is assumed + that the caller handles any messaging setup needed */ void *pvfs_wait_message(struct pvfs_state *pvfs, struct ntvfs_request *req, @@ -146,10 +151,12 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, /* register with the messaging subsystem for this message type */ - messaging_register(pwait->msg_ctx, - pwait, - msg_type, - pvfs_wait_dispatch); + if (msg_type != -1) { + messaging_register(pwait->msg_ctx, + pwait, + msg_type, + pvfs_wait_dispatch); + } /* tell the main smb server layer that we will be replying asynchronously */ -- cgit From 33f663b25206c6cc4b2c33dfca3983d9dfee73dc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 01:09:46 +0000 Subject: r14792: when we enable fake oplocks, give out batch oplocks not exclusive oplocks (This used to be commit 182aee1a213c1219772895deed31e1ed8aed00c4) --- source4/ntvfs/posix/pvfs_open.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3c3e13bc91..1b1c32cab5 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -710,7 +710,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { - io->generic.out.oplock_level = OPLOCK_EXCLUSIVE; + io->generic.out.oplock_level = OPLOCK_BATCH; } else { io->generic.out.oplock_level = OPLOCK_NONE; } @@ -1238,7 +1238,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_free(lck); if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { - io->generic.out.oplock_level = OPLOCK_EXCLUSIVE; + io->generic.out.oplock_level = OPLOCK_BATCH; } else { io->generic.out.oplock_level = OPLOCK_NONE; } -- cgit From 8a95fa446e1eca4c9ff332202f23183411b44c04 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 02:06:06 +0000 Subject: r14793: the RAW-NOTIFY test now passes. Next I need to make it efficient, and add the hooks in all the other places (This used to be commit d1937589029ac2a75d15f006685769c44a274a65) --- source4/ntvfs/posix/pvfs_notify.c | 46 ++++++++++++++++++++++----------------- source4/ntvfs/posix/pvfs_open.c | 2 ++ 2 files changed, 28 insertions(+), 20 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 55a9767863..01a88f25a7 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -40,21 +40,10 @@ struct pvfs_notify_buffer { struct smb_notify *info; }; -/* - destroy a notify buffer. Called when the handle is closed - */ -static int pvfs_notify_destructor(void *ptr) -{ - struct pvfs_notify_buffer *n = talloc_get_type(ptr, struct pvfs_notify_buffer); - notify_remove(n->f->pvfs->notify_context, n); - n->f->notify_buffer = NULL; - return 0; -} - /* send a reply to a pending notify request */ -static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer) +static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS status) { struct ntvfs_request *req = notify_buffer->req; struct smb_notify *info = notify_buffer->info; @@ -70,14 +59,27 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer) DEBUG(0,("sending %d changes\n", info->out.num_changes)); - if (info->out.num_changes == 0) { - req->async_states->status = NT_STATUS_CANCELLED; - } else { - req->async_states->status = NT_STATUS_OK; + if (info->out.num_changes != 0) { + status = NT_STATUS_OK; } + + req->async_states->status = status; req->async_states->send_fn(req); } +/* + destroy a notify buffer. Called when the handle is closed + */ +static int pvfs_notify_destructor(void *ptr) +{ + struct pvfs_notify_buffer *n = talloc_get_type(ptr, struct pvfs_notify_buffer); + notify_remove(n->f->pvfs->notify_context, n); + n->f->notify_buffer = NULL; + if (n->req) { + pvfs_notify_send(n, NT_STATUS_OK); + } + return 0; +} /* @@ -95,7 +97,7 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) DEBUG(0,("got notify for '%s' action=%d\n", ev->path, ev->action)); if (n->req != NULL) { - pvfs_notify_send(n); + pvfs_notify_send(n, NT_STATUS_OK); } } @@ -141,7 +143,11 @@ static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason) return; } - pvfs_notify_send(notify_buffer); + if (reason == PVFS_WAIT_CANCEL) { + pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED); + } else { + pvfs_notify_send(notify_buffer, NT_STATUS_OK); + } } /* change notify request - always async. This request blocks until the @@ -184,7 +190,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, if (f->notify_buffer->req != NULL) { DEBUG(0,("Notify already setup\n")); - pvfs_notify_send(f->notify_buffer); + pvfs_notify_send(f->notify_buffer, NT_STATUS_CANCELLED); } f->notify_buffer->req = talloc_reference(f->notify_buffer, req); @@ -200,7 +206,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } - pvfs_notify_send(f->notify_buffer); + pvfs_notify_send(f->notify_buffer, NT_STATUS_OK); return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1b1c32cab5..38123c3a9e 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -730,6 +730,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* success - keep the file handle */ talloc_steal(pvfs, f); + notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name); + return NT_STATUS_OK; cleanup_delete: -- cgit From 0d3a9493a27e7724a5c0337a5f93037114990956 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 02:25:38 +0000 Subject: r14795: queue notify requests on the same handle (This used to be commit c976f14a9f397802946a9bb36394fe4c27bf3caf) --- source4/ntvfs/posix/pvfs_notify.c | 63 +++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 32 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 01a88f25a7..a41a2d3cd2 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -24,6 +24,7 @@ #include "vfs_posix.h" #include "lib/messaging/irpc.h" #include "messaging/messaging.h" +#include "dlinklist.h" /* pending notifies buffer, hung off struct pvfs_file for open directories that have used change notify */ @@ -33,11 +34,13 @@ struct pvfs_notify_buffer { struct notify_changes *changes; uint32_t max_buffer_size; uint32_t current_buffer_size; - - /* these last two are only present when a notify request is - pending */ - struct ntvfs_request *req; - struct smb_notify *info; + + /* a list of requests waiting for events on this handle */ + struct notify_pending { + struct notify_pending *next, *prev; + struct ntvfs_request *req; + struct smb_notify *info; + } *pending; }; /* @@ -45,17 +48,24 @@ struct pvfs_notify_buffer { */ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS status) { - struct ntvfs_request *req = notify_buffer->req; - struct smb_notify *info = notify_buffer->info; + struct notify_pending *pending = notify_buffer->pending; + struct ntvfs_request *req; + struct smb_notify *info; + + if (pending == NULL) return; + + DLIST_REMOVE(notify_buffer->pending, pending); + + req = pending->req; + info = pending->info; info->out.num_changes = notify_buffer->num_changes; info->out.changes = talloc_steal(req, notify_buffer->changes); notify_buffer->num_changes = 0; notify_buffer->changes = NULL; notify_buffer->current_buffer_size = 0; - - notify_buffer->req = NULL; - notify_buffer->info = NULL; + + talloc_free(pending); DEBUG(0,("sending %d changes\n", info->out.num_changes)); @@ -75,9 +85,7 @@ static int pvfs_notify_destructor(void *ptr) struct pvfs_notify_buffer *n = talloc_get_type(ptr, struct pvfs_notify_buffer); notify_remove(n->f->pvfs->notify_context, n); n->f->notify_buffer = NULL; - if (n->req) { - pvfs_notify_send(n, NT_STATUS_OK); - } + pvfs_notify_send(n, NT_STATUS_OK); return 0; } @@ -96,9 +104,7 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) DEBUG(0,("got notify for '%s' action=%d\n", ev->path, ev->action)); - if (n->req != NULL) { - pvfs_notify_send(n, NT_STATUS_OK); - } + pvfs_notify_send(n, NT_STATUS_OK); } /* @@ -135,14 +141,8 @@ static NTSTATUS pvfs_notify_setup(struct pvfs_state *pvfs, struct pvfs_file *f, */ static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason) { - struct pvfs_notify_buffer *notify_buffer = talloc_get_type(private, struct pvfs_notify_buffer); - struct ntvfs_request *req = notify_buffer->req; - - if (req == NULL) { - /* nothing to do, nobody is waiting */ - return; - } - + struct pvfs_notify_buffer *notify_buffer = talloc_get_type(private, + struct pvfs_notify_buffer); if (reason == PVFS_WAIT_CANCEL) { pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED); } else { @@ -160,6 +160,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, struct pvfs_state); struct pvfs_file *f; NTSTATUS status; + struct notify_pending *pending; f = pvfs_find_fd(pvfs, req, info->in.file.fnum); if (!f) { @@ -186,15 +187,13 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); } - req->async_states->status = NT_STATUS_OK; - - if (f->notify_buffer->req != NULL) { - DEBUG(0,("Notify already setup\n")); - pvfs_notify_send(f->notify_buffer, NT_STATUS_CANCELLED); - } + pending = talloc(f->notify_buffer, struct notify_pending); + NT_STATUS_HAVE_NO_MEMORY(pending); + + pending->req = talloc_reference(pending, req); + pending->info = info; - f->notify_buffer->req = talloc_reference(f->notify_buffer, req); - f->notify_buffer->info = info; + DLIST_ADD_END(f->notify_buffer->pending, pending, struct notify_pending *); /* if the buffer is empty then start waiting */ if (f->notify_buffer->num_changes == 0) { -- cgit From 8260854a18fe784be01fa88be1678bf0e267720c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 03:14:38 +0000 Subject: r14796: handle overflows in the notify buffer. The pending events are dumped and the notify buffer removed (This used to be commit a4c0e23f9dc5049e7d6df3bf3d3ee694f715ce05) --- source4/ntvfs/posix/pvfs_notify.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index a41a2d3cd2..121ba499b3 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -52,7 +52,21 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS struct ntvfs_request *req; struct smb_notify *info; - if (pending == NULL) return; + if (notify_buffer->current_buffer_size > notify_buffer->max_buffer_size && + notify_buffer->num_changes != 0) { + /* on buffer overflow return no changes and destroys the notify buffer */ + notify_buffer->num_changes = 0; + while (notify_buffer->pending) { + pvfs_notify_send(notify_buffer, NT_STATUS_OK); + } + talloc_free(notify_buffer); + return; + } + + /* see if there is anyone waiting */ + if (notify_buffer->pending == NULL) { + return; + } DLIST_REMOVE(notify_buffer->pending, pending); @@ -67,8 +81,6 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS talloc_free(pending); - DEBUG(0,("sending %d changes\n", info->out.num_changes)); - if (info->out.num_changes != 0) { status = NT_STATUS_OK; } @@ -96,14 +108,23 @@ static int pvfs_notify_destructor(void *ptr) static void pvfs_notify_callback(void *private, const struct notify_event *ev) { struct pvfs_notify_buffer *n = talloc_get_type(private, struct pvfs_notify_buffer); + size_t len; n->changes = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1); n->changes[n->num_changes].action = ev->action; n->changes[n->num_changes].name.s = talloc_strdup(n->changes, ev->path); n->num_changes++; - DEBUG(0,("got notify for '%s' action=%d\n", ev->path, ev->action)); + /* + work out how much room this will take in the buffer + */ + len = 12 + strlen_m(ev->path)*2; + if (len & 3) { + len += 4 - (len & 3); + } + n->current_buffer_size += len; + /* send what we have */ pvfs_notify_send(n, NT_STATUS_OK); } @@ -187,6 +208,8 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); } + f->notify_buffer->max_buffer_size = info->in.buffer_size; + pending = talloc(f->notify_buffer, struct notify_pending); NT_STATUS_HAVE_NO_MEMORY(pending); -- cgit From ed3fc628713e1f9552b523c9aec9bd8993e0b771 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 03:51:49 +0000 Subject: r14797: added checking of the filter in notify requests (This used to be commit 1db0a5a7f4c1ff915d91bc15d8e40cc90a78961d) --- source4/ntvfs/common/notify.c | 14 +++++++++----- source4/ntvfs/posix/pvfs_mkdir.c | 15 ++++++++++++--- source4/ntvfs/posix/pvfs_open.c | 15 ++++++++++++++- source4/ntvfs/posix/pvfs_read.c | 5 +++++ source4/ntvfs/posix/pvfs_unlink.c | 4 +++- source4/ntvfs/posix/pvfs_write.c | 5 +++++ 6 files changed, 48 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index bc04c830f1..c5acf9decb 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -322,11 +322,15 @@ static NTSTATUS notify_remove_all(struct notify_context *notify) see if a notify event matches */ static BOOL notify_match(struct notify_context *notify, struct notify_entry *e, - const char *path, uint32_t action) + const char *path, uint32_t filter) { - size_t len = strlen(e->path); + size_t len; - /* TODO: check action */ + if (!(filter & e->filter)) { + return False; + } + + len = strlen(e->path); if (strncmp(path, e->path, len) != 0) { return False; @@ -379,7 +383,7 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, trigger a notify message for anyone waiting on a matching event */ void notify_trigger(struct notify_context *notify, - uint32_t action, const char *path) + uint32_t action, uint32_t filter, const char *path) { NTSTATUS status; int i; @@ -391,7 +395,7 @@ void notify_trigger(struct notify_context *notify, /* this needs to be changed to a log(n) search */ for (i=0;iarray->num_entries;i++) { - if (notify_match(notify, ¬ify->array->entries[i], path, action)) { + if (notify_match(notify, ¬ify->array->entries[i], path, filter)) { notify_send(notify, ¬ify->array->entries[i], path + strlen(notify->array->entries[i].path) + 1, action); diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 5ec7df3b9d..cd83c9de43 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -83,7 +83,10 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, return status; } - notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name); + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_ADDED, + FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + name->full_name); return NT_STATUS_OK; } @@ -137,7 +140,10 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, return status; } - notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name); + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_ADDED, + FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + name->full_name); return NT_STATUS_OK; } @@ -176,7 +182,10 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } - notify_trigger(pvfs->notify_context, NOTIFY_ACTION_REMOVED, name->full_name); + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + name->full_name); return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 38123c3a9e..264234a09b 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -378,6 +378,11 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->have_opendb_entry = True; create_action = NTCREATEX_ACTION_CREATED; + + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + name->full_name); } else { create_action = NTCREATEX_ACTION_EXISTED; } @@ -461,6 +466,11 @@ static int pvfs_handle_destructor(void *p) if (unlink(path) != 0) { DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", path, strerror(errno))); + } else { + notify_trigger(h->pvfs->notify_context, + NOTIFY_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME, + path); } } @@ -730,7 +740,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* success - keep the file handle */ talloc_steal(pvfs, f); - notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name); + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_ADDED, + FILE_NOTIFY_CHANGE_FILE_NAME, + name->full_name); return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 411fbd9c27..f30c4d6e38 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -90,5 +90,10 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, rd->readx.out.remaining = 0xFFFF; rd->readx.out.compaction_mode = 0; + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_LAST_ACCESS, + f->handle->name->full_name); + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 3a6e4bba2f..4477360deb 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -104,7 +104,9 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, } if (NT_STATUS_IS_OK(status)) { - notify_trigger(pvfs->notify_context, NOTIFY_ACTION_REMOVED, + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME, name->full_name); } diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 9c23b3e4fd..15e3526176 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -84,6 +84,11 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, wr->writex.out.nwritten = ret; wr->writex.out.remaining = 0; /* should fill this in? */ + + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, + f->handle->name->full_name); return NT_STATUS_OK; } -- cgit From 24bacd111334b34d4c52135eea9b466e3a28a8f9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 04:55:03 +0000 Subject: r14800: use tdb_get_seqnum() in the change notify code to avoid reloading the notify record if the tdb has not changed. This makes the notify_trigger() call much faster, which is important as it is called on just about every file operation (This used to be commit d09b8761bfda7dfbb4c7a5c4a4f4359ba01923a3) --- source4/ntvfs/common/notify.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index c5acf9decb..b71c2906ae 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -40,6 +40,7 @@ struct notify_context { struct messaging_context *messaging_ctx; struct notify_list *list; struct notify_array *array; + int seqnum; }; @@ -84,8 +85,8 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, path = smbd_tmp_path(notify, "notify.tdb"); notify->w = tdb_wrap_open(notify, path, 0, - TDB_DEFAULT, - O_RDWR|O_CREAT, 0600); + TDB_SEQNUM, + O_RDWR|O_CREAT, 0600); talloc_free(path); if (notify->w == NULL) { talloc_free(notify); @@ -96,6 +97,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, notify->messaging_ctx = messaging_ctx; notify->list = NULL; notify->array = NULL; + notify->seqnum = tdb_get_seqnum(notify->w->tdb); talloc_set_destructor(notify, notify_destructor); @@ -115,6 +117,15 @@ static NTSTATUS notify_load(struct notify_context *notify) TDB_DATA dbuf; DATA_BLOB blob; NTSTATUS status; + int seqnum; + + seqnum = tdb_get_seqnum(notify->w->tdb); + + if (seqnum == notify->seqnum && notify->array != NULL) { + return NT_STATUS_OK; + } + + notify->seqnum = seqnum; talloc_free(notify->array); notify->array = talloc_zero(notify, struct notify_array); -- cgit From aec7f3ae721bff48e63cc3abcee07b18fa13417a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 05:45:43 +0000 Subject: r14803: copy with the root directory, which has /. on the end of the path (This used to be commit 16742cd28621d205f21c855e5635be1dfc3f2b69) --- source4/ntvfs/common/notify.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index b71c2906ae..52abc08d74 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -227,6 +227,8 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, { NTSTATUS status; struct notify_list *listel; + char *path = NULL; + size_t len; status = notify_load(notify); NT_STATUS_NOT_OK_RETURN(status); @@ -239,14 +241,29 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, return NT_STATUS_NO_MEMORY; } + /* cope with /. on the end of the path */ + len = strlen(e->path); + if (len > 1 && e->path[len-1] == '.' && e->path[len-2] == '/') { + path = talloc_strndup(notify, e->path, len-2); + } + notify->array->entries[notify->array->num_entries] = *e; notify->array->entries[notify->array->num_entries].private = private; notify->array->entries[notify->array->num_entries].server = notify->server; + + if (path) { + notify->array->entries[notify->array->num_entries].path = path; + } + notify->array->num_entries++; status = notify_save(notify); NT_STATUS_NOT_OK_RETURN(status); + if (path) { + talloc_free(path); + } + listel = talloc(notify, struct notify_list); NT_STATUS_HAVE_NO_MEMORY(listel); -- cgit From 6942d1d62c23ea2e43469485c0e0503d3906760c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 06:07:38 +0000 Subject: r14805: use tdb_lock_bystring() to prevent race conditions in notify add/remove (This used to be commit a6be44f78ca2eaecbf0b6d8598addba5a11ae966) --- source4/ntvfs/common/notify.c | 61 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 56 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 52abc08d74..dd39aca095 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -109,6 +109,26 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, return notify; } + +/* + lock the notify db +*/ +static NTSTATUS notify_lock(struct notify_context *notify) +{ + if (tdb_lock_bystring(notify->w->tdb, NOTIFY_KEY) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return NT_STATUS_OK; +} + +/* + unlock the notify db +*/ +static void notify_unlock(struct notify_context *notify) +{ + tdb_unlock_bystring(notify->w->tdb, NOTIFY_KEY); +} + /* load the notify array */ @@ -230,14 +250,21 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, char *path = NULL; size_t len; - status = notify_load(notify); + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); + status = notify_load(notify); + if (!NT_STATUS_IS_OK(status)) { + notify_unlock(notify); + return status; + } + notify->array->entries = talloc_realloc(notify->array, notify->array->entries, struct notify_entry, notify->array->num_entries+1); if (notify->array->entries == NULL) { + notify_unlock(notify); return NT_STATUS_NO_MEMORY; } @@ -258,6 +285,9 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, notify->array->num_entries++; status = notify_save(notify); + + notify_unlock(notify); + NT_STATUS_NOT_OK_RETURN(status); if (path) { @@ -293,9 +323,15 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = notify_load(notify); + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); + status = notify_load(notify); + if (!NT_STATUS_IS_OK(status)) { + notify_unlock(notify); + return status; + } + for (i=0;iarray->num_entries;i++) { if (notify->server == notify->array->entries[i].server && private == notify->array->entries[i].private) { @@ -303,6 +339,7 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) } } if (i == notify->array->num_entries) { + notify_unlock(notify); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -312,7 +349,11 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) } notify->array->num_entries--; - return notify_save(notify); + status = notify_save(notify); + + notify_unlock(notify); + + return status; } /* @@ -327,9 +368,15 @@ static NTSTATUS notify_remove_all(struct notify_context *notify) return NT_STATUS_OK; } - status = notify_load(notify); + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); + status = notify_load(notify); + if (!NT_STATUS_IS_OK(status)) { + notify_unlock(notify); + return status; + } + for (i=0;iarray->num_entries;i++) { if (notify->server == notify->array->entries[i].server) { if (i < notify->array->num_entries-1) { @@ -342,7 +389,11 @@ static NTSTATUS notify_remove_all(struct notify_context *notify) } - return notify_save(notify); + status = notify_save(notify); + + notify_unlock(notify); + + return status; } -- cgit From be0a00726f121de03e3580db898e062237408b27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 30 Mar 2006 09:24:31 +0000 Subject: r14808: added notify_trigger() calls for rename and setfileinfo calls (This used to be commit adb4ea32e2d5506cb213ea4c0715918042fba084) --- source4/ntvfs/posix/pvfs_rename.c | 7 +++++++ source4/ntvfs/posix/pvfs_setfileinfo.c | 36 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 8629ecabf2..e69cbcde0b 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -180,6 +180,13 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, status = odb_rename(lck, fname2); + if (NT_STATUS_IS_OK(status)) { + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_FILE_NAME, + name1->full_name); + } + failed: talloc_free(mem_ctx); return status; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 4997207a8b..72c061078c 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -151,6 +151,11 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return pvfs_map_errno(pvfs, errno); } + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_FILE_NAME, + name->full_name); + name->full_name = talloc_steal(name, name2->full_name); name->original_name = talloc_steal(name, name2->original_name); @@ -225,6 +230,11 @@ NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs, return status; } + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_EA, + name->full_name); + name->dos.ea_size = 4; for (i=0;inum_eas;i++) { name->dos.ea_size += 4 + strlen(ealist->eas[i].name)+1 + @@ -249,6 +259,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct pvfs_filename newstats; NTSTATUS status; uint32_t access_needed; + uint32_t change_mask = 0; f = pvfs_find_fd(pvfs, req, info->generic.in.file.fnum); if (!f) { @@ -287,6 +298,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_STANDARD: if (!null_time(info->setattre.in.create_time)) { unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time); + change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_time(info->setattre.in.access_time)) { unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time); @@ -305,6 +317,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_BASIC_INFORMATION: if (!null_nttime(info->basic_info.in.create_time)) { newstats.dos.create_time = info->basic_info.in.create_time; + change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_nttime(info->basic_info.in.access_time)) { newstats.dos.access_time = info->basic_info.in.access_time; @@ -362,6 +375,10 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, info); case RAW_SFILEINFO_SEC_DESC: + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_SECURITY, + h->name->full_name); return pvfs_acl_set(pvfs, req, h->name, h->fd, f->access_mask, info); default: @@ -378,6 +395,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, if (!NT_STATUS_IS_OK(status)) { return status; } + + change_mask |= FILE_NOTIFY_CHANGE_STREAM_SIZE; } else { int ret; if (f->access_mask & @@ -389,6 +408,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, if (ret == -1) { return pvfs_map_errno(pvfs, errno); } + change_mask |= FILE_NOTIFY_CHANGE_SIZE; } } @@ -396,9 +416,11 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, ZERO_STRUCT(unix_times); if (newstats.dos.access_time != h->name->dos.access_time) { unix_times.actime = nt_time_to_unix(newstats.dos.access_time); + change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS; } if (newstats.dos.write_time != h->name->dos.write_time) { unix_times.modtime = nt_time_to_unix(newstats.dos.write_time); + change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE; } if (unix_times.actime != 0 || unix_times.modtime != 0) { if (utime(h->name->full_name, &unix_times) == -1) { @@ -414,10 +436,16 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } } + change_mask |= FILE_NOTIFY_CHANGE_ATTRIBUTES; } *h->name = newstats; + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + change_mask, + h->name->full_name); + return pvfs_dosattrib_save(pvfs, h->name, h->fd); } @@ -434,6 +462,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct utimbuf unix_times; uint32_t access_needed; + uint32_t change_mask = 0; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, @@ -471,6 +500,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_STANDARD: if (!null_time(info->setattre.in.create_time)) { unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time); + change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_time(info->setattre.in.access_time)) { unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time); @@ -489,6 +519,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_BASIC_INFORMATION: if (!null_nttime(info->basic_info.in.create_time)) { newstats.dos.create_time = info->basic_info.in.create_time; + change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_nttime(info->basic_info.in.access_time)) { newstats.dos.access_time = info->basic_info.in.access_time; @@ -583,6 +614,11 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, *name = newstats; + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + change_mask, + name->full_name); + return pvfs_dosattrib_save(pvfs, name, -1); } -- cgit From 96b5dd789be8468ca73665dc47da3779aaefe609 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 30 Mar 2006 13:56:25 +0000 Subject: r14822: if we use the snum used by the lp_* functions instead of the wire TID, then don't use tid as name... metze (This used to be commit d41d48caf209fec9f5f04d38d75277b1cfeed22f) --- source4/ntvfs/common/brlock.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index ddbab257bc..bc9d8b1288 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -48,7 +48,7 @@ struct lock_context { uint32_t server; uint16_t smbpid; - uint16_t tid; + int snum; }; /* The data in brlock records is an unsorted linear array of these @@ -66,7 +66,7 @@ struct lock_struct { struct brl_context { struct tdb_wrap *w; uint32_t server; - uint16_t tid; + int snum; struct messaging_context *messaging_ctx; struct lock_struct last_lock; }; @@ -77,7 +77,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, uint16_t tid, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, int snum, struct messaging_context *messaging_ctx) { char *path; @@ -98,7 +98,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, uint16_t tid, } brl->server = server; - brl->tid = tid; + brl->snum = snum; brl->messaging_ctx = messaging_ctx; ZERO_STRUCT(brl->last_lock); @@ -113,7 +113,7 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx { return (ctx1->server == ctx2->server && ctx1->smbpid == ctx2->smbpid && - ctx1->tid == ctx2->tid); + ctx1->snum == ctx2->snum); } /* @@ -200,7 +200,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) { if (lock->context.server == brl->last_lock.context.server && - lock->context.tid == brl->last_lock.context.tid && + lock->context.snum == brl->last_lock.context.snum && lock->fnum == brl->last_lock.fnum && lock->start == brl->last_lock.start && lock->size == brl->last_lock.size) { @@ -263,7 +263,7 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.tid = brl->tid; + lock.context.snum = brl->snum; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -398,7 +398,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, context.smbpid = smbpid; context.server = brl->server; - context.tid = brl->tid; + context.snum = brl->snum; /* there are existing locks - find a match */ locks = (struct lock_struct *)dbuf.dptr; @@ -548,7 +548,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.tid = brl->tid; + lock.context.snum = brl->snum; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -601,7 +601,7 @@ NTSTATUS brl_close(struct brl_context *brl, for (i=0; icontext.tid == brl->tid && + if (lock->context.snum == brl->snum && lock->context.server == brl->server && lock->fnum == fnum) { /* found it - delete it */ -- cgit From 07372df2fae85aaabc3858aa87466b50882cbd76 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 Mar 2006 03:02:39 +0000 Subject: r14835: split out the config rules for the ntvfs/common/ directory (This used to be commit 33495d19cf0263f6df5ec935f51c68bde84b1d01) --- source4/ntvfs/common/config.mk | 13 +++++++++++++ source4/ntvfs/config.mk | 7 ++----- 2 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 source4/ntvfs/common/config.mk (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk new file mode 100644 index 0000000000..e10f0fc8c1 --- /dev/null +++ b/source4/ntvfs/common/config.mk @@ -0,0 +1,13 @@ +################################################ +# Start MODULE ntvfs_common +[MODULE::ntvfs_common] +SUBSYSTEM = ntvfs +PRIVATE_PROTO_HEADER = vfs_common_proto.h +OBJ_FILES = \ + brlock.o \ + opendb.o \ + notify.o \ + sidmap.o +REQUIRED_SUBSYSTEMS = +# End MODULE ntvfs_common +################################################ diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index eb675c38e3..f17097e356 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -1,5 +1,6 @@ # NTVFS Server subsystem include posix/config.mk +include common/config.mk include unixuid/config.mk ################################################ @@ -75,11 +76,7 @@ OBJ_FILES = \ ntvfs_base.o \ ntvfs_generic.o \ ntvfs_interface.o \ - ntvfs_util.o \ - common/brlock.o \ - common/opendb.o \ - common/notify.o \ - common/sidmap.o + ntvfs_util.o REQUIRED_SUBSYSTEMS = NDR_OPENDB NDR_NOTIFY # # End SUBSYSTEM NTVFS -- cgit From 05c53f70f0e4b94cf26a433cb61b1706f7715757 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 Mar 2006 09:47:57 +0000 Subject: r14838: fix the build. Looks like I still haven't quite got the hang of the new dependency/proto system :-) (This used to be commit 63ae3f21e3471895ba83df1c2fdc4147090f7fdb) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/posix/vfs_posix.h | 1 + source4/ntvfs/unixuid/vfs_unixuid.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index e10f0fc8c1..6eb9073b73 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -2,7 +2,7 @@ # Start MODULE ntvfs_common [MODULE::ntvfs_common] SUBSYSTEM = ntvfs -PRIVATE_PROTO_HEADER = vfs_common_proto.h +PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = \ brlock.o \ opendb.o \ diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 00ae92a95a..f34529bc0f 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -26,6 +26,7 @@ #include "librpc/gen_ndr/xattr.h" #include "system/filesys.h" #include "ntvfs/ntvfs.h" +#include "ntvfs/common/proto.h" /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 9d8b058b7a..1bfaf85e70 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -26,6 +26,7 @@ #include "system/passwd.h" #include "auth/auth.h" #include "ntvfs/ntvfs.h" +#include "ntvfs/common/proto.h" struct unixuid_private { struct sidmap_context *sidmap; -- cgit From 1af925f394b1084779f5b1b5a10c2ec512d7e5be Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 2 Apr 2006 12:02:01 +0000 Subject: r14860: create libcli/security/security.h metze (This used to be commit 9ec706238c173992dc938d537bdf1103bf519dbf) --- source4/ntvfs/common/sidmap.c | 2 +- source4/ntvfs/posix/pvfs_acl.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index c22d29a723..cac238c70d 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -27,7 +27,7 @@ #include "auth/auth.h" #include "libcli/ldap/ldap.h" #include "db_wrap.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_security.h" /* diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index f7647ae3e4..53ee63dc0a 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -24,7 +24,7 @@ #include "auth/auth.h" #include "vfs_posix.h" #include "librpc/gen_ndr/xattr.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" /* diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 28cf2cc6cd..d161dac5a4 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -29,7 +29,7 @@ #include "librpc/gen_ndr/security.h" #include "lib/tdb/include/tdb.h" #include "db_wrap.h" -#include "libcli/security/proto.h" +#include "libcli/security/security.h" /* -- cgit From 6d98076c15e8726606da0a99714cd3382d82f9ac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Apr 2006 06:46:55 +0000 Subject: r14877: added support for the kernel inotify mechanism. This passes basic tests, but still needs some more work to ensure we correctly cope with events that may generate both a system inotify event and a internal notify event. The system inotify events won't handle recursion, and don't understand things like streams. This also adds the ntvfs/sysdep/ directory, which is meant for system dependent code that is not tied to a particular ntvfs backend. The inotify code is a good example of that. (This used to be commit eadadbb44adb3c4081d6ff1d85a9b850a0227059) --- source4/ntvfs/common/notify.c | 137 +++++++++++------ source4/ntvfs/config.mk | 1 + source4/ntvfs/posix/vfs_posix.c | 4 +- source4/ntvfs/sysdep/README | 5 + source4/ntvfs/sysdep/config.m4 | 7 + source4/ntvfs/sysdep/config.mk | 20 +++ source4/ntvfs/sysdep/inotify.c | 313 ++++++++++++++++++++++++++++++++++++++ source4/ntvfs/sysdep/sys_notify.c | 96 ++++++++++++ source4/ntvfs/sysdep/sys_notify.h | 52 +++++++ 9 files changed, 586 insertions(+), 49 deletions(-) create mode 100644 source4/ntvfs/sysdep/README create mode 100644 source4/ntvfs/sysdep/config.m4 create mode 100644 source4/ntvfs/sysdep/config.mk create mode 100644 source4/ntvfs/sysdep/inotify.c create mode 100644 source4/ntvfs/sysdep/sys_notify.c create mode 100644 source4/ntvfs/sysdep/sys_notify.h (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index dd39aca095..595a0f6566 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -33,6 +33,7 @@ #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_notify.h" #include "dlinklist.h" +#include "ntvfs/sysdep/sys_notify.h" struct notify_context { struct tdb_wrap *w; @@ -41,6 +42,7 @@ struct notify_context { struct notify_list *list; struct notify_array *array; int seqnum; + struct sys_notify_context *sys_notify_ctx; }; @@ -48,6 +50,7 @@ struct notify_list { struct notify_list *next, *prev; void *private; void (*callback)(void *, const struct notify_event *); + void *sys_notify_handle; }; #define NOTIFY_KEY "notify array" @@ -73,7 +76,8 @@ static int notify_destructor(void *p) via internal messages */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, - struct messaging_context *messaging_ctx) + struct messaging_context *messaging_ctx, + struct event_context *ev) { char *path; struct notify_context *notify; @@ -106,6 +110,8 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, messaging_register(notify->messaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); + notify->sys_notify_ctx = sys_notify_init(-1, notify, ev); + return notify; } @@ -166,6 +172,14 @@ static NTSTATUS notify_load(struct notify_context *notify) return status; } +/* + compare notify entries for sorting +*/ +static int notify_compare(const void *p1, const void *p2) +{ + const struct notify_entry *e1 = p1, *e2 = p2; + return strcmp(e1->path, e2->path); +} /* save the notify array @@ -186,6 +200,11 @@ static NTSTATUS notify_save(struct notify_context *notify) return NT_STATUS_OK; } + if (notify->array->num_entries > 1) { + qsort(notify->array->entries, notify->array->num_entries, + sizeof(struct notify_entry), notify_compare); + } + tmp_ctx = talloc_new(notify); status = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, @@ -237,6 +256,17 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private, talloc_free(tmp_ctx); } +/* + callback from sys_notify telling us about changes from the OS +*/ +static void sys_notify_callback(struct sys_notify_context *ctx, + void *ptr, struct notify_event *ev) +{ + struct notify_list *listel = talloc_get_type(ptr, struct notify_list); + ev->private = listel; + listel->callback(listel->private, ev); +} + /* add a notify watch. This is called when a notify is first setup on a open directory handle. @@ -274,33 +304,42 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, path = talloc_strndup(notify, e->path, len-2); } - notify->array->entries[notify->array->num_entries] = *e; - notify->array->entries[notify->array->num_entries].private = private; - notify->array->entries[notify->array->num_entries].server = notify->server; + listel = talloc_zero(notify, struct notify_list); + NT_STATUS_HAVE_NO_MEMORY(listel); - if (path) { - notify->array->entries[notify->array->num_entries].path = path; - } + listel->private = private; + listel->callback = callback; + DLIST_ADD(notify->list, listel); - notify->array->num_entries++; + /* ignore failures from sys_notify */ + status = sys_notify_watch(notify->sys_notify_ctx, e->path, e->filter, + sys_notify_callback, listel, + &listel->sys_notify_handle); + if (NT_STATUS_IS_OK(status)) { + talloc_steal(listel, listel->sys_notify_handle); + notify_unlock(notify); + } else { + notify->array->entries[notify->array->num_entries] = *e; + notify->array->entries[notify->array->num_entries].private = private; + notify->array->entries[notify->array->num_entries].server = notify->server; - status = notify_save(notify); + if (path) { + notify->array->entries[notify->array->num_entries].path = path; + } - notify_unlock(notify); + notify->array->num_entries++; - NT_STATUS_NOT_OK_RETURN(status); + status = notify_save(notify); + + notify_unlock(notify); + + NT_STATUS_NOT_OK_RETURN(status); + } if (path) { talloc_free(path); } - listel = talloc(notify, struct notify_list); - NT_STATUS_HAVE_NO_MEMORY(listel); - - listel->private = private; - listel->callback = callback; - DLIST_ADD(notify->list, listel); - return status; } @@ -323,6 +362,8 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + talloc_free(listel); + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); @@ -397,6 +438,35 @@ static NTSTATUS notify_remove_all(struct notify_context *notify) } +/* + send a notify message to another messaging server +*/ +static void notify_send(struct notify_context *notify, struct notify_entry *e, + const char *path, uint32_t action) +{ + struct notify_event ev; + DATA_BLOB data; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + ev.action = action; + ev.path = path; + ev.private = e->private; + + tmp_ctx = talloc_new(notify); + + status = ndr_push_struct_blob(&data, tmp_ctx, &ev, + (ndr_push_flags_fn_t)ndr_push_notify_event); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return; + } + + status = messaging_send(notify->messaging_ctx, e->server, + MSG_PVFS_NOTIFY, &data); + talloc_free(tmp_ctx); +} + /* see if a notify event matches */ @@ -429,35 +499,6 @@ static BOOL notify_match(struct notify_context *notify, struct notify_entry *e, } -/* - send a notify message to another messaging server -*/ -static void notify_send(struct notify_context *notify, struct notify_entry *e, - const char *path, uint32_t action) -{ - struct notify_event ev; - DATA_BLOB data; - NTSTATUS status; - TALLOC_CTX *tmp_ctx; - - ev.action = action; - ev.path = path; - ev.private = e->private; - - tmp_ctx = talloc_new(notify); - - status = ndr_push_struct_blob(&data, tmp_ctx, &ev, - (ndr_push_flags_fn_t)ndr_push_notify_event); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return; - } - - status = messaging_send(notify->messaging_ctx, e->server, - MSG_PVFS_NOTIFY, &data); - talloc_free(tmp_ctx); -} - /* trigger a notify message for anyone waiting on a matching event */ @@ -472,7 +513,7 @@ void notify_trigger(struct notify_context *notify, return; } - /* this needs to be changed to a log(n) search */ + /* TODO: this needs to be changed to a log(n) search */ for (i=0;iarray->num_entries;i++) { if (notify_match(notify, ¬ify->array->entries[i], path, filter)) { notify_send(notify, ¬ify->array->entries[i], diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index f17097e356..2a35bd5cb3 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -2,6 +2,7 @@ include posix/config.mk include common/config.mk include unixuid/config.mk +include sysdep/config.mk ################################################ # Start MODULE ntvfs_cifs diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index d161dac5a4..c279350e2f 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -30,6 +30,7 @@ #include "lib/tdb/include/tdb.h" #include "db_wrap.h" #include "libcli/security/security.h" +#include "lib/events/events.h" /* @@ -186,7 +187,8 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->notify_context = notify_init(pvfs, pvfs->ntvfs->ctx->server_id, - pvfs->ntvfs->ctx->msg_ctx); + pvfs->ntvfs->ctx->msg_ctx, + event_context_find(pvfs)); if (pvfs->notify_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/sysdep/README b/source4/ntvfs/sysdep/README new file mode 100644 index 0000000000..a2a8f57c28 --- /dev/null +++ b/source4/ntvfs/sysdep/README @@ -0,0 +1,5 @@ +This directory contains OS depdendent interfaces to facilities that +are only available on a few of our target systems, and require +substantial code to abstract. + + diff --git a/source4/ntvfs/sysdep/config.m4 b/source4/ntvfs/sysdep/config.m4 new file mode 100644 index 0000000000..f67a3bdace --- /dev/null +++ b/source4/ntvfs/sysdep/config.m4 @@ -0,0 +1,7 @@ +AC_CHECK_HEADERS(linux/inotify.h asm/unistd.h) +AC_CHECK_FUNC(inotify_init) + +SMB_ENABLE(ntvfs_inotify, NO) +if test x"$ac_cv_header_linux_inotify_h" = x"yes"; then + SMB_ENABLE(ntvfs_inotify, YES) +fi diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk new file mode 100644 index 0000000000..3bcebb5c0e --- /dev/null +++ b/source4/ntvfs/sysdep/config.mk @@ -0,0 +1,20 @@ +################################################ +# Start MODULE ntvfs_sys_notify +[MODULE::ntvfs_sys_notify] +SUBSYSTEM = ntvfs +OBJ_FILES = \ + sys_notify.o +# End MODULE ntvfs_sys_notify +################################################ + + +################################################ +# Start MODULE ntvfs_inotify +[MODULE::ntvfs_inotify] +SUBSYSTEM = ntvfs +INIT_FUNCTION = ntvfs_inotify_init +OBJ_FILES = \ + inotify.o +# End MODULE ntvfs_inotify +################################################ + diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c new file mode 100644 index 0000000000..31c408d112 --- /dev/null +++ b/source4/ntvfs/sysdep/inotify.c @@ -0,0 +1,313 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + notify implementation using inotify +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "ntvfs/sysdep/sys_notify.h" +#include "lib/events/events.h" +#include "smb.h" +#include "dlinklist.h" + +#include +#include + +#ifndef HAVE_INOTIFY_INIT +/* + glibc doesn't define these functions yet (as of March 2006) +*/ +static int inotify_init(void) +{ + return syscall(__NR_inotify_init); +} + +static int inotify_add_watch(int fd, const char *path, __u32 mask) +{ + return syscall(__NR_inotify_add_watch, fd, path, mask); +} + +static int inotify_rm_watch(int fd, int wd) +{ + return syscall(__NR_inotify_rm_watch, fd, wd); +} +#endif + + +/* older glibc headers don't have these defines either */ +#ifndef IN_ONLYDIR +#define IN_ONLYDIR 0x01000000 +#endif +#ifndef IN_MASK_ADD +#define IN_MASK_ADD 0x20000000 +#endif + +struct inotify_private { + struct sys_notify_context *ctx; + int fd; + struct watch_context *watches; +}; + +struct watch_context { + struct watch_context *next, *prev; + struct inotify_private *in; + int wd; + sys_notify_callback_t callback; + void *private; + uint32_t mask; +}; + + +/* + destroy the inotify private context +*/ +static int inotify_destructor(void *ptr) +{ + struct inotify_private *in = talloc_get_type(ptr, struct inotify_private); + close(in->fd); + return 0; +} + + +/* + dispatch one inotify event +*/ +static void inotify_dispatch(struct inotify_private *in, struct inotify_event *e) +{ + struct watch_context *w; + struct notify_event ne; + + /* ignore extraneous events, such as unmount and IN_IGNORED events */ + if ((e->mask & (IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO)) == 0) { + return; + } + + /* map the inotify mask to a action */ + if (e->mask & IN_CREATE) { + ne.action = NOTIFY_ACTION_ADDED; + } else if (e->mask & IN_DELETE) { + ne.action = NOTIFY_ACTION_REMOVED; + } else { + ne.action = NOTIFY_ACTION_MODIFIED; + } + ne.path = e->name; + + /* find any watches that have this watch descriptor */ + for (w=in->watches;w;w=w->next) { + /* checking the mask copes with multiple watches */ + if (w->wd == e->wd && (e->mask & w->mask) != 0) { + w->callback(in->ctx, w->private, &ne); + } + } +} + +/* + called when the kernel has some events for us +*/ +static void inotify_handler(struct event_context *ev, struct fd_event *fde, + uint16_t flags, void *private) +{ + struct inotify_private *in = talloc_get_type(private, struct inotify_private); + int bufsize = 0; + struct inotify_event *e0, *e; + + /* + we must use FIONREAD as we cannot predict the length of the + filenames, and thus can't know how much to allocate + otherwise + */ + if (ioctl(in->fd, FIONREAD, &bufsize) != 0 || + bufsize == 0) { + DEBUG(0,("No data on inotify fd?!\n")); + return; + } + + e0 = e = talloc_size(in, bufsize); + if (e == NULL) return; + + if (read(in->fd, e0, bufsize) != bufsize) { + DEBUG(0,("Failed to read all inotify data\n")); + talloc_free(e0); + return; + } + + /* we can get more than one event in the buffer */ + while (bufsize >= sizeof(*e)) { + inotify_dispatch(in, e); + bufsize -= e->len + sizeof(*e); + e = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); + } + + talloc_free(e0); +} + +/* + setup the inotify handle - called the first time a watch is added on + this context +*/ +static NTSTATUS inotify_setup(struct sys_notify_context *ctx) +{ + struct inotify_private *in; + + in = talloc(ctx, struct inotify_private); + NT_STATUS_HAVE_NO_MEMORY(in); + in->fd = inotify_init(); + if (in->fd == -1) { + DEBUG(0,("Failed to init inotify - %s\n", strerror(errno))); + talloc_free(in); + return map_nt_error_from_unix(errno); + } + in->ctx = ctx; + in->watches = NULL; + + ctx->private = in; + talloc_set_destructor(in, inotify_destructor); + + /* add a event waiting for the inotify fd to be readable */ + event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ, inotify_handler, in); + + return NT_STATUS_OK; +} + + +/* + map from a change notify mask to a inotify mask. Approximate only :( +*/ +static const struct { + uint32_t notify_mask; + uint32_t inotify_mask; +} inotify_mapping[] = { + {FILE_NOTIFY_CHANGE_FILE_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, + {FILE_NOTIFY_CHANGE_ATTRIBUTES, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_SIZE, IN_MODIFY}, + {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} +}; + +static uint32_t inotify_map(uint32_t mask) +{ + int i; + uint32_t out=0; + for (i=0;iin; + int wd = w->wd; + DLIST_REMOVE(w->in->watches, w); + + /* only rm the watch if its the last one with this wd */ + for (w=in->watches;w;w=w->next) { + if (w->wd == wd) break; + } + if (w == NULL) { + inotify_rm_watch(in->fd, wd); + } + return 0; +} + + +/* + add a watch. The watch is removed when the caller calls + talloc_free() on handle +*/ +static NTSTATUS inotify_watch(struct sys_notify_context *ctx, const char *dirpath, + uint32_t filter, sys_notify_callback_t callback, + void *private, void **handle) +{ + struct inotify_private *in; + int wd; + uint32_t mask; + struct watch_context *w; + + /* maybe setup the inotify fd */ + if (ctx->private == NULL) { + NTSTATUS status; + status = inotify_setup(ctx); + NT_STATUS_NOT_OK_RETURN(status); + } + + in = talloc_get_type(ctx->private, struct inotify_private); + + mask = inotify_map(filter); + if (mask == 0) { + /* this filter can't be handled by inotify */ + return NT_STATUS_INVALID_PARAMETER; + } + + /* using IN_MASK_ADD allows us to cope with inotify() returning the same + watch descriptor for muliple watches on the same path */ + mask |= (IN_MASK_ADD | IN_ONLYDIR); + + /* get a new watch descriptor for this path */ + wd = inotify_add_watch(in->fd, dirpath, mask); + if (wd == -1) { + return map_nt_error_from_unix(errno); + } + + w = talloc(in, struct watch_context); + if (w == NULL) { + inotify_rm_watch(in->fd, wd); + return NT_STATUS_NO_MEMORY; + } + + w->in = in; + w->wd = wd; + w->callback = callback; + w->private = private; + w->mask = mask; + + (*handle) = w; + + DLIST_ADD(in->watches, w); + + /* the caller frees the handle to stop watching */ + talloc_set_destructor(w, watch_destructor); + + return NT_STATUS_OK; +} + + +static struct sys_notify_backend inotify = { + .name = "inotify", + .notify_watch = inotify_watch +}; + +/* + initialialise the inotify module + */ +NTSTATUS ntvfs_inotify_init(void) +{ + /* register ourselves as a system inotify module */ + return sys_notify_register(&inotify); +} diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c new file mode 100644 index 0000000000..aedfd2a7de --- /dev/null +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -0,0 +1,96 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + abstract the various kernel interfaces to change notify into a + single Samba friendly interface +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "ntvfs/sysdep/sys_notify.h" +#include "lib/events/events.h" +#include "dlinklist.h" + +/* list of registered backends */ +static struct sys_notify_backend *backends; + + +/* + initialise a system change notify backend +*/ +struct sys_notify_context *sys_notify_init(int snum, + TALLOC_CTX *mem_ctx, + struct event_context *ev) +{ + struct sys_notify_context *ctx; + const char *bname; + struct sys_notify_backend *b; + + if (backends == NULL) { + return NULL; + } + + if (ev == NULL) { + ev = event_context_find(mem_ctx); + } + + ctx = talloc_zero(mem_ctx, struct sys_notify_context); + if (ctx == NULL) { + return NULL; + } + + ctx->ev = ev; + + bname = lp_parm_string(snum, "notify", "backend"); + if (bname == NULL) { + bname = backends->name; + } + + for (b=backends;b;b=b->next) { + if (strcasecmp(b->name, bname) == 0) break; + } + + if (b != NULL) { + ctx->name = b->name; + ctx->notify_watch = b->notify_watch; + } + + return ctx; +} + +/* + add a watch +*/ +NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, const char *dirpath, + uint32_t filter, sys_notify_callback_t callback, + void *private, void **handle) +{ + return ctx->notify_watch(ctx, dirpath, filter, callback, private, handle); +} + +/* + register a notify backend +*/ +NTSTATUS sys_notify_register(struct sys_notify_backend *backend) +{ + DLIST_ADD(backends, backend); + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h new file mode 100644 index 0000000000..9ad5ed7555 --- /dev/null +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -0,0 +1,52 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "librpc/gen_ndr/notify.h" + +struct sys_notify_context; + +typedef void (*sys_notify_callback_t)(struct sys_notify_context *, + void *, struct notify_event *ev); + +struct sys_notify_context { + struct event_context *ev; + void *private; /* for use of backend */ + NTSTATUS (*notify_watch)(struct sys_notify_context *ctx, const char *dirpath, + uint32_t filter, sys_notify_callback_t callback, + void *private, void **handle); + const char *name; +}; + +struct sys_notify_backend { + struct sys_notify_backend *next, *prev; + const char *name; + NTSTATUS (*notify_watch)(struct sys_notify_context *ctx, const char *dirpath, + uint32_t filter, sys_notify_callback_t callback, + void *private, void **handle); +}; + +NTSTATUS sys_notify_register(struct sys_notify_backend *backend); +struct sys_notify_context *sys_notify_init(int snum, + TALLOC_CTX *mem_ctx, + struct event_context *ev); +NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, const char *dirpath, + uint32_t filter, sys_notify_callback_t callback, + void *private, void **handle); + -- cgit From 770edafbf2e284b246fb29e936a19476eacde87f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 4 Apr 2006 16:58:28 +0000 Subject: r14912: don't crash if inotify isn't present... metze (This used to be commit 953aa7887b310117a05a59291f3770a9beb5e1eb) --- source4/ntvfs/sysdep/sys_notify.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index aedfd2a7de..fd29f42a0e 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -44,10 +44,6 @@ struct sys_notify_context *sys_notify_init(int snum, const char *bname; struct sys_notify_backend *b; - if (backends == NULL) { - return NULL; - } - if (ev == NULL) { ev = event_context_find(mem_ctx); } @@ -60,16 +56,25 @@ struct sys_notify_context *sys_notify_init(int snum, ctx->ev = ev; bname = lp_parm_string(snum, "notify", "backend"); - if (bname == NULL) { - bname = backends->name; + if (!bname) { + if (backends) { + bname = backends->name; + } else { + bname = "__unknown__"; + } } for (b=backends;b;b=b->next) { - if (strcasecmp(b->name, bname) == 0) break; + if (strcasecmp(b->name, bname) == 0) { + bname = b->name; + break; + } } + ctx->name = bname; + ctx->notify_watch = NULL; + if (b != NULL) { - ctx->name = b->name; ctx->notify_watch = b->notify_watch; } @@ -83,6 +88,9 @@ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, const char *dirpath, uint32_t filter, sys_notify_callback_t callback, void *private, void **handle) { + if (!ctx->notify_watch) { + return NT_STATUS_NOT_IMPLEMENTED; + } return ctx->notify_watch(ctx, dirpath, filter, callback, private, handle); } -- cgit From a9cb173f7674d311624c34205f1417b31972d1f2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Apr 2006 04:50:08 +0000 Subject: r14918: cleaner handling of systems without inotify (This used to be commit cf17ff15b15942f0ce068dd0a94b3b565a9b93cb) --- source4/ntvfs/common/notify.c | 57 ++++++++++++++++++++++----------------- source4/ntvfs/sysdep/inotify.c | 2 +- source4/ntvfs/sysdep/sys_notify.c | 4 +++ 3 files changed, 38 insertions(+), 25 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 595a0f6566..9ea024f2fc 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -267,6 +267,25 @@ static void sys_notify_callback(struct sys_notify_context *ctx, listel->callback(listel->private, ev); } +/* + add an entry to the notify array +*/ +static NTSTATUS notify_add_array(struct notify_context *notify, struct notify_entry *e, + const char *path, void *private) +{ + notify->array->entries[notify->array->num_entries] = *e; + notify->array->entries[notify->array->num_entries].private = private; + notify->array->entries[notify->array->num_entries].server = notify->server; + + if (path) { + notify->array->entries[notify->array->num_entries].path = path; + } + + notify->array->num_entries++; + + return notify_save(notify); +} + /* add a notify watch. This is called when a notify is first setup on a open directory handle. @@ -312,33 +331,23 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, DLIST_ADD(notify->list, listel); /* ignore failures from sys_notify */ - status = sys_notify_watch(notify->sys_notify_ctx, e->path, e->filter, - sys_notify_callback, listel, - &listel->sys_notify_handle); - if (NT_STATUS_IS_OK(status)) { - talloc_steal(listel, listel->sys_notify_handle); - notify_unlock(notify); - } else { - notify->array->entries[notify->array->num_entries] = *e; - notify->array->entries[notify->array->num_entries].private = private; - notify->array->entries[notify->array->num_entries].server = notify->server; - - if (path) { - notify->array->entries[notify->array->num_entries].path = path; + if (notify->sys_notify_ctx != NULL) { + status = sys_notify_watch(notify->sys_notify_ctx, e->path, e->filter, + sys_notify_callback, listel, + &listel->sys_notify_handle); + if (NT_STATUS_IS_OK(status)) { + /* if the kernel handler has said it can handle this notify then + we don't need to add it to the array */ + talloc_steal(listel, listel->sys_notify_handle); + goto done; } - - notify->array->num_entries++; - - status = notify_save(notify); - - notify_unlock(notify); - - NT_STATUS_NOT_OK_RETURN(status); } - if (path) { - talloc_free(path); - } + status = notify_add_array(notify, e, path, private); + +done: + notify_unlock(notify); + talloc_free(path); return status; } diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 31c408d112..ec8669306e 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -239,7 +239,7 @@ static int watch_destructor(void *ptr) /* add a watch. The watch is removed when the caller calls - talloc_free() on handle + talloc_free() on *handle */ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, const char *dirpath, uint32_t filter, sys_notify_callback_t callback, diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index fd29f42a0e..1927ac61ce 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -44,6 +44,10 @@ struct sys_notify_context *sys_notify_init(int snum, const char *bname; struct sys_notify_backend *b; + if (backends == NULL) { + return NULL; + } + if (ev == NULL) { ev = event_context_find(mem_ctx); } -- cgit From 416d7b421001d00c4d494fceb4f2d0ab3e30cfaf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Apr 2006 05:54:10 +0000 Subject: r14920: allow a notify backend to separately specify if it has handled the given mask for the current directory and sub-directories. This allows us to setup the less efficient internal handling for subdirectories, while using the kernel inotify service for the current directory if available. It also allows inotify to handle only some of the filter bits, leaving the other filter bits for the user space handler. (This used to be commit 7c3d989fa44c7f57853a825337159f476d7dff80) --- source4/ntvfs/common/notify.c | 61 +++++++++++++++++++++++++-------------- source4/ntvfs/posix/pvfs_notify.c | 6 +++- source4/ntvfs/sysdep/inotify.c | 22 +++++++++----- source4/ntvfs/sysdep/sys_notify.c | 38 +++++++++++++++--------- source4/ntvfs/sysdep/sys_notify.h | 21 +++++++------- 5 files changed, 93 insertions(+), 55 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 9ea024f2fc..e0d48d2b80 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -290,10 +290,11 @@ static NTSTATUS notify_add_array(struct notify_context *notify, struct notify_en add a notify watch. This is called when a notify is first setup on a open directory handle. */ -NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, +NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, void (*callback)(void *, const struct notify_event *), void *private) { + struct notify_entry e = *e0; NTSTATUS status; struct notify_list *listel; char *path = NULL; @@ -304,8 +305,7 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, status = notify_load(notify); if (!NT_STATUS_IS_OK(status)) { - notify_unlock(notify); - return status; + goto done; } notify->array->entries = talloc_realloc(notify->array, notify->array->entries, @@ -313,18 +313,25 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, notify->array->num_entries+1); if (notify->array->entries == NULL) { - notify_unlock(notify); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto done; } /* cope with /. on the end of the path */ - len = strlen(e->path); - if (len > 1 && e->path[len-1] == '.' && e->path[len-2] == '/') { - path = talloc_strndup(notify, e->path, len-2); + len = strlen(e.path); + if (len > 1 && e.path[len-1] == '.' && e.path[len-2] == '/') { + e.path = talloc_strndup(notify, e.path, len-2); + if (e.path == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } } listel = talloc_zero(notify, struct notify_list); - NT_STATUS_HAVE_NO_MEMORY(listel); + if (listel == NULL) { + status = NT_STATUS_NO_MEMORY; + goto done; + } listel->private = private; listel->callback = callback; @@ -332,22 +339,31 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e, /* ignore failures from sys_notify */ if (notify->sys_notify_ctx != NULL) { - status = sys_notify_watch(notify->sys_notify_ctx, e->path, e->filter, + /* + this call will modify e.filter and e.subdir_filter + to remove bits handled by the backend + */ + status = sys_notify_watch(notify->sys_notify_ctx, &e, sys_notify_callback, listel, &listel->sys_notify_handle); if (NT_STATUS_IS_OK(status)) { - /* if the kernel handler has said it can handle this notify then - we don't need to add it to the array */ talloc_steal(listel, listel->sys_notify_handle); - goto done; } } - status = notify_add_array(notify, e, path, private); + /* if the system notify handler couldn't handle some of the + filter bits, or couldn't handle a request for recursion + then we need to install it in the array used for the + intra-samba notify handling */ + if (e.filter != 0 || e.subdir_filter != 0) { + status = notify_add_array(notify, &e, path, private); + } done: notify_unlock(notify); - talloc_free(path); + if (e.path != e0->path) { + talloc_free(e.path); + } return status; } @@ -483,8 +499,9 @@ static BOOL notify_match(struct notify_context *notify, struct notify_entry *e, const char *path, uint32_t filter) { size_t len; + BOOL subdir; - if (!(filter & e->filter)) { + if (!(filter & e->filter) && !(filter & e->subdir_filter)) { return False; } @@ -498,13 +515,15 @@ static BOOL notify_match(struct notify_context *notify, struct notify_entry *e, return False; } - if (!e->recursive) { - if (strchr(&path[len+1], '/') != NULL) { - return False; - } + /* the filter and subdir_filter are handled separately, allowing a backend + to flexibly choose what it can handle */ + subdir = (strchr(&path[len+1], '/') != NULL); + + if (subdir) { + return (filter & e->subdir_filter) != 0; } - return True; + return (filter & e->filter) != 0; } diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 121ba499b3..d2fdbfc49a 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -145,7 +145,11 @@ static NTSTATUS pvfs_notify_setup(struct pvfs_state *pvfs, struct pvfs_file *f, e.filter = filter; e.path = f->handle->name->full_name; - e.recursive = recursive; + if (recursive) { + e.subdir_filter = filter; + } else { + e.subdir_filter = 0; + } status = notify_add(pvfs->notify_context, &e, pvfs_notify_callback, f->notify_buffer); diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index ec8669306e..c95c39ff01 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -190,13 +190,15 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) /* - map from a change notify mask to a inotify mask. Approximate only :( + map from a change notify mask to a inotify mask. Remove any bits + which we can handle */ static const struct { uint32_t notify_mask; uint32_t inotify_mask; } inotify_mapping[] = { {FILE_NOTIFY_CHANGE_FILE_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, + {FILE_NOTIFY_CHANGE_DIR_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, {FILE_NOTIFY_CHANGE_ATTRIBUTES, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_SIZE, IN_MODIFY}, {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, @@ -204,13 +206,14 @@ static const struct { {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} }; -static uint32_t inotify_map(uint32_t mask) +static uint32_t inotify_map(struct notify_entry *e) { int i; uint32_t out=0; for (i=0;ifilter) { out |= inotify_mapping[i].inotify_mask; + e->filter &= ~inotify_mapping[i].notify_mask; } } return out; @@ -241,14 +244,15 @@ static int watch_destructor(void *ptr) add a watch. The watch is removed when the caller calls talloc_free() on *handle */ -static NTSTATUS inotify_watch(struct sys_notify_context *ctx, const char *dirpath, - uint32_t filter, sys_notify_callback_t callback, - void *private, void **handle) +static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entry *e, + sys_notify_callback_t callback, void *private, + void **handle) { struct inotify_private *in; int wd; uint32_t mask; struct watch_context *w; + uint32_t filter = e->filter; /* maybe setup the inotify fd */ if (ctx->private == NULL) { @@ -259,7 +263,7 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, const char *dirpat in = talloc_get_type(ctx->private, struct inotify_private); - mask = inotify_map(filter); + mask = inotify_map(e); if (mask == 0) { /* this filter can't be handled by inotify */ return NT_STATUS_INVALID_PARAMETER; @@ -270,14 +274,16 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, const char *dirpat mask |= (IN_MASK_ADD | IN_ONLYDIR); /* get a new watch descriptor for this path */ - wd = inotify_add_watch(in->fd, dirpath, mask); + wd = inotify_add_watch(in->fd, e->path, mask); if (wd == -1) { + e->filter = filter; return map_nt_error_from_unix(errno); } w = talloc(in, struct watch_context); if (w == NULL) { inotify_rm_watch(in->fd, wd); + e->filter = filter; return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 1927ac61ce..1be57dd55a 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -31,7 +31,7 @@ /* list of registered backends */ static struct sys_notify_backend *backends; - +static uint32_t num_backends; /* initialise a system change notify backend @@ -43,8 +43,9 @@ struct sys_notify_context *sys_notify_init(int snum, struct sys_notify_context *ctx; const char *bname; struct sys_notify_backend *b; + int i; - if (backends == NULL) { + if (num_backends == 0) { return NULL; } @@ -61,16 +62,16 @@ struct sys_notify_context *sys_notify_init(int snum, bname = lp_parm_string(snum, "notify", "backend"); if (!bname) { - if (backends) { - bname = backends->name; + if (num_backends) { + bname = backends[0].name; } else { bname = "__unknown__"; } } - for (b=backends;b;b=b->next) { - if (strcasecmp(b->name, bname) == 0) { - bname = b->name; + for (i=0;iname = bname; ctx->notify_watch = NULL; - if (b != NULL) { - ctx->notify_watch = b->notify_watch; + if (i < num_backends) { + ctx->notify_watch = backends[i].notify_watch; } return ctx; @@ -87,15 +88,18 @@ struct sys_notify_context *sys_notify_init(int snum, /* add a watch + + note that this call must modify the e->filter and e->subdir_filter + bits to remove ones handled by this backend. Any remaining bits will + be handled by the generic notify layer */ -NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, const char *dirpath, - uint32_t filter, sys_notify_callback_t callback, - void *private, void **handle) +NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, + sys_notify_callback_t callback, void *private, void **handle) { if (!ctx->notify_watch) { return NT_STATUS_NOT_IMPLEMENTED; } - return ctx->notify_watch(ctx, dirpath, filter, callback, private, handle); + return ctx->notify_watch(ctx, e, callback, private, handle); } /* @@ -103,6 +107,12 @@ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, const char *dirpath, */ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) { - DLIST_ADD(backends, backend); + struct sys_notify_backend *b; + b = talloc_realloc(talloc_autofree_context(), backends, + struct sys_notify_backend, num_backends+1); + NT_STATUS_HAVE_NO_MEMORY(b); + backends = b; + backends[num_backends] = *backend; + num_backends++; return NT_STATUS_OK; } diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h index 9ad5ed7555..9cb01a1db4 100644 --- a/source4/ntvfs/sysdep/sys_notify.h +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -25,28 +25,27 @@ struct sys_notify_context; typedef void (*sys_notify_callback_t)(struct sys_notify_context *, void *, struct notify_event *ev); +typedef NTSTATUS (*notify_watch_t)(struct sys_notify_context *ctx, + struct notify_event *e, + sys_notify_callback_t callback, void *private, + void **handle); + struct sys_notify_context { struct event_context *ev; void *private; /* for use of backend */ - NTSTATUS (*notify_watch)(struct sys_notify_context *ctx, const char *dirpath, - uint32_t filter, sys_notify_callback_t callback, - void *private, void **handle); const char *name; + notify_watch_t notify_watch; }; struct sys_notify_backend { - struct sys_notify_backend *next, *prev; const char *name; - NTSTATUS (*notify_watch)(struct sys_notify_context *ctx, const char *dirpath, - uint32_t filter, sys_notify_callback_t callback, - void *private, void **handle); + notify_watch_t notify_watch; }; NTSTATUS sys_notify_register(struct sys_notify_backend *backend); struct sys_notify_context *sys_notify_init(int snum, TALLOC_CTX *mem_ctx, struct event_context *ev); -NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, const char *dirpath, - uint32_t filter, sys_notify_callback_t callback, - void *private, void **handle); - +NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, + sys_notify_callback_t callback, void *private, + void **handle); -- cgit From 22c1c78b1d3c888508df42ae518fcb9711cec45d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Apr 2006 08:50:33 +0000 Subject: r14924: when handling recursive change notify, the client expects a windows path name back (This used to be commit ceb85d12f7efb002af7a271f999e22f94b8536fb) --- source4/ntvfs/posix/pvfs_notify.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index d2fdbfc49a..2733c59f8c 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -113,6 +113,7 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) n->changes = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1); n->changes[n->num_changes].action = ev->action; n->changes[n->num_changes].name.s = talloc_strdup(n->changes, ev->path); + string_replace(n->changes[n->num_changes].name.s, '/', '\\'); n->num_changes++; /* -- cgit From 930e247d5692cc776c434f9caafa90f2ca1a70b1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Apr 2006 08:52:03 +0000 Subject: r14925: trigger NOTIFY_ACTION_OLD_NAME and NOTIFY_ACTION_NEW_NAME events for renames, if in the same directory. For renames between directories generate NOTIFY_ACTION_REMOVED and NOTIFY_ACTION_ADDED (This used to be commit 2ac248edf05c3ee715165f2b33055de480743e87) --- source4/ntvfs/posix/pvfs_rename.c | 80 +++++++++++++++++++++++----------- source4/ntvfs/posix/pvfs_setfileinfo.c | 14 ++---- source4/ntvfs/sysdep/sys_notify.c | 2 +- 3 files changed, 59 insertions(+), 37 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index e69cbcde0b..824581cdaf 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -24,6 +24,50 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/security.h" + +/* + do a file rename, and send any notify triggers +*/ +NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const char *name1, const char *name2) +{ + const char *r1, *r2; + + if (rename(name1, name2) == -1) { + return pvfs_map_errno(pvfs, errno); + } + + /* + renames to the same directory cause a OLD_NAME->NEW_NAME notify. + renames to a different directory are considered a remove/add + */ + r1 = strrchr_m(name1, '/'); + r2 = strrchr_m(name2, '/'); + + if ((r1-name1) != (r2-name2) || + strncmp(name1, name2, r1-name1) != 0) { + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME, + name1); + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_ADDED, + FILE_NOTIFY_CHANGE_FILE_NAME, + name2); + } else { + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_OLD_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME, + name1); + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_NEW_NAME, + FILE_NOTIFY_CHANGE_FILE_NAME, + name2); + } + + return NT_STATUS_OK; +} + + /* resolve a wildcard rename pattern. This works on one component of the name */ @@ -173,18 +217,10 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - if (rename(name1->full_name, fname2) == -1) { - talloc_free(mem_ctx); - return pvfs_map_errno(pvfs, errno); - } - - status = odb_rename(lck, fname2); + status = pvfs_do_rename(pvfs, name1->full_name, fname2); if (NT_STATUS_IS_OK(status)) { - notify_trigger(pvfs->notify_context, - NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_FILE_NAME, - name1->full_name); + status = odb_rename(lck, fname2); } failed: @@ -302,11 +338,10 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } - if (rename(name1->full_name, name2->full_name) == -1) { - return pvfs_map_errno(pvfs, errno); + status = pvfs_do_rename(pvfs, name1->full_name, name2->full_name); + if (NT_STATUS_IS_OK(status)) { + status = odb_rename(lck, name2->full_name); } - - status = odb_rename(lck, name2->full_name); return NT_STATUS_OK; } @@ -375,19 +410,14 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if (rename(name1->full_name, name2->full_name) == -1) { - return pvfs_map_errno(pvfs, errno); - } + NT_STATUS_NOT_OK_RETURN(status); + status = pvfs_do_rename(pvfs, name1->full_name, name2->full_name); + NT_STATUS_NOT_OK_RETURN(status); break; case RENAME_FLAG_HARD_LINK: status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NT_STATUS_NOT_OK_RETURN(status); if (link(name1->full_name, name2->full_name) == -1) { return pvfs_map_errno(pvfs, errno); } @@ -395,9 +425,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, case RENAME_FLAG_COPY: status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NT_STATUS_NOT_OK_RETURN(status); return pvfs_copy_file(pvfs, name1, name2); case RENAME_FLAG_MOVE_CLUSTER_INFORMATION: diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 72c061078c..9f5153eb4b 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -147,18 +147,12 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return status; } - if (rename(name->full_name, name2->full_name) == -1) { - return pvfs_map_errno(pvfs, errno); + status = pvfs_do_rename(pvfs, name->full_name, name2->full_name); + if (NT_STATUS_IS_OK(status)) { + name->full_name = talloc_steal(name, name2->full_name); + name->original_name = talloc_steal(name, name2->original_name); } - notify_trigger(pvfs->notify_context, - NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_FILE_NAME, - name->full_name); - - name->full_name = talloc_steal(name, name2->full_name); - name->original_name = talloc_steal(name, name2->original_name); - return NT_STATUS_OK; } diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 1be57dd55a..85831c80e9 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -97,7 +97,7 @@ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e sys_notify_callback_t callback, void *private, void **handle) { if (!ctx->notify_watch) { - return NT_STATUS_NOT_IMPLEMENTED; + return NT_STATUS_INVALID_SYSTEM_SERVICE; } return ctx->notify_watch(ctx, e, callback, private, handle); } -- cgit From 1dee94c333a06857de2981e1d8e019c8e430bc06 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Apr 2006 08:52:55 +0000 Subject: r14926: change the inotify backend to implement the rather unusual semantics for rename. The cookies in inotify tell us (indirectly!) if its a rename between directories or not (This used to be commit 13574a8d0c7228bf36a6debe4853f693c9f8f543) --- source4/ntvfs/sysdep/inotify.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index c95c39ff01..70ef4918cb 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -90,8 +90,13 @@ static int inotify_destructor(void *ptr) /* dispatch one inotify event + + the cookies are used to correctly handle renames */ -static void inotify_dispatch(struct inotify_private *in, struct inotify_event *e) +static void inotify_dispatch(struct inotify_private *in, + struct inotify_event *e, + uint32_t prev_cookie, + uint32_t next_cookie) { struct watch_context *w; struct notify_event ne; @@ -101,11 +106,24 @@ static void inotify_dispatch(struct inotify_private *in, struct inotify_event *e return; } - /* map the inotify mask to a action */ + /* map the inotify mask to a action. This gets complicated for + renames */ if (e->mask & IN_CREATE) { ne.action = NOTIFY_ACTION_ADDED; } else if (e->mask & IN_DELETE) { ne.action = NOTIFY_ACTION_REMOVED; + } else if (e->mask & IN_MOVED_FROM) { + if (e->cookie == next_cookie) { + ne.action = NOTIFY_ACTION_OLD_NAME; + } else { + ne.action = NOTIFY_ACTION_REMOVED; + } + } else if (e->mask & IN_MOVED_TO) { + if (e->cookie == prev_cookie) { + ne.action = NOTIFY_ACTION_NEW_NAME; + } else { + ne.action = NOTIFY_ACTION_ADDED; + } } else { ne.action = NOTIFY_ACTION_MODIFIED; } @@ -129,6 +147,7 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde, struct inotify_private *in = talloc_get_type(private, struct inotify_private); int bufsize = 0; struct inotify_event *e0, *e; + uint32_t prev_cookie=0; /* we must use FIONREAD as we cannot predict the length of the @@ -152,9 +171,14 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde, /* we can get more than one event in the buffer */ while (bufsize >= sizeof(*e)) { - inotify_dispatch(in, e); + struct inotify_event *e2 = NULL; bufsize -= e->len + sizeof(*e); - e = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); + if (bufsize >= sizeof(*e)) { + e2 = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); + } + inotify_dispatch(in, e, prev_cookie, e2?e2->cookie:0); + prev_cookie = e->cookie; + e = e2; } talloc_free(e0); -- cgit From e221db7a39094f0e456388454096d4cdd88082e9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Apr 2006 09:06:09 +0000 Subject: r14928: demonstrate that the completion filter is only set on the first notify on a directory handle (This used to be commit b6e40d9b0832fbab662f9289a30c26e2576b4821) --- source4/ntvfs/posix/pvfs_notify.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 2733c59f8c..ea11a9ff90 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -213,6 +213,8 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); } + /* we update the max_buffer_size on each call, but we do not + update the recursive flag or filter */ f->notify_buffer->max_buffer_size = info->in.buffer_size; pending = talloc(f->notify_buffer, struct notify_pending); -- cgit From fe071da009d910c3325f016ae9e4b349d726802f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 01:54:12 +0000 Subject: r14932: ensure that we send a NOTIFY_ACTION_OLD_NAME and NOTIFY_ACTION_NEW_NAME together to the client. (This used to be commit d58011b0f35c3299f35ba9d72a7b9b9b17253511) --- source4/ntvfs/posix/pvfs_notify.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index ea11a9ff90..652a5260d5 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -125,8 +125,10 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) } n->current_buffer_size += len; - /* send what we have */ - pvfs_notify_send(n, NT_STATUS_OK); + /* send what we have, unless its the first part of a rename */ + if (ev->action != NOTIFY_ACTION_OLD_NAME) { + pvfs_notify_send(n, NT_STATUS_OK); + } } /* -- cgit From e54abee4e19538760119e8e63eb23f78fd88da4f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 01:56:04 +0000 Subject: r14933: fix the handling of notify filters to be much closer to the behaviour of w2k3. The behaviour is particularly tricky for rename. (This used to be commit 4d3b8d95498a328ffc08ecb62d9531b6bfe4e2b5) --- source4/ntvfs/posix/pvfs_mkdir.c | 6 +++--- source4/ntvfs/posix/pvfs_open.c | 4 ++-- source4/ntvfs/posix/pvfs_read.c | 5 ----- source4/ntvfs/posix/pvfs_rename.c | 35 ++++++++++++++++++++-------------- source4/ntvfs/posix/pvfs_setfileinfo.c | 15 ++++++++++----- source4/ntvfs/posix/pvfs_write.c | 5 ----- source4/ntvfs/posix/vfs_posix.c | 2 +- 7 files changed, 37 insertions(+), 35 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index cd83c9de43..338fc7df0b 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -85,7 +85,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs, notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + FILE_NOTIFY_CHANGE_DIR_NAME, name->full_name); return NT_STATUS_OK; @@ -142,7 +142,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs, notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + FILE_NOTIFY_CHANGE_DIR_NAME, name->full_name); return NT_STATUS_OK; @@ -184,7 +184,7 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, notify_trigger(pvfs->notify_context, NOTIFY_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + FILE_NOTIFY_CHANGE_DIR_NAME, name->full_name); return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 264234a09b..5afb538db7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -380,8 +380,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, create_action = NTCREATEX_ACTION_CREATED; notify_trigger(pvfs->notify_context, - NOTIFY_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME, + NOTIFY_ACTION_ADDED, + FILE_NOTIFY_CHANGE_DIR_NAME, name->full_name); } else { create_action = NTCREATEX_ACTION_EXISTED; diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index f30c4d6e38..411fbd9c27 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -90,10 +90,5 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, rd->readx.out.remaining = 0xFFFF; rd->readx.out.compaction_mode = 0; - notify_trigger(pvfs->notify_context, - NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_LAST_ACCESS, - f->handle->name->full_name); - return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 824581cdaf..c3442884cf 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -28,39 +28,46 @@ /* do a file rename, and send any notify triggers */ -NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const char *name1, const char *name2) +NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *name1, + const char *name2) { const char *r1, *r2; + uint32_t mask; - if (rename(name1, name2) == -1) { + if (rename(name1->full_name, name2) == -1) { return pvfs_map_errno(pvfs, errno); } + if (name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + mask = FILE_NOTIFY_CHANGE_DIR_NAME; + } else { + mask = FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_CREATION; + } /* renames to the same directory cause a OLD_NAME->NEW_NAME notify. renames to a different directory are considered a remove/add */ - r1 = strrchr_m(name1, '/'); + r1 = strrchr_m(name1->full_name, '/'); r2 = strrchr_m(name2, '/'); - if ((r1-name1) != (r2-name2) || - strncmp(name1, name2, r1-name1) != 0) { + if ((r1-name1->full_name) != (r2-name2) || + strncmp(name1->full_name, name2, r1-name1->full_name) != 0) { notify_trigger(pvfs->notify_context, NOTIFY_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME, - name1); + mask, + name1->full_name); notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, - FILE_NOTIFY_CHANGE_FILE_NAME, + mask, name2); } else { notify_trigger(pvfs->notify_context, NOTIFY_ACTION_OLD_NAME, - FILE_NOTIFY_CHANGE_FILE_NAME, - name1); + mask, + name1->full_name); notify_trigger(pvfs->notify_context, NOTIFY_ACTION_NEW_NAME, - FILE_NOTIFY_CHANGE_FILE_NAME, + mask, name2); } @@ -217,7 +224,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - status = pvfs_do_rename(pvfs, name1->full_name, fname2); + status = pvfs_do_rename(pvfs, name1, fname2); if (NT_STATUS_IS_OK(status)) { status = odb_rename(lck, fname2); @@ -338,7 +345,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_do_rename(pvfs, name1->full_name, name2->full_name); + status = pvfs_do_rename(pvfs, name1, name2->full_name); if (NT_STATUS_IS_OK(status)) { status = odb_rename(lck, name2->full_name); } @@ -411,7 +418,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, case RENAME_FLAG_RENAME: status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); NT_STATUS_NOT_OK_RETURN(status); - status = pvfs_do_rename(pvfs, name1->full_name, name2->full_name); + status = pvfs_do_rename(pvfs, name1, name2->full_name); NT_STATUS_NOT_OK_RETURN(status); break; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 9f5153eb4b..b00624c0e9 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -147,7 +147,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return status; } - status = pvfs_do_rename(pvfs, name->full_name, name2->full_name); + status = pvfs_do_rename(pvfs, name, name2->full_name); if (NT_STATUS_IS_OK(status)) { name->full_name = talloc_steal(name, name2->full_name); name->original_name = talloc_steal(name, name2->original_name); @@ -292,7 +292,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_STANDARD: if (!null_time(info->setattre.in.create_time)) { unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time); - change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_time(info->setattre.in.access_time)) { unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time); @@ -311,7 +310,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_BASIC_INFORMATION: if (!null_nttime(info->basic_info.in.create_time)) { newstats.dos.create_time = info->basic_info.in.create_time; - change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_nttime(info->basic_info.in.access_time)) { newstats.dos.access_time = info->basic_info.in.access_time; @@ -408,6 +406,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file timestamps */ ZERO_STRUCT(unix_times); + if (newstats.dos.create_time != h->name->dos.create_time) { + change_mask |= FILE_NOTIFY_CHANGE_CREATION; + } if (newstats.dos.access_time != h->name->dos.access_time) { unix_times.actime = nt_time_to_unix(newstats.dos.access_time); change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS; @@ -494,7 +495,6 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_STANDARD: if (!null_time(info->setattre.in.create_time)) { unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time); - change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_time(info->setattre.in.access_time)) { unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time); @@ -513,7 +513,6 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_BASIC_INFORMATION: if (!null_nttime(info->basic_info.in.create_time)) { newstats.dos.create_time = info->basic_info.in.create_time; - change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (!null_nttime(info->basic_info.in.access_time)) { newstats.dos.access_time = info->basic_info.in.access_time; @@ -585,11 +584,16 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, /* possibly change the file timestamps */ ZERO_STRUCT(unix_times); + if (newstats.dos.create_time != name->dos.create_time) { + change_mask |= FILE_NOTIFY_CHANGE_CREATION; + } if (newstats.dos.access_time != name->dos.access_time) { unix_times.actime = nt_time_to_unix(newstats.dos.access_time); + change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS; } if (newstats.dos.write_time != name->dos.write_time) { unix_times.modtime = nt_time_to_unix(newstats.dos.write_time); + change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE; } if (unix_times.actime != 0 || unix_times.modtime != 0) { if (utime(name->full_name, &unix_times) == -1) { @@ -604,6 +608,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, if (chmod(name->full_name, mode) == -1) { return pvfs_map_errno(pvfs, errno); } + change_mask |= FILE_NOTIFY_CHANGE_ATTRIBUTES; } *name = newstats; diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 15e3526176..298c95e90b 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -85,10 +85,5 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, wr->writex.out.nwritten = ret; wr->writex.out.remaining = 0; /* should fill this in? */ - notify_trigger(pvfs->notify_context, - NOTIFY_ACTION_MODIFIED, - FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, - f->handle->name->full_name); - return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index c279350e2f..c0c1d6501c 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -111,7 +111,7 @@ static int pvfs_state_destructor(void *ptr) struct pvfs_search_state *s, *sn; /* - * make sure we cleanup files and searches before anythingelse + * make sure we cleanup files and searches before anything else * because there destructors need to acess the pvfs_state struct */ for (f=pvfs->files.list; f; f=fn) { -- cgit From 115acb5dd0bcd3a4b52c3a02302e8c250715bb44 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Apr 2006 09:15:17 +0000 Subject: r14939: don't use a void pointer metze (This used to be commit 03906b2b13c000ad9683f6bb1e336075655e1367) --- source4/ntvfs/common/sidmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c index cac238c70d..6f3cd42b62 100644 --- a/source4/ntvfs/common/sidmap.c +++ b/source4/ntvfs/common/sidmap.c @@ -43,7 +43,7 @@ private context for sid mapping routines */ struct sidmap_context { - void *samctx; + struct ldb_wrap *samctx; }; /* -- cgit From 4abf299e0cd238d80ebe8b31eb0a4388499da404 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 10:05:19 +0000 Subject: r14941: a rename of a file (but not a directory) triggers 3 events. The first two are the rename (FROM and TO) then the 3rd event is a modify event of both attributes and creation time. (This used to be commit 010a1b14a58c0194e1f8bba29f4d02a86b7559c5) --- source4/ntvfs/posix/pvfs_rename.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index c3442884cf..6a397ef981 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -41,7 +41,7 @@ NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *nam if (name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { mask = FILE_NOTIFY_CHANGE_DIR_NAME; } else { - mask = FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_CREATION; + mask = FILE_NOTIFY_CHANGE_FILE_NAME; } /* renames to the same directory cause a OLD_NAME->NEW_NAME notify. @@ -70,6 +70,16 @@ NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *nam mask, name2); } + + /* this is a strange one. w2k3 gives an additional event for CHANGE_ATTRIBUTES + and CHANGE_CREATION on the new file when renming files, but not + directories */ + if ((name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) == 0) { + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_CREATION, + name2); + } return NT_STATUS_OK; } -- cgit From ee2fb760af2fdc58ab6859ebdee0896ca16c89a8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 10:07:13 +0000 Subject: r14943: bring the inotify backend up to date with all the strange rename semantics (This used to be commit 74c274ea072fc45debaafd438ff63321b38a1448) --- source4/ntvfs/sysdep/inotify.c | 98 +++++++++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 70ef4918cb..ead2211c8e 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -73,7 +73,9 @@ struct watch_context { int wd; sys_notify_callback_t callback; void *private; - uint32_t mask; + uint32_t mask; /* the inotify mask */ + uint32_t filter; /* the windows completion filter */ + const char *path; }; @@ -88,6 +90,42 @@ static int inotify_destructor(void *ptr) } +/* + see if a particular event from inotify really does match a requested + notify event in SMB +*/ +static BOOL filter_match(struct watch_context *w, struct inotify_event *e) +{ + if ((e->mask & w->mask) == 0) { + /* this happens because inotify_add_watch() coalesces watches on the same + path, oring their masks together */ + return False; + } + + /* SMB separates the filters for files and directories */ + if (e->mask & IN_ISDIR) { + if ((w->filter & FILE_NOTIFY_CHANGE_DIR_NAME) == 0) { + return False; + } + } else { + if ((e->mask & IN_ATTRIB) && + (w->filter & (FILE_NOTIFY_CHANGE_ATTRIBUTES| + FILE_NOTIFY_CHANGE_LAST_WRITE| + FILE_NOTIFY_CHANGE_LAST_ACCESS| + FILE_NOTIFY_CHANGE_EA| + FILE_NOTIFY_CHANGE_SECURITY))) { + return True; + } + if ((w->filter & FILE_NOTIFY_CHANGE_FILE_NAME) == 0) { + return False; + } + } + + return True; +} + + + /* dispatch one inotify event @@ -96,13 +134,14 @@ static int inotify_destructor(void *ptr) static void inotify_dispatch(struct inotify_private *in, struct inotify_event *e, uint32_t prev_cookie, - uint32_t next_cookie) + struct inotify_event *e2) { - struct watch_context *w; + struct watch_context *w, *next; struct notify_event ne; /* ignore extraneous events, such as unmount and IN_IGNORED events */ - if ((e->mask & (IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO)) == 0) { + if ((e->mask & (IN_ATTRIB|IN_MODIFY|IN_CREATE|IN_DELETE| + IN_MOVED_FROM|IN_MOVED_TO)) == 0) { return; } @@ -113,7 +152,7 @@ static void inotify_dispatch(struct inotify_private *in, } else if (e->mask & IN_DELETE) { ne.action = NOTIFY_ACTION_REMOVED; } else if (e->mask & IN_MOVED_FROM) { - if (e->cookie == next_cookie) { + if (e2 != NULL && e2->cookie == e->cookie) { ne.action = NOTIFY_ACTION_OLD_NAME; } else { ne.action = NOTIFY_ACTION_REMOVED; @@ -130,9 +169,28 @@ static void inotify_dispatch(struct inotify_private *in, ne.path = e->name; /* find any watches that have this watch descriptor */ - for (w=in->watches;w;w=w->next) { - /* checking the mask copes with multiple watches */ - if (w->wd == e->wd && (e->mask & w->mask) != 0) { + for (w=in->watches;w;w=next) { + next = w->next; + if (w->wd == e->wd && filter_match(w, e)) { + w->callback(in->ctx, w->private, &ne); + } + } + + /* SMB expects a file rename to generate three events, two for + the rename and the other for a modify of the + destination. Strange! */ + if (ne.action != NOTIFY_ACTION_NEW_NAME || + (e->mask & IN_ISDIR) != 0) { + return; + } + + ne.action = NOTIFY_ACTION_MODIFIED; + e->mask = IN_ATTRIB; + + for (w=in->watches;w;w=next) { + next = w->next; + if (w->wd == e->wd && filter_match(w, e) && + !(w->filter & FILE_NOTIFY_CHANGE_CREATION)) { w->callback(in->ctx, w->private, &ne); } } @@ -176,7 +234,7 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde, if (bufsize >= sizeof(*e)) { e2 = (struct inotify_event *)(e->len + sizeof(*e) + (char *)e); } - inotify_dispatch(in, e, prev_cookie, e2?e2->cookie:0); + inotify_dispatch(in, e, prev_cookie, e2); prev_cookie = e->cookie; e = e2; } @@ -221,13 +279,14 @@ static const struct { uint32_t notify_mask; uint32_t inotify_mask; } inotify_mapping[] = { - {FILE_NOTIFY_CHANGE_FILE_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, - {FILE_NOTIFY_CHANGE_DIR_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, - {FILE_NOTIFY_CHANGE_ATTRIBUTES, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_SIZE, IN_MODIFY}, - {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, - {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} + {FILE_NOTIFY_CHANGE_FILE_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, + {FILE_NOTIFY_CHANGE_DIR_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, + {FILE_NOTIFY_CHANGE_ATTRIBUTES, IN_ATTRIB | IN_MOVED_TO | IN_MOVED_FROM}, + {FILE_NOTIFY_CHANGE_SIZE, IN_MODIFY}, + {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_LAST_ACCESS, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, + {FILE_NOTIFY_CHANGE_SECURITY, IN_ATTRIB} }; static uint32_t inotify_map(struct notify_entry *e) @@ -316,6 +375,13 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entr w->callback = callback; w->private = private; w->mask = mask; + w->filter = filter; + w->path = talloc_strdup(w, e->path); + if (w->path == NULL) { + inotify_rm_watch(in->fd, wd); + e->filter = filter; + return NT_STATUS_NO_MEMORY; + } (*handle) = w; -- cgit From fa91368fb4ea2c31f6e1b1037f1bd16ef9f3ba98 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 10:12:36 +0000 Subject: r14945: allow the notify backend to be specified per share (This used to be commit 467027e7730a3bc56f152df7e2ec272905e19584) --- source4/ntvfs/common/notify.c | 4 ++-- source4/ntvfs/posix/vfs_posix.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index e0d48d2b80..a1f7e80119 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -77,7 +77,7 @@ static int notify_destructor(void *p) */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, struct messaging_context *messaging_ctx, - struct event_context *ev) + struct event_context *ev, int snum) { char *path; struct notify_context *notify; @@ -110,7 +110,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, messaging_register(notify->messaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); - notify->sys_notify_ctx = sys_notify_init(-1, notify, ev); + notify->sys_notify_ctx = sys_notify_init(snum, notify, ev); return notify; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index c0c1d6501c..3e141219f4 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -188,7 +188,8 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->notify_context = notify_init(pvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, - event_context_find(pvfs)); + event_context_find(pvfs), + pvfs->ntvfs->ctx->config.snum); if (pvfs->notify_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From 2b0537143c8e098da5638a6b4f8eeffd1cbef4d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 11:07:21 +0000 Subject: r14947: add support for file truncate events (This used to be commit ed1b90407d8ef6e0216931cb3a89cc9a7789ead2) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index b00624c0e9..7661d1eb45 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -400,7 +400,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, if (ret == -1) { return pvfs_map_errno(pvfs, errno); } - change_mask |= FILE_NOTIFY_CHANGE_SIZE; + change_mask |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES; } } @@ -580,6 +580,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } else if (truncate(name->full_name, newstats.st.st_size) == -1) { return pvfs_map_errno(pvfs, errno); } + change_mask |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_ATTRIBUTES; } /* possibly change the file timestamps */ @@ -613,10 +614,12 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, *name = newstats; - notify_trigger(pvfs->notify_context, - NOTIFY_ACTION_MODIFIED, - change_mask, - name->full_name); + if (change_mask != 0) { + notify_trigger(pvfs->notify_context, + NOTIFY_ACTION_MODIFIED, + change_mask, + name->full_name); + } return pvfs_dosattrib_save(pvfs, name, -1); } -- cgit From b5ee277f1aa119e0acd498ab443e4eb990387af1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Apr 2006 11:09:24 +0000 Subject: r14948: add testing of truncate events, and add truncate support to inotify backend (This used to be commit b80523a631ec57c7d19e9a23dca4594d71036138) --- source4/ntvfs/sysdep/inotify.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index ead2211c8e..f86e3c1913 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -116,6 +116,10 @@ static BOOL filter_match(struct watch_context *w, struct inotify_event *e) FILE_NOTIFY_CHANGE_SECURITY))) { return True; } + if ((e->mask & IN_MODIFY) && + (w->filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)) { + return True; + } if ((w->filter & FILE_NOTIFY_CHANGE_FILE_NAME) == 0) { return False; } @@ -281,8 +285,7 @@ static const struct { } inotify_mapping[] = { {FILE_NOTIFY_CHANGE_FILE_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, {FILE_NOTIFY_CHANGE_DIR_NAME, IN_CREATE|IN_DELETE|IN_MOVED_FROM|IN_MOVED_TO}, - {FILE_NOTIFY_CHANGE_ATTRIBUTES, IN_ATTRIB | IN_MOVED_TO | IN_MOVED_FROM}, - {FILE_NOTIFY_CHANGE_SIZE, IN_MODIFY}, + {FILE_NOTIFY_CHANGE_ATTRIBUTES, IN_ATTRIB|IN_MOVED_TO|IN_MOVED_FROM|IN_MODIFY}, {FILE_NOTIFY_CHANGE_LAST_WRITE, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_LAST_ACCESS, IN_ATTRIB}, {FILE_NOTIFY_CHANGE_EA, IN_ATTRIB}, -- cgit From 317c4b81a5edf18eeb7f6358ca5b508e4af80bfd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Apr 2006 13:51:44 +0000 Subject: r14951: - remove unused var 'path' - fix compiler warning metze (This used to be commit 4d7de8b251e006a469adf2793dae422e128844c5) --- source4/ntvfs/common/notify.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index a1f7e80119..318b114efa 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -271,16 +271,12 @@ static void sys_notify_callback(struct sys_notify_context *ctx, add an entry to the notify array */ static NTSTATUS notify_add_array(struct notify_context *notify, struct notify_entry *e, - const char *path, void *private) + void *private) { notify->array->entries[notify->array->num_entries] = *e; notify->array->entries[notify->array->num_entries].private = private; notify->array->entries[notify->array->num_entries].server = notify->server; - if (path) { - notify->array->entries[notify->array->num_entries].path = path; - } - notify->array->num_entries++; return notify_save(notify); @@ -296,8 +292,8 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, { struct notify_entry e = *e0; NTSTATUS status; + char *tmp_path = NULL; struct notify_list *listel; - char *path = NULL; size_t len; status = notify_lock(notify); @@ -320,11 +316,12 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, /* cope with /. on the end of the path */ len = strlen(e.path); if (len > 1 && e.path[len-1] == '.' && e.path[len-2] == '/') { - e.path = talloc_strndup(notify, e.path, len-2); - if (e.path == NULL) { + tmp_path = talloc_strndup(notify, e.path, len-2); + if (tmp_path == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } + e.path = tmp_path; } listel = talloc_zero(notify, struct notify_list); @@ -356,14 +353,12 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, then we need to install it in the array used for the intra-samba notify handling */ if (e.filter != 0 || e.subdir_filter != 0) { - status = notify_add_array(notify, &e, path, private); + status = notify_add_array(notify, &e, private); } done: notify_unlock(notify); - if (e.path != e0->path) { - talloc_free(e.path); - } + talloc_free(tmp_path); return status; } -- cgit From 127967334fbf3851debacbc0f2574461b542cbad Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Apr 2006 10:36:54 +0000 Subject: r14956: change the notify search to be much more efficient by using a per-depth bisection search. This makes the notify_trigger() call log(N) which makes us scale well for large numbers of outstanding notifies (This used to be commit 16fd00925fdbf77e7a403ad501bf6ea429404c76) --- source4/ntvfs/common/notify.c | 250 +++++++++++++++++++++++++------------- source4/ntvfs/sysdep/sys_notify.c | 1 - 2 files changed, 167 insertions(+), 84 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 318b114efa..0c264de88f 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -51,6 +51,7 @@ struct notify_list { void *private; void (*callback)(void *, const struct notify_event *); void *sys_notify_handle; + int depth; }; #define NOTIFY_KEY "notify array" @@ -192,7 +193,14 @@ static NTSTATUS notify_save(struct notify_context *notify) int ret; TALLOC_CTX *tmp_ctx; - if (notify->array->num_entries == 0) { + /* if possible, remove some depth arrays */ + while (notify->array->num_depths > 0 && + notify->array->depth[notify->array->num_depths-1].num_entries == 0) { + notify->array->num_depths--; + } + + /* we might just be able to delete the record */ + if (notify->array->num_depths == 0) { ret = tdb_delete_bystring(notify->w->tdb, NOTIFY_KEY); if (ret != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -200,11 +208,6 @@ static NTSTATUS notify_save(struct notify_context *notify) return NT_STATUS_OK; } - if (notify->array->num_entries > 1) { - qsort(notify->array->entries, notify->array->num_entries, - sizeof(struct notify_entry), notify_compare); - } - tmp_ctx = talloc_new(notify); status = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, @@ -271,14 +274,53 @@ static void sys_notify_callback(struct sys_notify_context *ctx, add an entry to the notify array */ static NTSTATUS notify_add_array(struct notify_context *notify, struct notify_entry *e, - void *private) + void *private, int depth) { - notify->array->entries[notify->array->num_entries] = *e; - notify->array->entries[notify->array->num_entries].private = private; - notify->array->entries[notify->array->num_entries].server = notify->server; - - notify->array->num_entries++; - + int i; + struct notify_depth *d; + struct notify_entry *ee; + + /* possibly expand the depths array */ + if (depth >= notify->array->num_depths) { + d = talloc_realloc(notify->array, notify->array->depth, + struct notify_depth, depth+1); + NT_STATUS_HAVE_NO_MEMORY(d); + for (i=notify->array->num_depths;i<=depth;i++) { + ZERO_STRUCT(d[i]); + } + notify->array->depth = d; + notify->array->num_depths = depth+1; + } + d = ¬ify->array->depth[depth]; + + /* expand the entries array */ + ee = talloc_realloc(notify->array->depth, d->entries, struct notify_entry, + d->num_entries+1); + NT_STATUS_HAVE_NO_MEMORY(ee); + d->entries = ee; + + d->entries[d->num_entries] = *e; + d->entries[d->num_entries].private = private; + d->entries[d->num_entries].server = notify->server; + d->entries[d->num_entries].path_len = strlen(e->path); + d->num_entries++; + + d->max_mask |= e->filter; + d->max_mask_subdir |= e->subdir_filter; + + if (d->num_entries > 1) { + qsort(d->entries, d->num_entries, sizeof(d->entries[0]), notify_compare); + } + + /* recalculate the maximum masks */ + d->max_mask = 0; + d->max_mask_subdir = 0; + + for (i=0;inum_entries;i++) { + d->max_mask |= d->entries[i].filter; + d->max_mask_subdir |= d->entries[i].subdir_filter; + } + return notify_save(notify); } @@ -295,6 +337,7 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, char *tmp_path = NULL; struct notify_list *listel; size_t len; + int depth; status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); @@ -304,15 +347,6 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, goto done; } - notify->array->entries = talloc_realloc(notify->array, notify->array->entries, - struct notify_entry, - notify->array->num_entries+1); - - if (notify->array->entries == NULL) { - status = NT_STATUS_NO_MEMORY; - goto done; - } - /* cope with /. on the end of the path */ len = strlen(e.path); if (len > 1 && e.path[len-1] == '.' && e.path[len-2] == '/') { @@ -324,6 +358,8 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, e.path = tmp_path; } + depth = count_chars(e.path, '/'); + listel = talloc_zero(notify, struct notify_list); if (listel == NULL) { status = NT_STATUS_NO_MEMORY; @@ -332,6 +368,7 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, listel->private = private; listel->callback = callback; + listel->depth = depth; DLIST_ADD(notify->list, listel); /* ignore failures from sys_notify */ @@ -353,7 +390,7 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, then we need to install it in the array used for the intra-samba notify handling */ if (e.filter != 0 || e.subdir_filter != 0) { - status = notify_add_array(notify, &e, private); + status = notify_add_array(notify, &e, private, depth); } done: @@ -370,7 +407,8 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) { NTSTATUS status; struct notify_list *listel; - int i; + int i, depth; + struct notify_depth *d; for (listel=notify->list;listel;listel=listel->next) { if (listel->private == private) { @@ -382,6 +420,8 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) return NT_STATUS_OBJECT_NAME_NOT_FOUND; } + depth = listel->depth; + talloc_free(listel); status = notify_lock(notify); @@ -393,22 +433,25 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) return status; } - for (i=0;iarray->num_entries;i++) { - if (notify->server == notify->array->entries[i].server && - private == notify->array->entries[i].private) { + /* we only have to search at the depth of this element */ + d = ¬ify->array->depth[depth]; + + for (i=0;inum_entries;i++) { + if (private == d->entries[i].private && + notify->server == d->entries[i].server) { break; } } - if (i == notify->array->num_entries) { + if (i == d->num_entries) { notify_unlock(notify); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - if (i < notify->array->num_entries-1) { - memmove(¬ify->array->entries[i], ¬ify->array->entries[i+1], - sizeof(notify->array->entries[i])*(notify->array->num_entries-(i+1))); + if (i < d->num_entries-1) { + memmove(&d->entries[i], &d->entries[i+1], + sizeof(d->entries[i])*(d->num_entries-(i+1))); } - notify->array->num_entries--; + d->num_entries--; status = notify_save(notify); @@ -423,7 +466,7 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) static NTSTATUS notify_remove_all(struct notify_context *notify) { NTSTATUS status; - int i; + int i, depth, del_count=0; if (notify->list == NULL) { return NT_STATUS_OK; @@ -438,19 +481,26 @@ static NTSTATUS notify_remove_all(struct notify_context *notify) return status; } - for (i=0;iarray->num_entries;i++) { - if (notify->server == notify->array->entries[i].server) { - if (i < notify->array->num_entries-1) { - memmove(¬ify->array->entries[i], ¬ify->array->entries[i+1], - sizeof(notify->array->entries[i])*(notify->array->num_entries-(i+1))); + /* we have to search for all entries across all depths, looking for matches + for our server id */ + for (depth=0;deptharray->num_depths;depth++) { + struct notify_depth *d = ¬ify->array->depth[depth]; + for (i=0;inum_entries;i++) { + if (notify->server == d->entries[i].server) { + if (i < d->num_entries-1) { + memmove(&d->entries[i], &d->entries[i+1], + sizeof(d->entries[i])*(d->num_entries-(i+1))); + } + i--; + d->num_entries--; + del_count++; } - i--; - notify->array->num_entries--; } } - - status = notify_save(notify); + if (del_count > 0) { + status = notify_save(notify); + } notify_unlock(notify); @@ -487,61 +537,95 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, talloc_free(tmp_ctx); } -/* - see if a notify event matches -*/ -static BOOL notify_match(struct notify_context *notify, struct notify_entry *e, - const char *path, uint32_t filter) -{ - size_t len; - BOOL subdir; - - if (!(filter & e->filter) && !(filter & e->subdir_filter)) { - return False; - } - - len = strlen(e->path); - - if (strncmp(path, e->path, len) != 0) { - return False; - } - - if (path[len] != '/') { - return False; - } - - /* the filter and subdir_filter are handled separately, allowing a backend - to flexibly choose what it can handle */ - subdir = (strchr(&path[len+1], '/') != NULL); - - if (subdir) { - return (filter & e->subdir_filter) != 0; - } - - return (filter & e->filter) != 0; -} - /* trigger a notify message for anyone waiting on a matching event + + This function is called a lot, and needs to be very fast. The unusual data structure + and traversal is designed to be fast in the average case, even for large numbers of + notifies */ void notify_trigger(struct notify_context *notify, uint32_t action, uint32_t filter, const char *path) { NTSTATUS status; - int i; + int depth; + const char *p, *next_p; status = notify_load(notify); if (!NT_STATUS_IS_OK(status)) { return; } - /* TODO: this needs to be changed to a log(n) search */ - for (i=0;iarray->num_entries;i++) { - if (notify_match(notify, ¬ify->array->entries[i], path, filter)) { - notify_send(notify, ¬ify->array->entries[i], - path + strlen(notify->array->entries[i].path) + 1, - action); + /* loop along the given path, working with each directory depth separately */ + for (depth=0,p=path; + p && depth < notify->array->num_depths; + p=next_p,depth++) { + int p_len = p - path; + int min_i, max_i, i; + struct notify_depth *d = ¬ify->array->depth[depth]; + next_p = strchr(p+1, '/'); + + /* see if there are any entries at this depth */ + if (d->num_entries == 0) continue; + + /* try to skip based on the maximum mask. If next_p is + NULL then we know it will be a 'this directory' + match, otherwise it must be a subdir match */ + if (next_p != NULL) { + if (0 == (filter & d->max_mask_subdir)) { + continue; + } + } else { + if (0 == (filter & d->max_mask)) { + continue; + } + } + + /* we know there is an entry here worth looking + for. Use a bisection search to find the first entry + with a matching path */ + min_i = 0; + max_i = d->num_entries-1; + + while (min_i < max_i) { + struct notify_entry *e; + i = (min_i+max_i)/2; + e = &d->entries[i]; + int cmp = strncmp(path, e->path, p_len); + if (cmp == 0) { + if (p_len == e->path_len) { + max_i = i; + } else { + max_i = i-1; + } + } else if (cmp < 0) { + max_i = i-1; + } else { + min_i = i+1; + } + } + + if (min_i != max_i) { + /* none match */ + continue; + } + + /* we now know that the entries start at min_i */ + for (i=min_i;inum_entries;i++) { + struct notify_entry *e = &d->entries[i]; + if (p_len != e->path_len || + strncmp(path, e->path, p_len) != 0) break; + if (next_p != NULL) { + if (0 == (filter & e->subdir_filter)) { + continue; + } + } else { + if (0 == (filter & e->filter)) { + continue; + } + } + notify_send(notify, e, path + e->path_len + 1, action); } } } diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 85831c80e9..13c8f4359a 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -42,7 +42,6 @@ struct sys_notify_context *sys_notify_init(int snum, { struct sys_notify_context *ctx; const char *bname; - struct sys_notify_backend *b; int i; if (num_backends == 0) { -- cgit From cd794e79f999b3b7b639c4fe89ea1af23ed362f6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Apr 2006 11:25:21 +0000 Subject: r14959: allow change notify to be disabled completely using notify:enable=False (This used to be commit 2a8f093105f3047a3697f29aadcc9c48c6ac88e1) --- source4/ntvfs/common/notify.c | 19 +++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 4 +--- 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 0c264de88f..452b8188f0 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -83,6 +83,10 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, char *path; struct notify_context *notify; + if (lp_parm_bool(snum, "notify", "enable", True) != True) { + return NULL; + } + notify = talloc(mem_ctx, struct notify_context); if (notify == NULL) { return NULL; @@ -339,6 +343,11 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, size_t len; int depth; + /* see if change notify is enabled at all */ + if (notify == NULL) { + return NT_STATUS_NOT_IMPLEMENTED; + } + status = notify_lock(notify); NT_STATUS_NOT_OK_RETURN(status); @@ -410,6 +419,11 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) int i, depth; struct notify_depth *d; + /* see if change notify is enabled at all */ + if (notify == NULL) { + return NT_STATUS_NOT_IMPLEMENTED; + } + for (listel=notify->list;listel;listel=listel->next) { if (listel->private == private) { DLIST_REMOVE(notify->list, listel); @@ -552,6 +566,11 @@ void notify_trigger(struct notify_context *notify, int depth; const char *p, *next_p; + /* see if change notify is enabled at all */ + if (notify == NULL) { + return; + } + status = notify_load(notify); if (!NT_STATUS_IS_OK(status)) { return; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 3e141219f4..dd8c3fe81f 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -185,14 +185,12 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + /* allow this to be NULL - we just disable change notify */ pvfs->notify_context = notify_init(pvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, event_context_find(pvfs), pvfs->ntvfs->ctx->config.snum); - if (pvfs->notify_context == NULL) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } pvfs->sidmap = sidmap_open(pvfs); if (pvfs->sidmap == NULL) { -- cgit From 26c9cd62118df387d03b1f467fa6bf07cf57d7ec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Apr 2006 11:44:55 +0000 Subject: r14960: don't declare variables mid-function (This used to be commit 4537de9289ce025a240fe46a708434c195138d20) --- source4/ntvfs/common/notify.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 452b8188f0..a701880701 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -609,9 +609,10 @@ void notify_trigger(struct notify_context *notify, while (min_i < max_i) { struct notify_entry *e; + int cmp; i = (min_i+max_i)/2; e = &d->entries[i]; - int cmp = strncmp(path, e->path, p_len); + cmp = strncmp(path, e->path, p_len); if (cmp == 0) { if (p_len == e->path_len) { max_i = i; -- cgit From 09eb876ac0f23f840042aed9bc891d25520636e8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Apr 2006 12:11:50 +0000 Subject: r14961: fix compiler warning tridge: please add checks after talloc_realloc() and talloc_strdup()! metze (This used to be commit c136191870f91d4ce652da535a1cd52f4772574d) --- source4/ntvfs/posix/pvfs_notify.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 652a5260d5..b5f2ad167a 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -109,11 +109,13 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) { struct pvfs_notify_buffer *n = talloc_get_type(private, struct pvfs_notify_buffer); size_t len; + char *new_path; n->changes = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1); n->changes[n->num_changes].action = ev->action; - n->changes[n->num_changes].name.s = talloc_strdup(n->changes, ev->path); - string_replace(n->changes[n->num_changes].name.s, '/', '\\'); + new_path = talloc_strdup(n->changes, ev->path); + string_replace(new_path, '/', '\\'); + n->changes[n->num_changes].name.s = new_path; n->num_changes++; /* -- cgit From 5b1a495e96be6f92df3ba2d30095d879041f757e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Apr 2006 12:32:51 +0000 Subject: r14963: check talloc returns (This used to be commit dd928e84ece04d35144befeda7a9b9dd597e4cf7) --- source4/ntvfs/posix/pvfs_notify.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index b5f2ad167a..592beb5a3e 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -109,12 +109,23 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) { struct pvfs_notify_buffer *n = talloc_get_type(private, struct pvfs_notify_buffer); size_t len; + struct notify_changes *n2; char *new_path; - n->changes = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1); - n->changes[n->num_changes].action = ev->action; + n2 = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1); + if (n2 == NULL) { + /* nothing much we can do for this */ + return; + } + n->changes = n2; + new_path = talloc_strdup(n->changes, ev->path); + if (new_path == NULL) { + return; + } string_replace(new_path, '/', '\\'); + + n->changes[n->num_changes].action = ev->action; n->changes[n->num_changes].name.s = new_path; n->num_changes++; -- cgit From 2e894625e7c951b5ee66670124b4bef82a8129d9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Apr 2006 13:15:46 +0000 Subject: r14964: - move sidmap code from ntvfs_common to SAMDB - make ntvfs_common a library - create sys_notify library metze (This used to be commit a3e1d56cf7b688c515f5d6d4d43e0b24c2261d15) --- source4/ntvfs/common/config.mk | 16 +- source4/ntvfs/common/init.c | 33 +++ source4/ntvfs/common/notify.c | 2 +- source4/ntvfs/common/sidmap.c | 566 ------------------------------------ source4/ntvfs/config.mk | 5 +- source4/ntvfs/posix/config.mk | 2 +- source4/ntvfs/posix/vfs_posix.c | 10 +- source4/ntvfs/posix/vfs_posix.h | 1 + source4/ntvfs/sysdep/config.m4 | 4 +- source4/ntvfs/sysdep/config.mk | 28 +- source4/ntvfs/sysdep/inotify.c | 2 +- source4/ntvfs/sysdep/sys_notify.c | 27 +- source4/ntvfs/sysdep/sys_notify.h | 9 +- source4/ntvfs/unixuid/config.mk | 1 + source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- 15 files changed, 105 insertions(+), 603 deletions(-) create mode 100644 source4/ntvfs/common/init.c delete mode 100644 source4/ntvfs/common/sidmap.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 6eb9073b73..96ddfb348b 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -1,13 +1,15 @@ ################################################ -# Start MODULE ntvfs_common -[MODULE::ntvfs_common] -SUBSYSTEM = ntvfs +# Start LIBRARY ntvfs_common +[LIBRARY::ntvfs_common] PRIVATE_PROTO_HEADER = proto.h +VERSION = 0.0.1 +SO_VERSION = 0 +DESCRIPTION = Generic Code for use in NTVFS modules OBJ_FILES = \ + init.o \ brlock.o \ opendb.o \ - notify.o \ - sidmap.o -REQUIRED_SUBSYSTEMS = -# End MODULE ntvfs_common + notify.o +REQUIRED_SUBSYSTEMS = NDR_OPENDB NDR_NOTIFY sys_notify +# End LIBRARY ntvfs_common ################################################ diff --git a/source4/ntvfs/common/init.c b/source4/ntvfs/common/init.c new file mode 100644 index 0000000000..6cdc70dc50 --- /dev/null +++ b/source4/ntvfs/common/init.c @@ -0,0 +1,33 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Stefan Metzmacher 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + this is the change notify database. It implements mechanisms for + storing current change notify waiters in a tdb, and checking if a + given event matches any of the stored notify waiiters. +*/ + +#include "includes.h" +#include "ntvfs/sysdep/sys_notify.h" + +_PUBLIC_ NTSTATUS ntvfs_common_init(void) +{ + return sys_notify_init(); +} diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index a701880701..2d880dd5c4 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -115,7 +115,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, messaging_register(notify->messaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); - notify->sys_notify_ctx = sys_notify_init(snum, notify, ev); + notify->sys_notify_ctx = sys_notify_context_create(snum, notify, ev); return notify; } diff --git a/source4/ntvfs/common/sidmap.c b/source4/ntvfs/common/sidmap.c deleted file mode 100644 index 6f3cd42b62..0000000000 --- a/source4/ntvfs/common/sidmap.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - mapping routines for SID <-> unix uid/gid - - Copyright (C) Andrew Tridgell 2004 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include "system/passwd.h" -#include "ads.h" -#include "dsdb/samdb/samdb.h" -#include "auth/auth.h" -#include "libcli/ldap/ldap.h" -#include "db_wrap.h" -#include "libcli/security/security.h" -#include "librpc/gen_ndr/ndr_security.h" - -/* - these are used for the fallback local uid/gid to sid mapping - code. -*/ -#define SIDMAP_LOCAL_USER_BASE 0x80000000 -#define SIDMAP_LOCAL_GROUP_BASE 0xC0000000 -#define SIDMAP_MAX_LOCAL_UID 0x3fffffff -#define SIDMAP_MAX_LOCAL_GID 0x3fffffff - -/* - private context for sid mapping routines -*/ -struct sidmap_context { - struct ldb_wrap *samctx; -}; - -/* - open a sidmap context - use talloc_free to close -*/ -struct sidmap_context *sidmap_open(TALLOC_CTX *mem_ctx) -{ - struct sidmap_context *sidmap; - sidmap = talloc(mem_ctx, struct sidmap_context); - if (sidmap == NULL) { - return NULL; - } - sidmap->samctx = samdb_connect(sidmap, system_session(sidmap)); - if (sidmap->samctx == NULL) { - talloc_free(sidmap); - return NULL; - } - - return sidmap; -} - - -/* - check the sAMAccountType field of a search result to see if - the account is a user account -*/ -static BOOL is_user_account(struct ldb_message *res) -{ - uint_t atype = samdb_result_uint(res, "sAMAccountType", 0); - if (atype && (!(atype & ATYPE_ACCOUNT))) { - return False; - } - return True; -} - -/* - check the sAMAccountType field of a search result to see if - the account is a group account -*/ -static BOOL is_group_account(struct ldb_message *res) -{ - uint_t atype = samdb_result_uint(res, "sAMAccountType", 0); - if (atype && atype == ATYPE_NORMAL_ACCOUNT) { - return False; - } - return True; -} - - - -/* - return the dom_sid of our primary domain -*/ -static NTSTATUS sidmap_primary_domain_sid(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, struct dom_sid **sid) -{ - const char *attrs[] = { "objectSid", NULL }; - int ret; - struct ldb_message **res = NULL; - - ret = gendb_search_dn(sidmap->samctx, mem_ctx, samdb_base_dn(mem_ctx), - &res, attrs); - if (ret != 1) { - talloc_free(res); - return NT_STATUS_NO_SUCH_DOMAIN; - } - - *sid = samdb_result_dom_sid(mem_ctx, res[0], "objectSid"); - talloc_free(res); - if (*sid == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - - -/* - map a sid to a unix uid -*/ -NTSTATUS sidmap_sid_to_unixuid(struct sidmap_context *sidmap, - struct dom_sid *sid, uid_t *uid) -{ - const char *attrs[] = { "sAMAccountName", "unixID", - "unixName", "sAMAccountType", NULL }; - int ret; - const char *s; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - struct dom_sid *domain_sid; - NTSTATUS status; - - tmp_ctx = talloc_new(sidmap); - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); - if (ret != 1) { - goto allocated_sid; - } - - /* make sure its a user, not a group */ - if (!is_user_account(res[0])) { - DEBUG(0,("sid_to_unixuid: sid %s is not an account!\n", - dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SID; - } - - /* first try to get the uid directly */ - s = samdb_result_string(res[0], "unixID", NULL); - if (s != NULL) { - *uid = strtoul(s, NULL, 0); - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "unixName", NULL); - if (s != NULL) { - struct passwd *pwd = getpwnam(s); - if (!pwd) { - DEBUG(0,("unixName %s for sid %s does not exist as a local user\n", s, - dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_USER; - } - *uid = pwd->pw_uid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* finally try via the sAMAccountName attribute */ - s = samdb_result_string(res[0], "sAMAccountName", NULL); - if (s != NULL) { - struct passwd *pwd = getpwnam(s); - if (!pwd) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local user\n", - s, dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_USER; - } - *uid = pwd->pw_uid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - -allocated_sid: - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_DOMAIN; - } - - if (dom_sid_in_domain(domain_sid, sid)) { - uint32_t rid = sid->sub_auths[sid->num_auths-1]; - if (rid >= SIDMAP_LOCAL_USER_BASE && - rid < SIDMAP_LOCAL_GROUP_BASE) { - *uid = rid - SIDMAP_LOCAL_USER_BASE; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - } - - - DEBUG(0,("sid_to_unixuid: no unixID, unixName or sAMAccountName for sid %s\n", - dom_sid_string(tmp_ctx, sid))); - - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SID; -} - - -/* - map a sid to a unix gid -*/ -NTSTATUS sidmap_sid_to_unixgid(struct sidmap_context *sidmap, - struct dom_sid *sid, gid_t *gid) -{ - const char *attrs[] = { "sAMAccountName", "unixID", - "unixName", "sAMAccountType", NULL }; - int ret; - const char *s; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - NTSTATUS status; - struct dom_sid *domain_sid; - - tmp_ctx = talloc_new(sidmap); - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "objectSid=%s", ldap_encode_ndr_dom_sid(tmp_ctx, sid)); - if (ret != 1) { - goto allocated_sid; - } - - /* make sure its not a user */ - if (!is_group_account(res[0])) { - DEBUG(0,("sid_to_unixgid: sid %s is a ATYPE_NORMAL_ACCOUNT\n", - dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SID; - } - - /* first try to get the gid directly */ - s = samdb_result_string(res[0], "unixID", NULL); - if (s != NULL) { - *gid = strtoul(s, NULL, 0); - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* next try via the UnixName attribute */ - s = samdb_result_string(res[0], "unixName", NULL); - if (s != NULL) { - struct group *grp = getgrnam(s); - if (!grp) { - DEBUG(0,("unixName '%s' for sid %s does not exist as a local group\n", - s, dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_USER; - } - *gid = grp->gr_gid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - - /* finally try via the sAMAccountName attribute */ - s = samdb_result_string(res[0], "sAMAccountName", NULL); - if (s != NULL) { - struct group *grp = getgrnam(s); - if (!grp) { - DEBUG(0,("sAMAccountName '%s' for sid %s does not exist as a local group\n", s, dom_sid_string(tmp_ctx, sid))); - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_USER; - } - *gid = grp->gr_gid; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - -allocated_sid: - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return NT_STATUS_NO_SUCH_DOMAIN; - } - - if (dom_sid_in_domain(domain_sid, sid)) { - uint32_t rid = sid->sub_auths[sid->num_auths-1]; - if (rid >= SIDMAP_LOCAL_GROUP_BASE) { - *gid = rid - SIDMAP_LOCAL_GROUP_BASE; - talloc_free(tmp_ctx); - return NT_STATUS_OK; - } - } - - DEBUG(0,("sid_to_unixgid: no unixID, unixName or sAMAccountName for sid %s\n", - dom_sid_string(tmp_ctx, sid))); - - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SID; -} - - -/* - map a unix uid to a dom_sid - the returned sid is allocated in the supplied mem_ctx -*/ -NTSTATUS sidmap_uid_to_sid(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, - uid_t uid, struct dom_sid **sid) -{ - const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL }; - int ret, i; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - struct passwd *pwd; - struct dom_sid *domain_sid; - NTSTATUS status; - - /* - we search for the mapping in the following order: - - - check if the uid is in the dynamic uid range assigned for winbindd - use. If it is, then look in winbindd sid mapping - database (not implemented yet) - - look for a user account in samdb that has unixID set to the - given uid - - look for a user account in samdb that has unixName or - sAMAccountName set to the name given by getpwuid() - - assign a SID by adding the uid to SIDMAP_LOCAL_USER_BASE in the local - domain - */ - - - tmp_ctx = talloc_new(mem_ctx); - - - /* - step 2: look for a user account in samdb that has unixID set to the - given uid - */ - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "unixID=%u", (unsigned int)uid); - for (i=0;isamctx, tmp_ctx, NULL, &res, attrs, - "(|(unixName=%s)(sAMAccountName=%s))", - pwd->pw_name, pwd->pw_name); - for (i=0;i SIDMAP_MAX_LOCAL_UID) { - return NT_STATUS_INVALID_SID; - } - - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - - *sid = dom_sid_add_rid(mem_ctx, domain_sid, SIDMAP_LOCAL_USER_BASE + uid); - talloc_free(tmp_ctx); - - if (*sid == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - - -/* - map a unix gid to a dom_sid - the returned sid is allocated in the supplied mem_ctx -*/ -NTSTATUS sidmap_gid_to_sid(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, - gid_t gid, struct dom_sid **sid) -{ - const char *attrs[] = { "sAMAccountName", "objectSid", "sAMAccountType", NULL }; - int ret, i; - TALLOC_CTX *tmp_ctx; - struct ldb_message **res; - struct group *grp; - struct dom_sid *domain_sid; - NTSTATUS status; - - /* - we search for the mapping in the following order: - - - check if the gid is in the dynamic gid range assigned for winbindd - use. If it is, then look in winbindd sid mapping - database (not implemented yet) - - look for a group account in samdb that has unixID set to the - given gid - - look for a group account in samdb that has unixName or - sAMAccountName set to the name given by getgrgid() - - assign a SID by adding the gid to SIDMAP_LOCAL_GROUP_BASE in the local - domain - */ - - - tmp_ctx = talloc_new(sidmap); - - - /* - step 2: look for a group account in samdb that has unixID set to the - given gid - */ - - ret = gendb_search(sidmap->samctx, tmp_ctx, NULL, &res, attrs, - "unixID=%u", (unsigned int)gid); - for (i=0;isamctx, tmp_ctx, NULL, &res, attrs, - "(|(unixName=%s)(sAMAccountName=%s))", - grp->gr_name, grp->gr_name); - for (i=0;i SIDMAP_MAX_LOCAL_GID) { - return NT_STATUS_INVALID_SID; - } - - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - - *sid = dom_sid_add_rid(mem_ctx, domain_sid, SIDMAP_LOCAL_GROUP_BASE + gid); - talloc_free(tmp_ctx); - - if (*sid == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - -/* - check if a sid is in the range of auto-allocated SIDs from our primary domain, - and if it is, then return the name and atype -*/ -NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, - TALLOC_CTX *mem_ctx, - const struct dom_sid *sid, - const char **name, - uint32_t *atype) -{ - NTSTATUS status; - struct dom_sid *domain_sid; - TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - uint32_t rid; - - status = sidmap_primary_domain_sid(sidmap, tmp_ctx, &domain_sid); - if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_NO_SUCH_DOMAIN; - } - - if (!dom_sid_in_domain(domain_sid, sid)) { - talloc_free(tmp_ctx); - return NT_STATUS_INVALID_SID; - } - - talloc_free(tmp_ctx); - - rid = sid->sub_auths[sid->num_auths-1]; - if (rid < SIDMAP_LOCAL_USER_BASE) { - return NT_STATUS_INVALID_SID; - } - - if (rid < SIDMAP_LOCAL_GROUP_BASE) { - struct passwd *pwd; - uid_t uid = rid - SIDMAP_LOCAL_USER_BASE; - *atype = ATYPE_NORMAL_ACCOUNT; - pwd = getpwuid(uid); - if (pwd == NULL) { - *name = talloc_asprintf(mem_ctx, "uid%u", uid); - } else { - *name = talloc_strdup(mem_ctx, pwd->pw_name); - } - } else { - struct group *grp; - gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE; - *atype = ATYPE_LOCAL_GROUP; - grp = getgrgid(gid); - if (grp == NULL) { - *name = talloc_asprintf(mem_ctx, "gid%u", gid); - } else { - *name = talloc_strdup(mem_ctx, grp->gr_name); - } - } - - if (*name == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 2a35bd5cb3..d11e2c848d 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -48,12 +48,11 @@ OBJ_FILES = \ ipc/vfs_ipc.o \ ipc/ipc_rap.o \ ipc/rap_server.o -REQUIRED_SUBSYSTEMS = DCERPC_COMMON dcerpc_server +REQUIRED_SUBSYSTEMS = dcerpc_server # End MODULE ntvfs_ipc ################################################ - ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] @@ -78,7 +77,7 @@ OBJ_FILES = \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o -REQUIRED_SUBSYSTEMS = NDR_OPENDB NDR_NOTIFY +REQUIRED_SUBSYSTEMS = # # End SUBSYSTEM NTVFS ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index c49fbc88b7..b9724cb9f2 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -32,6 +32,6 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o -REQUIRED_SUBSYSTEMS = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID +REQUIRED_SUBSYSTEMS = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID ntvfs_common # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index dd8c3fe81f..c4d4d11c04 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -332,11 +332,19 @@ NTSTATUS ntvfs_posix_init(void) ops.name = "default"; ret = ntvfs_register(&ops); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); + } + ops.name = "posix"; ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register POSIX backend!\n")); + DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); + } + + if (NT_STATUS_IS_OK(ret)) { + ret = ntvfs_common_init(); } return ret; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index f34529bc0f..335cfdf4e0 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -27,6 +27,7 @@ #include "system/filesys.h" #include "ntvfs/ntvfs.h" #include "ntvfs/common/proto.h" +#include "dsdb/samdb/samdb.h" /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ diff --git a/source4/ntvfs/sysdep/config.m4 b/source4/ntvfs/sysdep/config.m4 index f67a3bdace..372e6b5bd5 100644 --- a/source4/ntvfs/sysdep/config.m4 +++ b/source4/ntvfs/sysdep/config.m4 @@ -1,7 +1,7 @@ AC_CHECK_HEADERS(linux/inotify.h asm/unistd.h) AC_CHECK_FUNC(inotify_init) -SMB_ENABLE(ntvfs_inotify, NO) +SMB_ENABLE(sys_notify_inotify, NO) if test x"$ac_cv_header_linux_inotify_h" = x"yes"; then - SMB_ENABLE(ntvfs_inotify, YES) + SMB_ENABLE(sys_notify_inotify, YES) fi diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 3bcebb5c0e..3b3681adef 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -1,20 +1,22 @@ ################################################ -# Start MODULE ntvfs_sys_notify -[MODULE::ntvfs_sys_notify] -SUBSYSTEM = ntvfs +# Start MODULE sys_notify_inotify +[MODULE::sys_notify_inotify] +SUBSYSTEM = sys_notify +INIT_FUNCTION = sys_notify_inotify_init OBJ_FILES = \ - sys_notify.o -# End MODULE ntvfs_sys_notify + inotify.o +# End MODULE sys_notify_inotify ################################################ - ################################################ -# Start MODULE ntvfs_inotify -[MODULE::ntvfs_inotify] -SUBSYSTEM = ntvfs -INIT_FUNCTION = ntvfs_inotify_init +# Start SUBSYSTEM sys_notify +[LIBRARY::sys_notify] +PUBLIC_HEADERS = sys_notify.h +VERSION = 0.0.1 +SO_VERSION = 0 +DESCRIPTION = File System Notify Abstraction Layer OBJ_FILES = \ - inotify.o -# End MODULE ntvfs_inotify + sys_notify.o +REQUIRED_SUBSYSTEMS = +# End SUBSYSTEM sys_notify ################################################ - diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index f86e3c1913..33c4ff4928 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -405,7 +405,7 @@ static struct sys_notify_backend inotify = { /* initialialise the inotify module */ -NTSTATUS ntvfs_inotify_init(void) +NTSTATUS sys_notify_inotify_init(void) { /* register ourselves as a system inotify module */ return sys_notify_register(&inotify); diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 13c8f4359a..a74312f32b 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -28,6 +28,7 @@ #include "ntvfs/sysdep/sys_notify.h" #include "lib/events/events.h" #include "dlinklist.h" +#include "build.h" /* list of registered backends */ static struct sys_notify_backend *backends; @@ -36,9 +37,9 @@ static uint32_t num_backends; /* initialise a system change notify backend */ -struct sys_notify_context *sys_notify_init(int snum, - TALLOC_CTX *mem_ctx, - struct event_context *ev) +struct sys_notify_context *sys_notify_context_create(int snum, + TALLOC_CTX *mem_ctx, + struct event_context *ev) { struct sys_notify_context *ctx; const char *bname; @@ -115,3 +116,23 @@ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) num_backends++; return NT_STATUS_OK; } + +NTSTATUS sys_notify_init(void) +{ + static BOOL initialized = False; + + init_module_fn static_init[] = STATIC_sys_notify_MODULES; + init_module_fn *shared_init; + + if (initialized) return NT_STATUS_OK; + initialized = True; + + shared_init = load_samba_modules(NULL, "sys_notify"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); + + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h index 9cb01a1db4..6f8e91efec 100644 --- a/source4/ntvfs/sysdep/sys_notify.h +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -26,7 +26,7 @@ typedef void (*sys_notify_callback_t)(struct sys_notify_context *, void *, struct notify_event *ev); typedef NTSTATUS (*notify_watch_t)(struct sys_notify_context *ctx, - struct notify_event *e, + struct notify_entry *e, sys_notify_callback_t callback, void *private, void **handle); @@ -43,9 +43,10 @@ struct sys_notify_backend { }; NTSTATUS sys_notify_register(struct sys_notify_backend *backend); -struct sys_notify_context *sys_notify_init(int snum, - TALLOC_CTX *mem_ctx, - struct event_context *ev); +struct sys_notify_context *sys_notify_context_create(int snum, + TALLOC_CTX *mem_ctx, + struct event_context *ev); NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, sys_notify_callback_t callback, void *private, void **handle); +NTSTATUS sys_notify_init(void); diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 3fdeb79e3d..f8af68eb9b 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -5,5 +5,6 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs OBJ_FILES = \ vfs_unixuid.o +REQUIRED_SUBSYSTEMS = SAMDB # End MODULE ntvfs_unixuid ################################################ diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 1bfaf85e70..061b8fbe55 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -26,7 +26,7 @@ #include "system/passwd.h" #include "auth/auth.h" #include "ntvfs/ntvfs.h" -#include "ntvfs/common/proto.h" +#include "dsdb/samdb/samdb.h" struct unixuid_private { struct sidmap_context *sidmap; -- cgit From 7672505c72c34a5e35dc05cf3fdc0d49e974a690 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Apr 2006 14:14:27 +0000 Subject: r14966: make more functions _PUBLIC_ metze (This used to be commit 193f7da254cce40ab30fda9e99b8cd07e0b0a0a8) --- source4/ntvfs/common/opendb.c | 38 +++++++++++++++++++------------------- source4/ntvfs/sysdep/sys_notify.c | 14 +++++++------- 2 files changed, 26 insertions(+), 26 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 0890bb112d..81a13857ab 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -68,8 +68,8 @@ struct odb_lock { talloc_free(). We need the messaging_ctx to allow for pending open notifications. */ -struct odb_context *odb_init(TALLOC_CTX *mem_ctx, uint32_t server, - struct messaging_context *messaging_ctx) +_PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, uint32_t server, + struct messaging_context *messaging_ctx) { char *path; struct odb_context *odb; @@ -109,8 +109,8 @@ static int odb_lock_destructor(void *ptr) get a lock on a entry in the odb. This call returns a lock handle, which the caller should unlock using talloc_free(). */ -struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, - struct odb_context *odb, DATA_BLOB *file_key) +_PUBLIC_ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, + struct odb_context *odb, DATA_BLOB *file_key) { struct odb_lock *lck; @@ -257,10 +257,10 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) Note that the path is only used by the delete on close logic, not for comparing with other filenames */ -NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, - uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, BOOL delete_on_close, - const char *path) +_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, BOOL delete_on_close, + const char *path) { struct odb_context *odb = lck->odb; struct opendb_entry e; @@ -312,7 +312,7 @@ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, /* register a pending open file in the open files database */ -NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) +_PUBLIC_ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) { struct odb_context *odb = lck->odb; struct opendb_file file; @@ -337,7 +337,7 @@ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) /* remove a opendb entry */ -NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) +_PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) { struct odb_context *odb = lck->odb; struct opendb_file file; @@ -384,7 +384,7 @@ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) /* remove a pending opendb entry */ -NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) +_PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) { struct odb_context *odb = lck->odb; int i; @@ -420,7 +420,7 @@ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) /* rename the path in a open file */ -NTSTATUS odb_rename(struct odb_lock *lck, const char *path) +_PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) { struct opendb_file file; NTSTATUS status; @@ -439,7 +439,7 @@ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) /* update delete on close flag on an open file */ -NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) +_PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) { NTSTATUS status; struct opendb_file file; @@ -456,9 +456,9 @@ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) return the current value of the delete_on_close bit, and how many people still have the file open */ -NTSTATUS odb_get_delete_on_close(struct odb_context *odb, - DATA_BLOB *key, BOOL *del_on_close, - int *open_count, char **path) +_PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, + DATA_BLOB *key, BOOL *del_on_close, + int *open_count, char **path) { NTSTATUS status; struct opendb_file file; @@ -500,9 +500,9 @@ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, determine if a file can be opened with the given share_access, create_options and access_mask */ -NTSTATUS odb_can_open(struct odb_lock *lck, - uint32_t share_access, uint32_t create_options, - uint32_t access_mask) +_PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, + uint32_t share_access, uint32_t create_options, + uint32_t access_mask) { struct odb_context *odb = lck->odb; NTSTATUS status; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index a74312f32b..c4fa4647d1 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -37,9 +37,9 @@ static uint32_t num_backends; /* initialise a system change notify backend */ -struct sys_notify_context *sys_notify_context_create(int snum, - TALLOC_CTX *mem_ctx, - struct event_context *ev) +_PUBLIC_ struct sys_notify_context *sys_notify_context_create(int snum, + TALLOC_CTX *mem_ctx, + struct event_context *ev) { struct sys_notify_context *ctx; const char *bname; @@ -93,8 +93,8 @@ struct sys_notify_context *sys_notify_context_create(int snum, bits to remove ones handled by this backend. Any remaining bits will be handled by the generic notify layer */ -NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, - sys_notify_callback_t callback, void *private, void **handle) +_PUBLIC_ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, + sys_notify_callback_t callback, void *private, void **handle) { if (!ctx->notify_watch) { return NT_STATUS_INVALID_SYSTEM_SERVICE; @@ -105,7 +105,7 @@ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e /* register a notify backend */ -NTSTATUS sys_notify_register(struct sys_notify_backend *backend) +_PUBLIC_ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) { struct sys_notify_backend *b; b = talloc_realloc(talloc_autofree_context(), backends, @@ -117,7 +117,7 @@ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) return NT_STATUS_OK; } -NTSTATUS sys_notify_init(void) +_PUBLIC_ NTSTATUS sys_notify_init(void) { static BOOL initialized = False; -- cgit From 5d221987c7aad409b78c31f8eed3059d7fb317c3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Apr 2006 07:54:15 +0000 Subject: r14990: talloc_reference() can fail metze (This used to be commit 4410d7ea5d356f9a04f419f7254a60c20b1345c0) --- source4/ntvfs/posix/pvfs_notify.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 592beb5a3e..ea4c0b2bc6 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -236,6 +236,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(pending); pending->req = talloc_reference(pending, req); + NT_STATUS_HAVE_NO_MEMORY(pending->req); pending->info = info; DLIST_ADD_END(f->notify_buffer->pending, pending, struct notify_pending *); -- cgit From fd4a8ad8c38ea94355ba22a0b622163b3f541c5e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Apr 2006 13:53:11 +0000 Subject: r14993: Make subsystems again (This used to be commit d55b040bd280c86423f2a620dfc0341accb23cc4) --- source4/ntvfs/common/config.mk | 5 +---- source4/ntvfs/sysdep/config.mk | 6 +----- 2 files changed, 2 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 96ddfb348b..5b2c8ddba7 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -1,10 +1,7 @@ ################################################ # Start LIBRARY ntvfs_common -[LIBRARY::ntvfs_common] +[SUBSYSTEM::ntvfs_common] PRIVATE_PROTO_HEADER = proto.h -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = Generic Code for use in NTVFS modules OBJ_FILES = \ init.o \ brlock.o \ diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 3b3681adef..91d739f7b7 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -10,11 +10,7 @@ OBJ_FILES = \ ################################################ # Start SUBSYSTEM sys_notify -[LIBRARY::sys_notify] -PUBLIC_HEADERS = sys_notify.h -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = File System Notify Abstraction Layer +[SUBSYSTEM::sys_notify] OBJ_FILES = \ sys_notify.o REQUIRED_SUBSYSTEMS = -- cgit From bfa8d649096c417fd67fcdeaf899c1fab4bcda3e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 10 Apr 2006 12:15:40 +0000 Subject: r15017: When making up our own inotify functions, make sure glibc exports the __NR_inotify_* syscall numbers before trying. (This used to be commit 5e79adda7c7e00c194efd1a5e57671f7bd34fe50) --- source4/ntvfs/sysdep/config.m4 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/config.m4 b/source4/ntvfs/sysdep/config.m4 index 372e6b5bd5..46787f9f0f 100644 --- a/source4/ntvfs/sysdep/config.m4 +++ b/source4/ntvfs/sysdep/config.m4 @@ -1,7 +1,13 @@ AC_CHECK_HEADERS(linux/inotify.h asm/unistd.h) AC_CHECK_FUNC(inotify_init) +AC_CHECK_DECL(__NR_inotify_init) SMB_ENABLE(sys_notify_inotify, NO) -if test x"$ac_cv_header_linux_inotify_h" = x"yes"; then + +if test x"$ac_cv_func_inotify_init" = x"yes" -a x"$ac_cv_header_linux_inotify_h" = x"yes"; then + SMB_ENABLE(sys_notify_inotify, YES) +fi + +if test x"$ac_cv_header_linux_inotify_h" = x"yes" -a x"$ac_cv_have_decl___NR_inotify_init"; then SMB_ENABLE(sys_notify_inotify, YES) fi -- cgit From 3979da11a4685a029bf5b7cbc8ec0c4216e8cf08 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Apr 2006 01:19:20 +0000 Subject: r15029: fixed the detection of inotify (This used to be commit 5471b4b1a812dad3c97c97b938bd2dc41ae32420) --- source4/ntvfs/sysdep/config.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/config.m4 b/source4/ntvfs/sysdep/config.m4 index 46787f9f0f..f70cac5e64 100644 --- a/source4/ntvfs/sysdep/config.m4 +++ b/source4/ntvfs/sysdep/config.m4 @@ -1,6 +1,6 @@ AC_CHECK_HEADERS(linux/inotify.h asm/unistd.h) AC_CHECK_FUNC(inotify_init) -AC_CHECK_DECL(__NR_inotify_init) +AC_HAVE_DECL(__NR_inotify_init, [#include ]) SMB_ENABLE(sys_notify_inotify, NO) @@ -8,6 +8,6 @@ if test x"$ac_cv_func_inotify_init" = x"yes" -a x"$ac_cv_header_linux_inotify_h" SMB_ENABLE(sys_notify_inotify, YES) fi -if test x"$ac_cv_header_linux_inotify_h" = x"yes" -a x"$ac_cv_have_decl___NR_inotify_init"; then +if test x"$ac_cv_header_linux_inotify_h" = x"yes" -a x"$ac_cv_have___NR_inotify_init_decl" = x"yes"; then SMB_ENABLE(sys_notify_inotify, YES) fi -- cgit From 289911bb4e7980bf42cc87305d3f94477c5f2b75 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Apr 2006 04:42:40 +0000 Subject: r15048: started on the server side implementation of oplocks. The code is not functional yet, I'm committing so it doesn't diverge too much from other peoples work. It is disabled by default. (This used to be commit ba0b8a218dfe1ef6cdf7de724fb30650301369dd) --- source4/ntvfs/common/opendb.c | 105 +++++++++++++++++++++++++++++++--------- source4/ntvfs/posix/pvfs_open.c | 51 +++++++++++++------ source4/ntvfs/posix/vfs_posix.c | 4 +- 3 files changed, 120 insertions(+), 40 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 81a13857ab..fc981d5af6 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -47,11 +47,12 @@ #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" #include "smb.h" +#include "ntvfs/ntvfs.h" struct odb_context { struct tdb_wrap *w; - uint32_t server; - struct messaging_context *messaging_ctx; + struct ntvfs_context *ntvfs_ctx; + BOOL oplocks; }; /* @@ -68,8 +69,8 @@ struct odb_lock { talloc_free(). We need the messaging_ctx to allow for pending open notifications. */ -_PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, uint32_t server, - struct messaging_context *messaging_ctx) +_PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, + struct ntvfs_context *ntvfs_ctx) { char *path; struct odb_context *odb; @@ -89,8 +90,10 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, uint32_t server, return NULL; } - odb->server = server; - odb->messaging_ctx = messaging_ctx; + odb->ntvfs_ctx = ntvfs_ctx; + + /* leave oplocks disabled by default until the code is working */ + odb->oplocks = lp_parm_bool(-1, "opendb", "oplocks", False); return odb; } @@ -249,6 +252,16 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) return NT_STATUS_OK; } +/* + send an oplock break to a client +*/ +static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_entry *e) +{ + /* tell the server handling this open file about the need to send the client + a break */ + return messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, e->server, + MSG_NTVFS_OPLOCK_BREAK, e->file_handle); +} /* register an open file in the open files database. This implements the share_access @@ -260,7 +273,8 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, BOOL delete_on_close, - const char *path) + const char *path, + uint32_t oplock_level, uint32_t *oplock_granted) { struct odb_context *odb = lck->odb; struct opendb_entry e; @@ -268,6 +282,10 @@ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, struct opendb_file file; NTSTATUS status; + if (odb->oplocks == False) { + oplock_level = OPLOCK_NONE; + } + status = odb_pull_record(lck, &file); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { /* initialise a blank structure */ @@ -277,27 +295,70 @@ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, NT_STATUS_NOT_OK_RETURN(status); } - - if (file.delete_on_close || - (file.num_entries != 0 && delete_on_close)) { - /* while delete on close is set, no new opens are allowed */ - return NT_STATUS_DELETE_PENDING; - } - /* see if it conflicts */ - e.server = odb->server; + e.server = odb->ntvfs_ctx->server_id; e.file_handle = file_handle; e.stream_id = stream_id; e.share_access = share_access; e.access_mask = access_mask; e.delete_on_close = delete_on_close; + e.oplock_level = OPLOCK_NONE; + /* see if anyone has an oplock, which we need to break */ + for (i=0;iserver; + file.pending[file.num_pending].server = odb->ntvfs_ctx->server_id; file.pending[file.num_pending].notify_ptr = private; file.num_pending++; @@ -350,7 +411,7 @@ _PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) /* find the entry, and delete it */ for (i=0;iserver == file.entries[i].server) { + odb->ntvfs_ctx->server_id == file.entries[i].server) { if (file.entries[i].delete_on_close) { file.delete_on_close = True; } @@ -369,7 +430,7 @@ _PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) /* send any pending notifications, removing them once sent */ for (i=0;imessaging_ctx, file.pending[i].server, + messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, file.pending[i].server, MSG_PVFS_RETRY_OPEN, file.pending[i].notify_ptr); } @@ -397,7 +458,7 @@ _PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) /* find the entry, and delete it */ for (i=0;iserver == file.pending[i].server) { + odb->ntvfs_ctx->server_id == file.pending[i].server) { if (i < file.num_pending-1) { memmove(file.pending+i, file.pending+i+1, (file.num_pending - (i+1)) * @@ -525,7 +586,7 @@ _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, return NT_STATUS_DELETE_PENDING; } - e.server = odb->server; + e.server = odb->ntvfs_ctx->server_id; e.file_handle = NULL; e.stream_id = 0; e.share_access = share_access; @@ -536,7 +597,7 @@ _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, if (!NT_STATUS_IS_OK(status)) { /* note that we discard the error code here. We do this as unless we are actually - doing an open (which comes via a sdifferent + doing an open (which comes via a different function), we need to return a sharing violation */ return NT_STATUS_SHARING_VIOLATION; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5afb538db7..0a2cab8747 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -313,7 +313,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* see if we are allowed to open at the same time as existing opens */ status = odb_open_file(lck, f->handle, f->handle->name->stream_id, - share_access, access_mask, del_on_close, name->full_name); + share_access, access_mask, del_on_close, + name->full_name, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->files.idtree, f->fnum); @@ -369,7 +370,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } status = odb_open_file(lck, f->handle, f->handle->name->stream_id, - share_access, access_mask, del_on_close, name->full_name); + share_access, access_mask, del_on_close, + name->full_name, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; @@ -563,6 +565,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t attrib; BOOL del_on_close; struct pvfs_filename *parent; + uint32_t oplock_level = OPLOCK_NONE, oplock_granted; if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { @@ -678,8 +681,17 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, del_on_close = False; } + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { + oplock_level = OPLOCK_NONE; + } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK) { + oplock_level = OPLOCK_BATCH; + } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_OPLOCK) { + oplock_level = OPLOCK_EXCLUSIVE; + } + status = odb_open_file(lck, f->handle, name->stream_id, - share_access, access_mask, del_on_close, name->full_name); + share_access, access_mask, del_on_close, + name->full_name, oplock_level, &oplock_granted); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { /* bad news, we must have hit a race - we don't delete the file @@ -690,6 +702,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { + oplock_granted = OPLOCK_BATCH; + } + f->fnum = fnum; f->session_info = req->session_info; f->smbpid = req->smbpid; @@ -718,12 +734,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, talloc_set_destructor(f, pvfs_fnum_destructor); talloc_set_destructor(f->handle, pvfs_handle_destructor); - - if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { - io->generic.out.oplock_level = OPLOCK_BATCH; - } else { - io->generic.out.oplock_level = OPLOCK_NONE; - } + io->generic.out.oplock_level = oplock_granted; io->generic.out.file.fnum = f->fnum; io->generic.out.create_action = NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; @@ -994,6 +1005,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t share_access; uint32_t access_mask; BOOL stream_existed, stream_truncate=False; + uint32_t oplock_level = OPLOCK_NONE, oplock_granted; /* use the generic mapping code to avoid implementing all the different open calls. */ @@ -1174,9 +1186,18 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_set_destructor(f, pvfs_fnum_destructor); talloc_set_destructor(f->handle, pvfs_handle_destructor); + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { + oplock_level = OPLOCK_NONE; + } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK) { + oplock_level = OPLOCK_BATCH; + } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_OPLOCK) { + oplock_level = OPLOCK_EXCLUSIVE; + } + /* see if we are allowed to open at the same time as existing opens */ status = odb_open_file(lck, f->handle, f->handle->name->stream_id, - share_access, access_mask, False, name->full_name); + share_access, access_mask, False, name->full_name, + oplock_level, &oplock_granted); /* on a sharing violation we need to retry when the file is closed by the other user, or after 1 second */ @@ -1190,6 +1211,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { + oplock_granted = OPLOCK_BATCH; + } + f->handle->have_opendb_entry = True; if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { @@ -1252,11 +1277,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_free(lck); - if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { - io->generic.out.oplock_level = OPLOCK_BATCH; - } else { - io->generic.out.oplock_level = OPLOCK_NONE; - } + io->generic.out.oplock_level = oplock_granted; io->generic.out.file.fnum = f->fnum; io->generic.out.create_action = stream_existed? NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index c4d4d11c04..eddc49c919 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -178,9 +178,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - pvfs->odb_context = odb_init(pvfs, - pvfs->ntvfs->ctx->server_id, - pvfs->ntvfs->ctx->msg_ctx); + pvfs->odb_context = odb_init(pvfs, pvfs->ntvfs->ctx); if (pvfs->odb_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From e91394ceccd762a204e3b59d379173fd1090ff41 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Apr 2006 16:19:42 +0000 Subject: r15056: w2k3 gives NT_STATUS_ACCESS_DENIED instead of NT_STATUS_ACCESS_VIOLATION metze (This used to be commit 5c1d96b36f14538360d90afc76ddba59d4feee1b) --- source4/ntvfs/posix/pvfs_write.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 298c95e90b..1da1985550 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -50,16 +50,14 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, } if (!(f->access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA))) { - return NT_STATUS_ACCESS_VIOLATION; + return NT_STATUS_ACCESS_DENIED; } status = pvfs_check_lock(pvfs, f, req->smbpid, wr->writex.in.offset, wr->writex.in.count, WRITE_LOCK); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NT_STATUS_NOT_OK_RETURN(status); if (f->handle->name->stream_name) { ret = pvfs_stream_write(pvfs, -- cgit From f347be4c738450e910d8453cef03c273069899a3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Apr 2006 16:27:53 +0000 Subject: r15057: fix access masks for getting and setting security_descriptors I'll add some torture tests later... metze (This used to be commit ce045f4df37b6740f2bf849fd06ab51c682ea0b7) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 22 ++++++++++++++++------ source4/ntvfs/posix/pvfs_setfileinfo.c | 11 +++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index fb1b0aa3f9..e4e69a8289 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -28,11 +28,11 @@ /* determine what access bits are needed for a call */ -static uint32_t pvfs_fileinfo_access(enum smb_fileinfo_level level) +static uint32_t pvfs_fileinfo_access(union smb_fileinfo *info) { uint32_t needed; - switch (level) { + switch (info->generic.level) { case RAW_FILEINFO_EA_LIST: case RAW_FILEINFO_ALL_EAS: needed = SEC_FILE_READ_EA; @@ -43,14 +43,24 @@ static uint32_t pvfs_fileinfo_access(enum smb_fileinfo_level level) break; case RAW_FILEINFO_SEC_DESC: - needed = SEC_STD_READ_CONTROL; + needed = 0; + if (info->query_secdesc.in.secinfo_flags & (SECINFO_OWNER|SECINFO_GROUP)) { + needed |= SEC_STD_READ_CONTROL; + } + if (info->query_secdesc.in.secinfo_flags & SECINFO_DACL) { + needed |= SEC_STD_READ_CONTROL; + } + if (info->query_secdesc.in.secinfo_flags & SECINFO_SACL) { + needed |= SEC_FLAG_SYSTEM_SECURITY; + } break; default: needed = SEC_FILE_READ_ATTRIBUTE; break; } - return needed; + + return needed; } /* @@ -304,7 +314,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, } status = pvfs_access_check_simple(pvfs, req, name, - pvfs_fileinfo_access(info->generic.level)); + pvfs_fileinfo_access(info)); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -332,7 +342,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, } h = f->handle; - access_needed = pvfs_fileinfo_access(info->generic.level); + access_needed = pvfs_fileinfo_access(info); if ((f->access_mask & access_needed) != access_needed) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 7661d1eb45..e85f52fc2c 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -53,16 +53,23 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) case RAW_SFILEINFO_SEC_DESC: needed = 0; - if (info->set_secdesc.in.secinfo_flags & (SECINFO_DACL|SECINFO_SACL)) { + if (info->set_secdesc.in.secinfo_flags & (SECINFO_OWNER|SECINFO_GROUP)) { + needed |= SEC_STD_WRITE_OWNER; + } + if (info->set_secdesc.in.secinfo_flags & SECINFO_DACL) { needed |= SEC_STD_WRITE_DAC; } + if (info->set_secdesc.in.secinfo_flags & SECINFO_SACL) { + needed |= SEC_FLAG_SYSTEM_SECURITY; + } break; default: needed = SEC_FILE_WRITE_ATTRIBUTE; break; } - return needed; + + return needed; } /* -- cgit From 0dd63e0432d185c1f2397c7cc95489c2d50fc2c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Apr 2006 11:34:39 +0000 Subject: r15069: - don't crash on a NULL acl - add the correct access checks for changing sd->group and sd->dacl metze (This used to be commit 2a61f65cd4084bf690caccf87efaf46551a13aee) --- source4/ntvfs/posix/pvfs_acl.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 53ee63dc0a..90c357934c 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -52,6 +52,8 @@ static void pvfs_translate_generic_bits(struct security_acl *acl) { unsigned i; + if (!acl) return; + for (i=0;inum_aces;i++) { struct security_ace *ace = &acl->aces[i]; ace->access_mask = pvfs_translate_mask(ace->access_mask); @@ -236,6 +238,9 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } if ((secinfo_flags & SECINFO_GROUP) && !dom_sid_equal(sd->group_sid, new_sd->group_sid)) { + if (!(access_mask & SEC_STD_WRITE_OWNER)) { + return NT_STATUS_ACCESS_DENIED; + } sd->group_sid = new_sd->group_sid; status = sidmap_sid_to_unixgid(pvfs->sidmap, sd->owner_sid, &gid); if (!NT_STATUS_IS_OK(status)) { @@ -243,14 +248,17 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } } if (secinfo_flags & SECINFO_DACL) { + if (!(access_mask & SEC_STD_WRITE_DAC)) { + return NT_STATUS_ACCESS_DENIED; + } sd->dacl = new_sd->dacl; pvfs_translate_generic_bits(sd->dacl); } if (secinfo_flags & SECINFO_SACL) { - sd->sacl = new_sd->sacl; if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) { return NT_STATUS_ACCESS_DENIED; } + sd->sacl = new_sd->sacl; pvfs_translate_generic_bits(sd->sacl); } -- cgit From 732027b87a25e1b0d2df3335bab95be90b6cc984 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Apr 2006 12:03:05 +0000 Subject: r15071: fix typo metze (This used to be commit fde8922947551f5f7d50607c5c83feba062138c8) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 90c357934c..c2afdbec24 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -242,7 +242,7 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, return NT_STATUS_ACCESS_DENIED; } sd->group_sid = new_sd->group_sid; - status = sidmap_sid_to_unixgid(pvfs->sidmap, sd->owner_sid, &gid); + status = sidmap_sid_to_unixgid(pvfs->sidmap, sd->group_sid, &gid); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 8302b889b410934330ed9c7c492d9b26b3bce58a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Apr 2006 12:59:41 +0000 Subject: r15078: add TODO about setting the full ACL with an NTTRANS_CREATE metze (This used to be commit bd2c899d83615066fbd1332495a4610eeea8f8ee) --- source4/ntvfs/posix/pvfs_open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 0a2cab8747..488f2d9568 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -143,7 +143,7 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, /* setup an initial sec_desc if requested */ if (io->ntcreatex.in.sec_desc) { union smb_setfileinfo set; - +/* TODO: set the full ACL! */ set.set_secdesc.in.file.fnum = fnum; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; -- cgit From dd894d56267009f76977502d49a82ca34bdd8a41 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 18 Apr 2006 08:07:35 +0000 Subject: r15117: add more comments metze (This used to be commit d76f3e2fb61317633876afc90c1cea1130e58dea) --- source4/ntvfs/posix/pvfs_open.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 488f2d9568..9570fa08d9 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -143,7 +143,13 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, /* setup an initial sec_desc if requested */ if (io->ntcreatex.in.sec_desc) { union smb_setfileinfo set; -/* TODO: set the full ACL! */ +/* + * TODO: set the full ACL! + * - vista denies the creation of the file with NT_STATUS_PRIVILEGE_NOT_HELD, + * when a SACL is present on the sd, + * but the user doesn't have SeSecurityPrivilege + * - w2k3 allows it + */ set.set_secdesc.in.file.fnum = fnum; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; -- cgit From 44ba1055031404c2e11247b4b70c8306ffecd094 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 18 Apr 2006 08:33:48 +0000 Subject: r15118: - do access checks also when the owner and group are not changed - only call chown/fchown when we want to change something metze (This used to be commit 46b3096d938331a2339a876649bc6cbfec883cb2) --- source4/ntvfs/posix/pvfs_acl.c | 47 +++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index c2afdbec24..3826b2f157 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -194,8 +194,10 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags; struct security_descriptor *new_sd, *sd, orig_sd; NTSTATUS status; - uid_t uid = -1; - gid_t gid = -1; + uid_t old_uid = -1; + gid_t old_gid = -1; + uid_t new_uid = -1; + gid_t new_gid = -1; acl = talloc(req, struct xattr_NTACL); if (acl == NULL) { @@ -221,31 +223,29 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, new_sd = info->set_secdesc.in.sd; orig_sd = *sd; - uid = name->st.st_uid; - gid = name->st.st_gid; + old_uid = name->st.st_uid; + old_gid = name->st.st_gid; /* only set the elements that have been specified */ - if ((secinfo_flags & SECINFO_OWNER) && - !dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) { + if (secinfo_flags & SECINFO_OWNER) { if (!(access_mask & SEC_STD_WRITE_OWNER)) { return NT_STATUS_ACCESS_DENIED; } - sd->owner_sid = new_sd->owner_sid; - status = sidmap_sid_to_unixuid(pvfs->sidmap, sd->owner_sid, &uid); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) { + status = sidmap_sid_to_unixuid(pvfs->sidmap, new_sd->owner_sid, &new_uid); + NT_STATUS_NOT_OK_RETURN(status); } + sd->owner_sid = new_sd->owner_sid; } - if ((secinfo_flags & SECINFO_GROUP) && - !dom_sid_equal(sd->group_sid, new_sd->group_sid)) { + if (secinfo_flags & SECINFO_GROUP) { if (!(access_mask & SEC_STD_WRITE_OWNER)) { return NT_STATUS_ACCESS_DENIED; } - sd->group_sid = new_sd->group_sid; - status = sidmap_sid_to_unixgid(pvfs->sidmap, sd->group_sid, &gid); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) { + status = sidmap_sid_to_unixgid(pvfs->sidmap, new_sd->group_sid, &new_gid); + NT_STATUS_NOT_OK_RETURN(status); } + sd->group_sid = new_sd->group_sid; } if (secinfo_flags & SECINFO_DACL) { if (!(access_mask & SEC_STD_WRITE_DAC)) { @@ -262,12 +262,21 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, pvfs_translate_generic_bits(sd->sacl); } - if (uid != -1 || gid != -1) { + if (new_uid == old_uid) { + new_uid = -1; + } + + if (new_gid == old_gid) { + new_gid = -1; + } + + /* if there's something to change try it */ + if (new_uid != -1 || new_gid != -1) { int ret; if (fd == -1) { - ret = chown(name->full_name, uid, gid); + ret = chown(name->full_name, new_uid, new_gid); } else { - ret = fchown(fd, uid, gid); + ret = fchown(fd, new_uid, new_gid); } if (ret == -1) { return pvfs_map_errno(pvfs, errno); -- cgit From 073587abac756383a02f07f43f6be2787abf21a5 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 23 Apr 2006 23:40:53 +0000 Subject: r15183: Hoist the critical sizes initialiser into a header so that modules can have standard access to critical sizes. Add a convenience function to determine whether two critical sizes differ. (This used to be commit 7ced96d2d348701734cc4cdf3f8899dbce8cd0f7) --- source4/ntvfs/ntvfs.h | 11 +++++++++++ source4/ntvfs/ntvfs_base.c | 46 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index ec1f741fa8..3d12c5efc9 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -266,6 +266,17 @@ struct ntvfs_critical_sizes { int sizeof_ntvfs_request; }; +#define NTVFS_CURRENT_CRITICAL_SIZES(c) \ + struct ntvfs_critical_sizes c = { \ + .interface_version = NTVFS_INTERFACE_VERSION, \ + .sizeof_ntvfs_critical_sizes = sizeof(struct ntvfs_critical_sizes), \ + .sizeof_ntvfs_context = sizeof(struct ntvfs_context), \ + .sizeof_ntvfs_module_context = sizeof(struct ntvfs_module_context), \ + .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), \ + .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), \ + .sizeof_ntvfs_request = sizeof(struct ntvfs_request), \ + } + struct messaging_context; #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/notify.h" diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index b1efb44ec7..1705bbef2f 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -98,21 +98,49 @@ _PUBLIC_ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntv This can be used by backends to either detect compilation errors, or provide multiple implementations for different smbd compilation options in one module */ -static const struct ntvfs_critical_sizes critical_sizes = { - .interface_version = NTVFS_INTERFACE_VERSION, - .sizeof_ntvfs_critical_sizes = sizeof(struct ntvfs_critical_sizes), - .sizeof_ntvfs_context = sizeof(struct ntvfs_context), - .sizeof_ntvfs_module_context = sizeof(struct ntvfs_module_context), - .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), - .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), - .sizeof_ntvfs_request = sizeof(struct ntvfs_request), -}; + +static const NTVFS_CURRENT_CRITICAL_SIZES(critical_sizes); _PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { return &critical_sizes; } +_PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) +{ + /* The comparison would be easier with memcmp, but compiler-interset + * alignment padding is not guaranteed to be zeroed. + */ + +#define FIELD_DIFFERS(field) (iface->field != critical_sizes.field) + + if (FIELD_DIFFERS(interface_version)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_critical_sizes)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_context)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_module_context)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_ops)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_async_state)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_request)) + return True; + + /* Versions match. */ + return False; + +#undef FIELD_DIFFERS +} + /* initialise a connection structure to point at a NTVFS backend -- cgit From 419e6d1112c4bcb8b09b5f4f7b4da1007a235ca9 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 23 Apr 2006 23:42:23 +0000 Subject: r15184: Declare ntvfs_register with a typed ops pointer. (This used to be commit bf946e6d6d3de1384588a687e15e030f3b1806f0) --- source4/ntvfs/ntvfs_base.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 1705bbef2f..72b3eaaed8 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -44,9 +44,8 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -_PUBLIC_ NTSTATUS ntvfs_register(const void *_ops) +_PUBLIC_ NTSTATUS ntvfs_register(const struct ntvfs_ops *ops) { - const struct ntvfs_ops *ops = _ops; struct ntvfs_ops *new_ops; if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { -- cgit From f380d365eaad89db2c46331a3fa2d5d8600aeba1 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 23 Apr 2006 23:44:14 +0000 Subject: r15185: Force all NTVFS modules to provide a critical sizes structure so the version information can be checked when modules are registered. (This used to be commit 95eb55806339fc5409c0adf137ebd5bffd7098ac) --- source4/ntvfs/cifs/vfs_cifs.c | 3 ++- source4/ntvfs/ipc/vfs_ipc.c | 3 ++- source4/ntvfs/nbench/vfs_nbench.c | 3 ++- source4/ntvfs/ntvfs_base.c | 12 ++++++++++-- source4/ntvfs/posix/vfs_posix.c | 5 +++-- source4/ntvfs/print/vfs_print.c | 3 ++- source4/ntvfs/simple/vfs_simple.c | 3 ++- source4/ntvfs/unixuid/vfs_unixuid.c | 7 ++++--- 8 files changed, 27 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 25fe4cb2a4..586e0ebb98 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -939,6 +939,7 @@ NTSTATUS ntvfs_cifs_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -985,7 +986,7 @@ NTSTATUS ntvfs_cifs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register CIFS backend!\n")); diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b6b931eccd..6ef380c4eb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -777,6 +777,7 @@ NTSTATUS ntvfs_ipc_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -817,7 +818,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.cancel = ipc_cancel; /* register ourselves with the NTVFS subsystem. */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register IPC backend!\n")); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index b93e5f3c44..a8ec141760 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -884,6 +884,7 @@ NTSTATUS ntvfs_nbench_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -928,7 +929,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.trans2 = NULL; /* register ourselves with the NTVFS subsystem. */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register nbench backend!\n")); diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 72b3eaaed8..316a9e9c68 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -44,10 +44,18 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -_PUBLIC_ NTSTATUS ntvfs_register(const struct ntvfs_ops *ops) +_PUBLIC_ NTSTATUS ntvfs_register(const struct ntvfs_ops *ops, + const struct ntvfs_critical_sizes *const sizes) { struct ntvfs_ops *new_ops; - + + if (ntvfs_interface_differs(sizes)) { + DEBUG(0, ("NTVFS backend '%s' for type %d " + "failed version check\n", + ops->name, (int)ops->type)); + return NT_STATUS_BAD_FUNCTION_TABLE; + } + if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { /* its already registered! */ DEBUG(0,("NTVFS backend '%s' for type %d already registered\n", diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index eddc49c919..2d40ceb85d 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -286,6 +286,7 @@ NTSTATUS ntvfs_posix_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -328,14 +329,14 @@ NTSTATUS ntvfs_posix_init(void) under the name 'default' as we wish to be the default backend, and also register as 'posix' */ ops.name = "default"; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); } ops.name = "posix"; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 1aa38a59c2..31cfcc9303 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -100,6 +100,7 @@ NTSTATUS ntvfs_print_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -115,7 +116,7 @@ NTSTATUS ntvfs_print_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register PRINT backend!\n")); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 2347f31bde..35c18e3f1c 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -969,6 +969,7 @@ NTSTATUS ntvfs_simple_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -1010,7 +1011,7 @@ NTSTATUS ntvfs_simple_init(void) ops.type = NTVFS_DISK; ops.name = "simple"; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register simple backend with name: %s!\n", diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 061b8fbe55..9afb2b1380 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -639,6 +639,7 @@ NTSTATUS ntvfs_unixuid_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -679,15 +680,15 @@ NTSTATUS ntvfs_unixuid_init(void) /* we register under all 3 backend types, as we are not type specific */ ops.type = NTVFS_DISK; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_PRINT; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_IPC; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) goto failed; failed: -- cgit From 6ab33938d5239e8688440f65e802f627622d301b Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 24 Apr 2006 00:16:51 +0000 Subject: r15186: Introduce ISDOT and ISDOTDOT macros for testing whether a filename is "." for "..". These express the intention better that strcmp or strequal and improve searchability via cscope/ctags. (This used to be commit 7e4ad7e8e5ec266b969e3075c4ad7f021571f24e) --- source4/ntvfs/cifs/vfs_cifs.c | 3 +- source4/ntvfs/ipc/vfs_ipc.c | 3 +- source4/ntvfs/nbench/vfs_nbench.c | 3 +- source4/ntvfs/ntvfs.h | 11 ------- source4/ntvfs/ntvfs_base.c | 59 ++++++++----------------------------- source4/ntvfs/posix/pvfs_dirlist.c | 10 +++---- source4/ntvfs/posix/pvfs_resolve.c | 4 +-- source4/ntvfs/posix/pvfs_unlink.c | 4 +-- source4/ntvfs/posix/vfs_posix.c | 5 ++-- source4/ntvfs/print/vfs_print.c | 3 +- source4/ntvfs/simple/vfs_simple.c | 3 +- source4/ntvfs/unixuid/vfs_unixuid.c | 7 ++--- 12 files changed, 30 insertions(+), 85 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 586e0ebb98..25fe4cb2a4 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -939,7 +939,6 @@ NTSTATUS ntvfs_cifs_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -986,7 +985,7 @@ NTSTATUS ntvfs_cifs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register CIFS backend!\n")); diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 6ef380c4eb..b6b931eccd 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -777,7 +777,6 @@ NTSTATUS ntvfs_ipc_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -818,7 +817,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.cancel = ipc_cancel; /* register ourselves with the NTVFS subsystem. */ - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register IPC backend!\n")); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index a8ec141760..b93e5f3c44 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -884,7 +884,6 @@ NTSTATUS ntvfs_nbench_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -929,7 +928,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.trans2 = NULL; /* register ourselves with the NTVFS subsystem. */ - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register nbench backend!\n")); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 3d12c5efc9..ec1f741fa8 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -266,17 +266,6 @@ struct ntvfs_critical_sizes { int sizeof_ntvfs_request; }; -#define NTVFS_CURRENT_CRITICAL_SIZES(c) \ - struct ntvfs_critical_sizes c = { \ - .interface_version = NTVFS_INTERFACE_VERSION, \ - .sizeof_ntvfs_critical_sizes = sizeof(struct ntvfs_critical_sizes), \ - .sizeof_ntvfs_context = sizeof(struct ntvfs_context), \ - .sizeof_ntvfs_module_context = sizeof(struct ntvfs_module_context), \ - .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), \ - .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), \ - .sizeof_ntvfs_request = sizeof(struct ntvfs_request), \ - } - struct messaging_context; #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/notify.h" diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 316a9e9c68..b1efb44ec7 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -44,18 +44,11 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -_PUBLIC_ NTSTATUS ntvfs_register(const struct ntvfs_ops *ops, - const struct ntvfs_critical_sizes *const sizes) +_PUBLIC_ NTSTATUS ntvfs_register(const void *_ops) { + const struct ntvfs_ops *ops = _ops; struct ntvfs_ops *new_ops; - - if (ntvfs_interface_differs(sizes)) { - DEBUG(0, ("NTVFS backend '%s' for type %d " - "failed version check\n", - ops->name, (int)ops->type)); - return NT_STATUS_BAD_FUNCTION_TABLE; - } - + if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { /* its already registered! */ DEBUG(0,("NTVFS backend '%s' for type %d already registered\n", @@ -105,49 +98,21 @@ _PUBLIC_ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntv This can be used by backends to either detect compilation errors, or provide multiple implementations for different smbd compilation options in one module */ - -static const NTVFS_CURRENT_CRITICAL_SIZES(critical_sizes); +static const struct ntvfs_critical_sizes critical_sizes = { + .interface_version = NTVFS_INTERFACE_VERSION, + .sizeof_ntvfs_critical_sizes = sizeof(struct ntvfs_critical_sizes), + .sizeof_ntvfs_context = sizeof(struct ntvfs_context), + .sizeof_ntvfs_module_context = sizeof(struct ntvfs_module_context), + .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), + .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), + .sizeof_ntvfs_request = sizeof(struct ntvfs_request), +}; _PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { return &critical_sizes; } -_PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) -{ - /* The comparison would be easier with memcmp, but compiler-interset - * alignment padding is not guaranteed to be zeroed. - */ - -#define FIELD_DIFFERS(field) (iface->field != critical_sizes.field) - - if (FIELD_DIFFERS(interface_version)) - return True; - - if (FIELD_DIFFERS(sizeof_ntvfs_critical_sizes)) - return True; - - if (FIELD_DIFFERS(sizeof_ntvfs_context)) - return True; - - if (FIELD_DIFFERS(sizeof_ntvfs_module_context)) - return True; - - if (FIELD_DIFFERS(sizeof_ntvfs_ops)) - return True; - - if (FIELD_DIFFERS(sizeof_ntvfs_async_state)) - return True; - - if (FIELD_DIFFERS(sizeof_ntvfs_request)) - return True; - - /* Versions match. */ - return False; - -#undef FIELD_DIFFERS -} - /* initialise a connection structure to point at a NTVFS backend diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index a61fc458b3..a3eaca3cbb 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -218,8 +218,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) while ((de = readdir(dir->dir))) { const char *dname = de->d_name; - if (strcmp(dname, ".") == 0 || - strcmp(dname, "..") == 0) { + if (ISDOT(dname) || ISDOT(dname)) { continue; } @@ -269,13 +268,13 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) struct dirent *de; int i; - if (strcmp(name, ".") == 0) { + if (ISDOT(name)) { dir->offset = DIR_OFFSET_DOTDOT; *ofs = dir->offset; return NT_STATUS_OK; } - if (strcmp(name, "..") == 0) { + if (ISDOTDOT(name)) { dir->offset = DIR_OFFSET_BASE; *ofs = dir->offset; return NT_STATUS_OK; @@ -324,8 +323,7 @@ BOOL pvfs_directory_empty(struct pvfs_state *pvfs, struct pvfs_filename *name) } while ((de = readdir(dir))) { - if (strcmp(de->d_name, ".") != 0 && - strcmp(de->d_name, "..") != 0) { + if (!ISDOT(de->d_name) && !ISDOTDOT(de->d_name)) { closedir(dir); return False; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index b8e55c85bf..70a1c0523a 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -372,7 +372,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t if (strcmp(components[i], "") == 0) { continue; } - if (strcmp(components[i], ".") == 0 || err_count) { + if (ISDOT(components[i]) || err_count) { err_count++; } } @@ -394,7 +394,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t i--; continue; } - if (strcmp(components[i], "..") == 0) { + if (ISDOTDOT(components[i])) { if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; memmove(&components[i-1], &components[i+1], sizeof(char *)*(num_components-(i+1))); diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 4477360deb..c40634035d 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "system/dir.h" /* @@ -164,8 +165,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, while ((fname = pvfs_list_next(dir, &ofs))) { /* this seems to be a special case */ if ((unl->unlink.in.attrib & FILE_ATTRIBUTE_DIRECTORY) && - (strcmp(fname, ".") == 0 || - strcmp(fname, "..") == 0)) { + (ISDOT(fname) || ISDOTDOT(fname))) { return NT_STATUS_OBJECT_NAME_INVALID; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 2d40ceb85d..eddc49c919 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -286,7 +286,6 @@ NTSTATUS ntvfs_posix_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -329,14 +328,14 @@ NTSTATUS ntvfs_posix_init(void) under the name 'default' as we wish to be the default backend, and also register as 'posix' */ ops.name = "default"; - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); } ops.name = "posix"; - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 31cfcc9303..1aa38a59c2 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -100,7 +100,6 @@ NTSTATUS ntvfs_print_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -116,7 +115,7 @@ NTSTATUS ntvfs_print_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register PRINT backend!\n")); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 35c18e3f1c..2347f31bde 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -969,7 +969,6 @@ NTSTATUS ntvfs_simple_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -1011,7 +1010,7 @@ NTSTATUS ntvfs_simple_init(void) ops.type = NTVFS_DISK; ops.name = "simple"; - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register simple backend with name: %s!\n", diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 9afb2b1380..061b8fbe55 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -639,7 +639,6 @@ NTSTATUS ntvfs_unixuid_init(void) { NTSTATUS ret; struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -680,15 +679,15 @@ NTSTATUS ntvfs_unixuid_init(void) /* we register under all 3 backend types, as we are not type specific */ ops.type = NTVFS_DISK; - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_PRINT; - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_IPC; - ret = ntvfs_register(&ops, &vers); + ret = ntvfs_register(&ops); if (!NT_STATUS_IS_OK(ret)) goto failed; failed: -- cgit From 7baa8a13aa751e2a1de287d43de0884ea638f04e Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 24 Apr 2006 01:26:31 +0000 Subject: r15188: Restore svn rev. 15183, 15184 and 15185, which I inadvertantly clobbered in r15186. I don't think I should be allowed to use quilt and svn at the same time any more :( (This used to be commit e0ca5ead27743c84f5d9310a05d6d718862ead1d) --- source4/ntvfs/cifs/vfs_cifs.c | 3 +- source4/ntvfs/ipc/vfs_ipc.c | 3 +- source4/ntvfs/nbench/vfs_nbench.c | 3 +- source4/ntvfs/ntvfs.h | 11 +++++++ source4/ntvfs/ntvfs_base.c | 59 +++++++++++++++++++++++++++++-------- source4/ntvfs/posix/vfs_posix.c | 5 ++-- source4/ntvfs/print/vfs_print.c | 3 +- source4/ntvfs/simple/vfs_simple.c | 3 +- source4/ntvfs/unixuid/vfs_unixuid.c | 7 +++-- 9 files changed, 75 insertions(+), 22 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 25fe4cb2a4..586e0ebb98 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -939,6 +939,7 @@ NTSTATUS ntvfs_cifs_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -985,7 +986,7 @@ NTSTATUS ntvfs_cifs_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register CIFS backend!\n")); diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b6b931eccd..6ef380c4eb 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -777,6 +777,7 @@ NTSTATUS ntvfs_ipc_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -817,7 +818,7 @@ NTSTATUS ntvfs_ipc_init(void) ops.cancel = ipc_cancel; /* register ourselves with the NTVFS subsystem. */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register IPC backend!\n")); diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index b93e5f3c44..a8ec141760 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -884,6 +884,7 @@ NTSTATUS ntvfs_nbench_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -928,7 +929,7 @@ NTSTATUS ntvfs_nbench_init(void) ops.trans2 = NULL; /* register ourselves with the NTVFS subsystem. */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register nbench backend!\n")); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index ec1f741fa8..3d12c5efc9 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -266,6 +266,17 @@ struct ntvfs_critical_sizes { int sizeof_ntvfs_request; }; +#define NTVFS_CURRENT_CRITICAL_SIZES(c) \ + struct ntvfs_critical_sizes c = { \ + .interface_version = NTVFS_INTERFACE_VERSION, \ + .sizeof_ntvfs_critical_sizes = sizeof(struct ntvfs_critical_sizes), \ + .sizeof_ntvfs_context = sizeof(struct ntvfs_context), \ + .sizeof_ntvfs_module_context = sizeof(struct ntvfs_module_context), \ + .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), \ + .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), \ + .sizeof_ntvfs_request = sizeof(struct ntvfs_request), \ + } + struct messaging_context; #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/notify.h" diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index b1efb44ec7..316a9e9c68 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -44,11 +44,18 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -_PUBLIC_ NTSTATUS ntvfs_register(const void *_ops) +_PUBLIC_ NTSTATUS ntvfs_register(const struct ntvfs_ops *ops, + const struct ntvfs_critical_sizes *const sizes) { - const struct ntvfs_ops *ops = _ops; struct ntvfs_ops *new_ops; - + + if (ntvfs_interface_differs(sizes)) { + DEBUG(0, ("NTVFS backend '%s' for type %d " + "failed version check\n", + ops->name, (int)ops->type)); + return NT_STATUS_BAD_FUNCTION_TABLE; + } + if (ntvfs_backend_byname(ops->name, ops->type) != NULL) { /* its already registered! */ DEBUG(0,("NTVFS backend '%s' for type %d already registered\n", @@ -98,21 +105,49 @@ _PUBLIC_ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntv This can be used by backends to either detect compilation errors, or provide multiple implementations for different smbd compilation options in one module */ -static const struct ntvfs_critical_sizes critical_sizes = { - .interface_version = NTVFS_INTERFACE_VERSION, - .sizeof_ntvfs_critical_sizes = sizeof(struct ntvfs_critical_sizes), - .sizeof_ntvfs_context = sizeof(struct ntvfs_context), - .sizeof_ntvfs_module_context = sizeof(struct ntvfs_module_context), - .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), - .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), - .sizeof_ntvfs_request = sizeof(struct ntvfs_request), -}; + +static const NTVFS_CURRENT_CRITICAL_SIZES(critical_sizes); _PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { return &critical_sizes; } +_PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) +{ + /* The comparison would be easier with memcmp, but compiler-interset + * alignment padding is not guaranteed to be zeroed. + */ + +#define FIELD_DIFFERS(field) (iface->field != critical_sizes.field) + + if (FIELD_DIFFERS(interface_version)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_critical_sizes)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_context)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_module_context)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_ops)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_async_state)) + return True; + + if (FIELD_DIFFERS(sizeof_ntvfs_request)) + return True; + + /* Versions match. */ + return False; + +#undef FIELD_DIFFERS +} + /* initialise a connection structure to point at a NTVFS backend diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index eddc49c919..2d40ceb85d 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -286,6 +286,7 @@ NTSTATUS ntvfs_posix_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -328,14 +329,14 @@ NTSTATUS ntvfs_posix_init(void) under the name 'default' as we wish to be the default backend, and also register as 'posix' */ ops.name = "default"; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); } ops.name = "posix"; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register POSIX backend as '%s'!\n", ops.name)); diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 1aa38a59c2..31cfcc9303 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -100,6 +100,7 @@ NTSTATUS ntvfs_print_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -115,7 +116,7 @@ NTSTATUS ntvfs_print_init(void) /* register ourselves with the NTVFS subsystem. We register under the name 'default' as we wish to be the default backend */ - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register PRINT backend!\n")); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 2347f31bde..35c18e3f1c 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -969,6 +969,7 @@ NTSTATUS ntvfs_simple_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -1010,7 +1011,7 @@ NTSTATUS ntvfs_simple_init(void) ops.type = NTVFS_DISK; ops.name = "simple"; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { DEBUG(0,("Failed to register simple backend with name: %s!\n", diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 061b8fbe55..9afb2b1380 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -639,6 +639,7 @@ NTSTATUS ntvfs_unixuid_init(void) { NTSTATUS ret; struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); ZERO_STRUCT(ops); @@ -679,15 +680,15 @@ NTSTATUS ntvfs_unixuid_init(void) /* we register under all 3 backend types, as we are not type specific */ ops.type = NTVFS_DISK; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_PRINT; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) goto failed; ops.type = NTVFS_IPC; - ret = ntvfs_register(&ops); + ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) goto failed; failed: -- cgit From cdae64b18c46926f32ecee71896e60b66228e8b0 Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 24 Apr 2006 02:36:55 +0000 Subject: r15189: Add parentheses to force ISDOt and ISDOTDOT evaluation order. Fix typo that made the BASE-DIR2 test fail. (This used to be commit dcebc59a987b3c0d8379912d0451dedb9e895451) --- source4/ntvfs/posix/pvfs_dirlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index a3eaca3cbb..517f5b68d0 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -218,7 +218,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) while ((de = readdir(dir->dir))) { const char *dname = de->d_name; - if (ISDOT(dname) || ISDOT(dname)) { + if (ISDOT(dname) || ISDOTDOT(dname)) { continue; } -- cgit From 69b51f702af1ded825d5c17bdb97014cac12e752 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Apr 2006 15:47:59 +0000 Subject: r15207: Introduce PRIVATE_DEPENDENCIES and PUBLIC_DEPENDENCIES as replacement for REQUIRED_SUBSYSTEMS. (This used to be commit adc8a019b6da256f104abed1b82bfde6998a2ac9) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/config.mk | 6 +++--- source4/ntvfs/posix/config.mk | 2 +- source4/ntvfs/sysdep/config.mk | 2 +- source4/ntvfs/unixuid/config.mk | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 5b2c8ddba7..feb3613f78 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,6 +7,6 @@ OBJ_FILES = \ brlock.o \ opendb.o \ notify.o -REQUIRED_SUBSYSTEMS = NDR_OPENDB NDR_NOTIFY sys_notify +PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify # End LIBRARY ntvfs_common ################################################ diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index d11e2c848d..e17f649abb 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -11,7 +11,7 @@ INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = ntvfs OBJ_FILES = \ cifs/vfs_cifs.o -REQUIRED_SUBSYSTEMS = \ +PUBLIC_DEPENDENCIES = \ LIBCLI # End MODULE ntvfs_cifs ################################################ @@ -48,7 +48,7 @@ OBJ_FILES = \ ipc/vfs_ipc.o \ ipc/ipc_rap.o \ ipc/rap_server.o -REQUIRED_SUBSYSTEMS = dcerpc_server +PUBLIC_DEPENDENCIES = dcerpc_server # End MODULE ntvfs_ipc ################################################ @@ -77,7 +77,7 @@ OBJ_FILES = \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o -REQUIRED_SUBSYSTEMS = +PUBLIC_DEPENDENCIES = # # End SUBSYSTEM NTVFS ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index b9724cb9f2..b3c6a54904 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -32,6 +32,6 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o -REQUIRED_SUBSYSTEMS = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID ntvfs_common +PUBLIC_DEPENDENCIES = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID ntvfs_common # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 91d739f7b7..dee198c9da 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -13,6 +13,6 @@ OBJ_FILES = \ [SUBSYSTEM::sys_notify] OBJ_FILES = \ sys_notify.o -REQUIRED_SUBSYSTEMS = +PUBLIC_DEPENDENCIES = # End SUBSYSTEM sys_notify ################################################ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index f8af68eb9b..a26f96ffad 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -5,6 +5,6 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs OBJ_FILES = \ vfs_unixuid.o -REQUIRED_SUBSYSTEMS = SAMDB +PUBLIC_DEPENDENCIES = SAMDB # End MODULE ntvfs_unixuid ################################################ -- cgit From 1e8e6aeb6fed306be4196daca19af284a7fef3cf Mon Sep 17 00:00:00 2001 From: Steve French Date: Tue, 25 Apr 2006 11:36:15 +0000 Subject: r15237: Add primitive Samba 4 backend for cifs posix clients (based on simple backend). (This used to be commit f054e1a9e6101f22559f5c4a546b537531b60f94) --- source4/ntvfs/cifs_posix_cli/README | 10 + source4/ntvfs/cifs_posix_cli/cvfs.h | 35 + source4/ntvfs/cifs_posix_cli/svfs_util.c | 185 ++++++ source4/ntvfs/cifs_posix_cli/vfs_simple.c | 1022 +++++++++++++++++++++++++++++ source4/ntvfs/config.mk | 14 +- 5 files changed, 1265 insertions(+), 1 deletion(-) create mode 100644 source4/ntvfs/cifs_posix_cli/README create mode 100644 source4/ntvfs/cifs_posix_cli/cvfs.h create mode 100644 source4/ntvfs/cifs_posix_cli/svfs_util.c create mode 100644 source4/ntvfs/cifs_posix_cli/vfs_simple.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs_posix_cli/README b/source4/ntvfs/cifs_posix_cli/README new file mode 100644 index 0000000000..f1de5d9f80 --- /dev/null +++ b/source4/ntvfs/cifs_posix_cli/README @@ -0,0 +1,10 @@ +This module (ntvfs 'simple') provides a very, very simple posix backend. + +WARNING: All file access is done as user 'root'!!! + Only use this module for testing, with only test data!!! + +For activating this module use: + +[testshare] + path = /tmp/testshare + nfvfs handler = simple diff --git a/source4/ntvfs/cifs_posix_cli/cvfs.h b/source4/ntvfs/cifs_posix_cli/cvfs.h new file mode 100644 index 0000000000..8e462d99f4 --- /dev/null +++ b/source4/ntvfs/cifs_posix_cli/cvfs.h @@ -0,0 +1,35 @@ + +struct svfs_private { + /* the base directory */ + char *connectpath; + + /* a linked list of open searches */ + struct search_state *search; + + /* next available search handle */ + uint16_t next_search_handle; + + struct svfs_file *open_files; +}; + +struct svfs_dir { + uint_t count; + char *unix_dir; + struct svfs_dirfile { + char *name; + struct stat st; + } *files; +}; + +struct svfs_file { + struct svfs_file *next, *prev; + int fd; + char *name; +}; + +struct search_state { + struct search_state *next, *prev; + uint16_t handle; + uint_t current_index; + struct svfs_dir *dir; +}; diff --git a/source4/ntvfs/cifs_posix_cli/svfs_util.c b/source4/ntvfs/cifs_posix_cli/svfs_util.c new file mode 100644 index 0000000000..b85c43b071 --- /dev/null +++ b/source4/ntvfs/cifs_posix_cli/svfs_util.c @@ -0,0 +1,185 @@ +/* + Unix SMB/CIFS implementation. + + simple NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + utility functions for simple backend +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "cvfs.h" +#include "system/time.h" +#include "system/dir.h" +#include "ntvfs/ntvfs.h" + +/* + convert a windows path to a unix path - don't do any manging or case sensitive handling +*/ +char *cvfs_unix_path(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const char *name) +{ + struct svfs_private *private = ntvfs->private_data; + char *ret; + + if (*name != '\\') { + ret = talloc_asprintf(req, "%s/%s", private->connectpath, name); + } else { + ret = talloc_asprintf(req, "%s%s", private->connectpath, name); + } + all_string_sub(ret, "\\", "/", 0); + + strlower(ret + strlen(private->connectpath)); + + return ret; +} + + +/* + read a directory and find all matching file names and stat info + returned names are separate unix and DOS names. The returned names + are relative to the directory +*/ +struct svfs_dir *cvfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, const char *unix_path) +{ + char *p, *mask; + struct svfs_dir *dir; + DIR *odir; + struct dirent *dent; + uint_t allocated = 0; + char *low_mask; + + dir = talloc(mem_ctx, struct svfs_dir); + if (!dir) { return NULL; } + + dir->count = 0; + dir->files = 0; + + /* find the base directory */ + p = strrchr(unix_path, '/'); + if (!p) { return NULL; } + + dir->unix_dir = talloc_strndup(mem_ctx, unix_path, PTR_DIFF(p, unix_path)); + if (!dir->unix_dir) { return NULL; } + + /* the wildcard pattern is the last part */ + mask = p+1; + + low_mask = talloc_strdup(mem_ctx, mask); + if (!low_mask) { return NULL; } + strlower(low_mask); + + odir = opendir(dir->unix_dir); + if (!odir) { return NULL; } + + while ((dent = readdir(odir))) { + uint_t i = dir->count; + char *full_name; + char *low_name; + + if (strchr(dent->d_name, ':') && !strchr(unix_path, ':')) { + /* don't show streams in dir listing */ + continue; + } + + low_name = talloc_strdup(mem_ctx, dent->d_name); + if (!low_name) { continue; } + strlower(low_name); + + /* check it matches the wildcard pattern */ + if (ms_fnmatch(low_mask, low_name, PROTOCOL_NT1) != 0) { + continue; + } + + if (dir->count >= allocated) { + allocated = (allocated + 100) * 1.2; + dir->files = talloc_realloc(dir, dir->files, struct svfs_dirfile, allocated); + if (!dir->files) { + closedir(odir); + return NULL; + } + } + + dir->files[i].name = low_name; + if (!dir->files[i].name) { continue; } + + asprintf(&full_name, "%s/%s", dir->unix_dir, dir->files[i].name); + if (!full_name) { continue; } + + if (stat(full_name, &dir->files[i].st) == 0) { + dir->count++; + } + + free(full_name); + } + + closedir(odir); + + return dir; +} + +/* + read a directory and find all matching file names and stat info + returned names are separate unix and DOS names. The returned names + are relative to the directory +*/ +struct svfs_dir *cvfs_list(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *pattern) +{ + struct svfs_private *private = ntvfs->private_data; + char *unix_path; + + unix_path = cvfs_unix_path(ntvfs, req, pattern); + if (!unix_path) { return NULL; } + + return cvfs_list_unix(private, req, unix_path); +} + + +/******************************************************************* +set the time on a file via file descriptor +*******************************************************************/ +int cvfs_file_utime(int fd, struct utimbuf *times) +{ + char *fd_path = NULL; + int ret; + + asprintf(&fd_path, "/proc/self/%d", fd); + if (!fd_path) { + errno = ENOMEM; + return -1; + } + + ret = utime(fd_path, times); + free(fd_path); + return ret; +} + + +/* + map a unix file attrib to a DOS attribute +*/ +uint16_t cvfs_unix_to_dos_attrib(mode_t mode) +{ + uint16_t ret = 0; + if (S_ISDIR(mode)) ret |= FILE_ATTRIBUTE_DIRECTORY; + if (!(mode & S_IWUSR)) ret |= FILE_ATTRIBUTE_READONLY; + return ret; +} + diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c new file mode 100644 index 0000000000..cdecf5f8c6 --- /dev/null +++ b/source4/ntvfs/cifs_posix_cli/vfs_simple.c @@ -0,0 +1,1022 @@ +/* + Unix SMB/CIFS implementation. + + simple NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + this implements a very simple NTVFS filesystem backend. + + this backend largely ignores the POSIX -> CIFS mappings, just doing absolutely + minimal work to give a working backend. +*/ + +#include "includes.h" +#include "system/dir.h" +#include "system/filesys.h" +#include "cvfs.h" +#include "system/time.h" +#include "dlinklist.h" +#include "ntvfs/ntvfs.h" +#include "ntvfs/cifs_posix_cli/proto.h" + +#ifndef O_DIRECTORY +#define O_DIRECTORY 0 +#endif + +#define CHECK_READ_ONLY(req) do { if (lp_readonly(ntvfs->ctx->config.snum)) return NT_STATUS_ACCESS_DENIED; } while (0) + +/* + connect to a share - used when a tree_connect operation comes + in. For a disk based backend we needs to ensure that the base + directory exists (tho it doesn't need to be accessible by the user, + that comes later) +*/ +static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const char *sharename) +{ + struct stat st; + struct svfs_private *private; + int snum = ntvfs->ctx->config.snum; + + private = talloc(ntvfs, struct svfs_private); + + private->next_search_handle = 0; + private->connectpath = talloc_strdup(private, lp_pathname(snum)); + private->open_files = NULL; + private->search = NULL; + + /* the directory must exist */ + if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { + DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", + private->connectpath, sharename)); + return NT_STATUS_BAD_NETWORK_NAME; + } + + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + + ntvfs->private_data = private; + + DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs) +{ + return NT_STATUS_OK; +} + +/* + find open file handle given fd +*/ +static struct svfs_file *find_fd(struct svfs_private *private, int fd) +{ + struct svfs_file *f; + for (f=private->open_files;f;f=f->next) { + if (f->fd == fd) { + return f; + } + } + return NULL; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_unlink *unl) +{ + char *unix_path; + + CHECK_READ_ONLY(req); + + unix_path = cvfs_unix_path(ntvfs, req, unl->unlink.in.pattern); + + /* ignoring wildcards ... */ + if (unlink(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + + +/* + ioctl interface - we don't do any +*/ +static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_ioctl *io) +{ + return NT_STATUS_INVALID_PARAMETER; +} + +/* + check if a directory exists +*/ +static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_chkpath *cp) +{ + char *unix_path; + struct stat st; + + unix_path = cvfs_unix_path(ntvfs, req, cp->chkpath.in.path); + + if (stat(unix_path, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + if (!S_ISDIR(st.st_mode)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + return NT_STATUS_OK; +} + +/* + build a file_id from a stat struct +*/ +static uint64_t svfs_file_id(struct stat *st) +{ + uint64_t ret = st->st_ino; + ret <<= 32; + ret |= st->st_dev; + return ret; +} + +/* + approximately map a struct stat to a generic fileinfo struct +*/ +static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info, + struct stat *st, const char *unix_path) +{ + struct svfs_dir *dir = NULL; + char *pattern = NULL; + int i; + const char *s, *short_name; + + s = strrchr(unix_path, '/'); + if (s) { + short_name = s+1; + } else { + short_name = ""; + } + + asprintf(&pattern, "%s:*", unix_path); + + if (pattern) { + dir = cvfs_list_unix(req, req, pattern); + } + + unix_to_nt_time(&info->generic.out.create_time, st->st_ctime); + unix_to_nt_time(&info->generic.out.access_time, st->st_atime); + unix_to_nt_time(&info->generic.out.write_time, st->st_mtime); + unix_to_nt_time(&info->generic.out.change_time, st->st_mtime); + info->generic.out.alloc_size = st->st_size; + info->generic.out.size = st->st_size; + info->generic.out.attrib = cvfs_unix_to_dos_attrib(st->st_mode); + info->generic.out.alloc_size = st->st_blksize * st->st_blocks; + info->generic.out.nlink = st->st_nlink; + info->generic.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; + info->generic.out.file_id = svfs_file_id(st); + /* REWRITE: TODO stuff in here */ + info->generic.out.delete_pending = 0; + info->generic.out.ea_size = 0; + info->generic.out.num_eas = 0; + info->generic.out.fname.s = talloc_strdup(req, short_name); + info->generic.out.alt_fname.s = talloc_strdup(req, short_name); + info->generic.out.compressed_size = 0; + info->generic.out.format = 0; + info->generic.out.unit_shift = 0; + info->generic.out.chunk_shift = 0; + info->generic.out.cluster_shift = 0; + + info->generic.out.access_flags = 0; + info->generic.out.position = 0; + info->generic.out.mode = 0; + info->generic.out.alignment_requirement = 0; + info->generic.out.reparse_tag = 0; + info->generic.out.num_streams = 0; + /* setup a single data stream */ + info->generic.out.num_streams = 1 + (dir?dir->count:0); + info->generic.out.streams = talloc_array(req, + struct stream_struct, + info->generic.out.num_streams); + if (!info->generic.out.streams) { + return NT_STATUS_NO_MEMORY; + } + info->generic.out.streams[0].size = st->st_size; + info->generic.out.streams[0].alloc_size = st->st_size; + info->generic.out.streams[0].stream_name.s = talloc_strdup(req,"::$DATA"); + + for (i=0;dir && icount;i++) { + s = strchr(dir->files[i].name, ':'); + info->generic.out.streams[1+i].size = dir->files[i].st.st_size; + info->generic.out.streams[1+i].alloc_size = dir->files[i].st.st_size; + info->generic.out.streams[1+i].stream_name.s = s?s:dir->files[i].name; + } + + return NT_STATUS_OK; +} + +/* + return info on a pathname +*/ +static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + char *unix_path; + struct stat st; + + DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.file.path, info->generic.level)); + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qpathinfo(ntvfs, req, info); + } + + unix_path = cvfs_unix_path(ntvfs, req, info->generic.in.file.path); + DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); + if (stat(unix_path, &st) == -1) { + DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); + return svfs_map_fileinfo(ntvfs, req, info, &st, unix_path); +} + +/* + query info on a open file +*/ +static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; + struct stat st; + + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qfileinfo(ntvfs, req, info); + } + + f = find_fd(private, info->generic.in.file.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + if (fstat(info->generic.in.file.fnum, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + return svfs_map_fileinfo(ntvfs, req,info, &st, f->name); +} + + +/* + open a file +*/ +static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io) +{ + struct svfs_private *private = ntvfs->private_data; + char *unix_path; + struct stat st; + int fd, flags; + struct svfs_file *f; + int create_flags, rdwr_flags; + BOOL readonly; + + if (io->generic.level != RAW_OPEN_GENERIC) { + return ntvfs_map_open(ntvfs, req, io); + } + + readonly = lp_readonly(ntvfs->ctx->config.snum); + if (readonly) { + create_flags = 0; + rdwr_flags = O_RDONLY; + } else { + create_flags = O_CREAT; + rdwr_flags = O_RDWR; + } + + unix_path = cvfs_unix_path(ntvfs, req, io->ntcreatex.in.fname); + + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_SUPERSEDE: + case NTCREATEX_DISP_OVERWRITE_IF: + flags = create_flags | O_TRUNC; + break; + case NTCREATEX_DISP_OPEN: + case NTCREATEX_DISP_OVERWRITE: + flags = 0; + break; + case NTCREATEX_DISP_CREATE: + flags = create_flags | O_EXCL; + break; + case NTCREATEX_DISP_OPEN_IF: + flags = create_flags; + break; + default: + flags = 0; + break; + } + + flags |= rdwr_flags; + + if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { + flags = O_RDONLY | O_DIRECTORY; + if (readonly) { + goto do_open; + } + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_CREATE: + if (mkdir(unix_path, 0755) == -1) { + DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + break; + case NTCREATEX_DISP_OPEN_IF: + if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { + DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + break; + } + } + +do_open: + fd = open(unix_path, flags, 0644); + if (fd == -1) { + return map_nt_error_from_unix(errno); + } + + if (fstat(fd, &st) == -1) { + DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); + close(fd); + return map_nt_error_from_unix(errno); + } + + f = talloc(ntvfs, struct svfs_file); + NT_STATUS_HAVE_NO_MEMORY(f); + f->fd = fd; + f->name = talloc_strdup(f, unix_path); + NT_STATUS_HAVE_NO_MEMORY(f->name); + + DLIST_ADD(private->open_files, f); + + ZERO_STRUCT(io->generic.out); + + unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); + unix_to_nt_time(&io->generic.out.access_time, st.st_atime); + unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); + unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); + io->generic.out.file.fnum = fd; + io->generic.out.alloc_size = st.st_size; + io->generic.out.size = st.st_size; + io->generic.out.attrib = cvfs_unix_to_dos_attrib(st.st_mode); + io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; + + return NT_STATUS_OK; +} + +/* + create a directory +*/ +static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_mkdir *md) +{ + char *unix_path; + + CHECK_READ_ONLY(req); + + if (md->generic.level != RAW_MKDIR_MKDIR) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path = cvfs_unix_path(ntvfs, req, md->mkdir.in.path); + + if (mkdir(unix_path, 0777) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + remove a directory +*/ +static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_rmdir *rd) +{ + char *unix_path; + + CHECK_READ_ONLY(req); + + unix_path = cvfs_unix_path(ntvfs, req, rd->in.path); + + if (rmdir(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + rename a set of files +*/ +static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_rename *ren) +{ + char *unix_path1, *unix_path2; + + CHECK_READ_ONLY(req); + + if (ren->generic.level != RAW_RENAME_RENAME) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path1 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern1); + unix_path2 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern2); + + if (rename(unix_path1, unix_path2) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + copy a set of files +*/ +static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + read from a file +*/ +static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_read *rd) +{ + ssize_t ret; + + if (rd->generic.level != RAW_READ_READX) { + return NT_STATUS_NOT_SUPPORTED; + } + + ret = pread(rd->readx.in.file.fnum, + rd->readx.out.data, + rd->readx.in.maxcnt, + rd->readx.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + rd->readx.out.nread = ret; + rd->readx.out.remaining = 0; /* should fill this in? */ + rd->readx.out.compaction_mode = 0; + + return NT_STATUS_OK; +} + +/* + write to a file +*/ +static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_write *wr) +{ + ssize_t ret; + + if (wr->generic.level != RAW_WRITE_WRITEX) { + return ntvfs_map_write(ntvfs, req, wr); + } + + CHECK_READ_ONLY(req); + + ret = pwrite(wr->writex.in.file.fnum, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; +} + +/* + seek in a file +*/ +static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_seek *io) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + flush a file +*/ +static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_flush *io) +{ + fsync(io->flush.in.file.fnum); + return NT_STATUS_OK; +} + +/* + close a file +*/ +static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_close *io) +{ + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; + + if (io->generic.level != RAW_CLOSE_CLOSE) { + /* we need a mapping function */ + return NT_STATUS_INVALID_LEVEL; + } + + f = find_fd(private, io->close.in.file.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + if (close(io->close.in.file.fnum) == -1) { + return map_nt_error_from_unix(errno); + } + + DLIST_REMOVE(private->open_files, f); + talloc_free(f->name); + talloc_free(f); + + return NT_STATUS_OK; +} + +/* + exit - closing files +*/ +static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + logoff - closing files +*/ +static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + setup for an async call +*/ +static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* + cancel an async call +*/ +static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +/* + lock a byte range +*/ +static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lock *lck) +{ + DEBUG(0,("REWRITE: not doing byte range locking!\n")); + return NT_STATUS_OK; +} + +/* + set info on a pathname +*/ +static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_setfileinfo *st) +{ + CHECK_READ_ONLY(req); + + return NT_STATUS_NOT_SUPPORTED; +} + +/* + set info on a open file +*/ +static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *info) +{ + struct utimbuf unix_times; + int fd; + + CHECK_READ_ONLY(req); + + switch (info->generic.level) { + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + if (ftruncate(info->end_of_file_info.in.file.fnum, + info->end_of_file_info.in.size) == -1) { + return map_nt_error_from_unix(errno); + } + break; + case RAW_SFILEINFO_SETATTRE: + unix_times.actime = info->setattre.in.access_time; + unix_times.modtime = info->setattre.in.write_time; + fd = info->setattre.in.file.fnum; + + if (unix_times.actime == 0 && unix_times.modtime == 0) { + break; + } + + /* set modify time = to access time if modify time was 0 */ + if (unix_times.actime != 0 && unix_times.modtime == 0) { + unix_times.modtime = unix_times.actime; + } + + /* Set the date on this file */ + if (cvfs_file_utime(fd, &unix_times) != 0) { + return NT_STATUS_ACCESS_DENIED; + } + break; + default: + DEBUG(2,("svfs_setfileinfo: level %d not implemented\n", + info->generic.level)); + return NT_STATUS_NOT_IMPLEMENTED; + } + return NT_STATUS_OK; +} + + +/* + return filesystem space info +*/ +static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fsinfo *fs) +{ + struct svfs_private *private = ntvfs->private_data; + struct stat st; + + if (fs->generic.level != RAW_QFS_GENERIC) { + return ntvfs_map_fsinfo(ntvfs, req, fs); + } + + if (sys_fsusage(private->connectpath, + &fs->generic.out.blocks_free, + &fs->generic.out.blocks_total) == -1) { + return map_nt_error_from_unix(errno); + } + + fs->generic.out.block_size = 512; + + if (stat(private->connectpath, &st) != 0) { + return NT_STATUS_DISK_CORRUPT_ERROR; + } + + fs->generic.out.fs_id = st.st_ino; + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.serial_number = st.st_ino; + fs->generic.out.fs_attr = 0; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.device_type = 0; + fs->generic.out.device_characteristics = 0; + fs->generic.out.quota_soft = 0; + fs->generic.out.quota_hard = 0; + fs->generic.out.quota_flags = 0; + fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(ntvfs->ctx->config.snum)); + fs->generic.out.fs_type = ntvfs->ctx->fs_type; + + return NT_STATUS_OK; +} + +#if 0 +/* + return filesystem attribute info +*/ +static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fsattr *fs) +{ + struct stat st; + struct svfs_private *private = ntvfs->private_data; + + if (fs->generic.level != RAW_FSATTR_GENERIC) { + return ntvfs_map_fsattr(ntvfs, req, fs); + } + + if (stat(private->connectpath, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.fs_attr = + FILE_CASE_PRESERVED_NAMES | + FILE_CASE_SENSITIVE_SEARCH | + FILE_PERSISTENT_ACLS; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.serial_number = 1; + fs->generic.out.fs_type = talloc_strdup(req, "NTFS"); + fs->generic.out.volume_name = talloc_strdup(req, + lp_servicename(req->tcon->service)); + + return NT_STATUS_OK; +} +#endif + +/* + return print queue info +*/ +static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = ntvfs->private_data; + struct search_state *search; + union smb_search_data file; + uint_t max_count; + + if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { + return NT_STATUS_NOT_SUPPORTED; + } + + search = talloc_zero(private, struct search_state); + if (!search) { + return NT_STATUS_NO_MEMORY; + } + + max_count = io->t2ffirst.in.max_count; + + dir = cvfs_list(ntvfs, req, io->t2ffirst.in.pattern); + if (!dir) { + return NT_STATUS_FOOBAR; + } + + search->handle = private->next_search_handle; + search->dir = dir; + + if (dir->count < max_count) { + max_count = dir->count; + } + + for (i=0; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); + file.both_directory_info.name.s = dir->files[i].name; + file.both_directory_info.short_name.s = dir->files[i].name; + file.both_directory_info.size = dir->files[i].st.st_size; + file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + + if (!callback(search_private, &file)) { + break; + } + } + + search->current_index = i; + + io->t2ffirst.out.count = i; + io->t2ffirst.out.handle = search->handle; + io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; + + /* work out if we are going to keep the search state */ + if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + talloc_free(search); + } else { + private->next_search_handle++; + DLIST_ADD(private->search, search); + } + + return NT_STATUS_OK; +} + +/* continue a search */ +static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = ntvfs->private_data; + struct search_state *search; + union smb_search_data file; + uint_t max_count; + + if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { + return NT_STATUS_NOT_SUPPORTED; + } + + for (search=private->search; search; search = search->next) { + if (search->handle == io->t2fnext.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + dir = search->dir; + + /* the client might be asking for something other than just continuing + with the search */ + if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && + (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && + io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { + /* look backwards first */ + for (i=search->current_index; i > 0; i--) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + + /* then look forwards */ + for (i=search->current_index+1; i <= dir->count; i++) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + } + +found: + max_count = search->current_index + io->t2fnext.in.max_count; + + if (max_count > dir->count) { + max_count = dir->count; + } + + for (i = search->current_index; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); + file.both_directory_info.name.s = dir->files[i].name; + file.both_directory_info.short_name.s = dir->files[i].name; + file.both_directory_info.size = dir->files[i].st.st_size; + file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + + if (!callback(search_private, &file)) { + break; + } + } + + io->t2fnext.out.count = i - search->current_index; + io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; + + search->current_index = i; + + /* work out if we are going to keep the search state */ + if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + DLIST_REMOVE(private->search, search); + talloc_free(search); + } + + return NT_STATUS_OK; +} + +/* close a search */ +static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_close *io) +{ + struct svfs_private *private = ntvfs->private_data; + struct search_state *search; + + for (search=private->search; search; search = search->next) { + if (search->handle == io->findclose.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + DLIST_REMOVE(private->search, search); + talloc_free(search); + + return NT_STATUS_OK; +} + +/* SMBtrans - not used on file shares */ +static NTSTATUS svfs_trans(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_trans2 *trans2) +{ + return NT_STATUS_ACCESS_DENIED; +} + + +/* + initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem + */ +NTSTATUS ntvfs_cifs_posix_init(void) +{ + NTSTATUS ret; + struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = svfs_connect; + ops.disconnect = svfs_disconnect; + ops.unlink = svfs_unlink; + ops.chkpath = svfs_chkpath; + ops.qpathinfo = svfs_qpathinfo; + ops.setpathinfo = svfs_setpathinfo; + ops.open = svfs_open; + ops.mkdir = svfs_mkdir; + ops.rmdir = svfs_rmdir; + ops.rename = svfs_rename; + ops.copy = svfs_copy; + ops.ioctl = svfs_ioctl; + ops.read = svfs_read; + ops.write = svfs_write; + ops.seek = svfs_seek; + ops.flush = svfs_flush; + ops.close = svfs_close; + ops.exit = svfs_exit; + ops.lock = svfs_lock; + ops.setfileinfo = svfs_setfileinfo; + ops.qfileinfo = svfs_qfileinfo; + ops.fsinfo = svfs_fsinfo; + ops.lpq = svfs_lpq; + ops.search_first = svfs_search_first; + ops.search_next = svfs_search_next; + ops.search_close = svfs_search_close; + ops.trans = svfs_trans; + ops.logoff = svfs_logoff; + ops.async_setup = svfs_async_setup; + ops.cancel = svfs_cancel; + + /* register ourselves with the NTVFS subsystem. We register + under names 'simple' + */ + + ops.type = NTVFS_DISK; + ops.name = "cifs-posix-cli"; + ret = ntvfs_register(&ops, &vers); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register simple backend with name: %s!\n", + ops.name)); + } + + return ret; +} diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index e17f649abb..ac96164347 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -25,7 +25,19 @@ PRIVATE_PROTO_HEADER = simple/proto.h OBJ_FILES = \ simple/vfs_simple.o \ simple/svfs_util.o -# End MODULE ntvfs_cifs +# End MODULE ntvfs_simple +################################################ + +################################################ +# Start MODULE ntvfs_cifs_posix_cli +[MODULE::ntvfs_cifs_posix] +INIT_FUNCTION = ntvfs_cifs_posix_init +SUBSYSTEM = ntvfs +PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h +OBJ_FILES = \ + cifs_posix_cli/vfs_simple.o \ + cifs_posix_cli/svfs_util.o +# End MODULE ntvfs_cifs_posix_cli ################################################ ################################################ -- cgit From f1c2b22d534fa628cce3ce8f248216770865abf8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Apr 2006 12:19:19 +0000 Subject: r15239: (hopefully) fix Samba4 build on AIX (This used to be commit 0291ae47579a0f2ae67b04b049edb51974e3c8f0) --- source4/ntvfs/nbench/vfs_nbench.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index a8ec141760..0a5dff9bd0 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -314,6 +314,7 @@ static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, { NTSTATUS status; +#undef open PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io)); return status; -- cgit From 25ac06eb46c70686c831884b6cf77b8689ae1a23 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Apr 2006 16:38:09 +0000 Subject: r15249: Fix typos (This used to be commit 06a735d85e8b325a9b605e23edfb2dcef511dbe3) --- source4/ntvfs/cifs_posix_cli/vfs_simple.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c index cdecf5f8c6..bbe52d9db1 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_simple.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_simple.c @@ -819,7 +819,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, file.both_directory_info.name.s = dir->files[i].name; file.both_directory_info.short_name.s = dir->files[i].name; file.both_directory_info.size = dir->files[i].st.st_size; - file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); if (!callback(search_private, &file)) { break; @@ -910,7 +910,7 @@ found: file.both_directory_info.name.s = dir->files[i].name; file.both_directory_info.short_name.s = dir->files[i].name; file.both_directory_info.size = dir->files[i].st.st_size; - file.both_directory_info.attrib = svfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); if (!callback(search_private, &file)) { break; -- cgit From 2319864a32f28748cce912845f8bcc17439abe30 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Apr 2006 00:10:57 +0000 Subject: r15261: Work around AIX defining open as open64 again (This used to be commit 05f5f3da8f08fb36f9709fa40b6b84ed1f948f3c) --- source4/ntvfs/nbench/vfs_nbench.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 0a5dff9bd0..77de979153 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -25,8 +25,8 @@ */ #include "includes.h" -#include "system/filesys.h" #include "ntvfs/ntvfs.h" +#include "system/filesys.h" /* this is stored in ntvfs_private */ struct nbench_private { @@ -314,7 +314,7 @@ static NTSTATUS nbench_open(struct ntvfs_module_context *ntvfs, { NTSTATUS status; -#undef open +#undef open /* AIX defines open to be open64 */ PASS_THRU_REQ(ntvfs, req, open, io, (ntvfs, req, io)); return status; -- cgit From 0d5587b5d128d9dd502a3b78c02fb986b33d92c4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 26 Apr 2006 12:22:54 +0000 Subject: r15274: Drop default EXT_LIB_ prefix for external libraries. Fixes issues with local (empty) libpopt.a overriding global one (This used to be commit 2f06305e53478e5030c24550954f221a9a97c83f) --- source4/ntvfs/posix/config.m4 | 4 ++-- source4/ntvfs/posix/config.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 37c2b57cf1..8d8b07810c 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -30,7 +30,7 @@ AC_CHECK_FUNC_EXT(flistxattr, $XATTR_LIBS) SMB_EXT_LIB(XATTR,[${XATTR_LIBS}],[${XATTR_CFLAGS}],[${XATTR_CPPFLAGS}],[${XATTR_LDFLAGS}]) if test x"$ac_cv_func_ext_flistxattr" = x"yes"; then AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) - SMB_EXT_LIB_ENABLE(XATTR,YES) + SMB_ENABLE(XATTR,YES) fi AC_CHECK_HEADERS(blkid/blkid.h) @@ -39,5 +39,5 @@ AC_CHECK_FUNC_EXT(blkid_get_cache, $BLKID_LIBS) SMB_EXT_LIB(BLKID,[${BLKID_LIBS}],[${BLKID_CFLAGS}],[${BLKID_CPPFLAGS}],[${BLKID_LDFLAGS}]) if test x"$ac_cv_func_ext_blkid_get_cache" = x"yes"; then AC_DEFINE(HAVE_LIBBLKID,1,[Whether we have blkid support (e2fsprogs)]) - SMB_EXT_LIB_ENABLE(BLKID,YES) + SMB_ENABLE(BLKID,YES) fi diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index b3c6a54904..32ede78cc9 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -32,6 +32,6 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o -PUBLIC_DEPENDENCIES = NDR_XATTR EXT_LIB_XATTR EXT_LIB_BLKID ntvfs_common +PUBLIC_DEPENDENCIES = NDR_XATTR XATTR BLKID ntvfs_common # End MODULE ntvfs_posix ################################################ -- cgit From e002300f238dd0937dd9f768e366c006945e8baa Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Apr 2006 17:34:49 +0000 Subject: r15328: Move some functions around, remove dependencies. Remove some autogenerated headers (which had prototypes now autogenerated by pidl) Remove ndr_security.h from a few places - it's no longer necessary (This used to be commit c19c2b51d3e1ad347120b06a22bda5ec586c22e8) --- source4/ntvfs/common/opendb.c | 1 - source4/ntvfs/ntvfs_generic.c | 1 - 2 files changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index fc981d5af6..395e6c6dbf 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -42,7 +42,6 @@ #include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messaging/messaging.h" -#include "librpc/gen_ndr/ndr_security.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index fdc186c710..b04a3af21e 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -32,7 +32,6 @@ */ #include "includes.h" -#include "librpc/gen_ndr/ndr_security.h" #include "ntvfs/ntvfs.h" /* a second stage function converts from the out parameters of the generic -- cgit From f7c86b912dd8033837a8411c7b99c9436de079c0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Apr 2006 23:22:54 +0000 Subject: r15331: Integrate LIBSMB and LIBCLI into new LIBCLI_SMB (This used to be commit 4ec89bce8715f35f21fe05bb738dae13fc6c3066) --- source4/ntvfs/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index ac96164347..a7194b049d 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -12,7 +12,7 @@ SUBSYSTEM = ntvfs OBJ_FILES = \ cifs/vfs_cifs.o PUBLIC_DEPENDENCIES = \ - LIBCLI + LIBCLI_SMB # End MODULE ntvfs_cifs ################################################ -- cgit From cf0f4ec073b694e43daeeddf9aab51cd3e51fd2b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 30 Apr 2006 13:54:03 +0000 Subject: r15358: Fix some compiler warnings / type safety. Found by tcc (This used to be commit 12ba42de5886f9f4f9b1698476557e0c217d06f3) --- source4/ntvfs/posix/pvfs_resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 70a1c0523a..3e5457f0cd 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -548,7 +548,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, struct pvfs_filename *name) { - dev_t device = 0; + dev_t device = (dev_t)0; ino_t inode = 0; if (name->exists) { -- cgit From 5c3a1d76ffc7b9e41846f7eaf6039f58184737a0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 18:11:15 +0000 Subject: r15379: Fix shared library build's unresolved dependencies (This used to be commit 0fafa2e59566f8f892d7dfd7dd33d0100b96a780) --- source4/ntvfs/config.mk | 4 ++-- source4/ntvfs/posix/config.mk | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index a7194b049d..c40e103082 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -12,7 +12,7 @@ SUBSYSTEM = ntvfs OBJ_FILES = \ cifs/vfs_cifs.o PUBLIC_DEPENDENCIES = \ - LIBCLI_SMB + LIBCLI_SMB LIBCLI_RAW # End MODULE ntvfs_cifs ################################################ @@ -60,7 +60,7 @@ OBJ_FILES = \ ipc/vfs_ipc.o \ ipc/ipc_rap.o \ ipc/rap_server.o -PUBLIC_DEPENDENCIES = dcerpc_server +PUBLIC_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 32ede78cc9..dde49a5531 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -32,6 +32,6 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o -PUBLIC_DEPENDENCIES = NDR_XATTR XATTR BLKID ntvfs_common +PUBLIC_DEPENDENCIES = NDR_XATTR XATTR BLKID ntvfs_common MESSAGING # End MODULE ntvfs_posix ################################################ -- cgit From 8bab9322825090952b25aa7e54c9bcd2f367de8d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 May 2006 23:03:32 +0000 Subject: r15387: Fix installation of dcerpc headers, remove more instances of uint_t (This used to be commit 9e9bfd04c6db013453b900e201df9c09e8777a22) --- source4/ntvfs/cifs_posix_cli/cvfs.h | 4 ++-- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/simple/svfs.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs_posix_cli/cvfs.h b/source4/ntvfs/cifs_posix_cli/cvfs.h index 8e462d99f4..74e7b6c452 100644 --- a/source4/ntvfs/cifs_posix_cli/cvfs.h +++ b/source4/ntvfs/cifs_posix_cli/cvfs.h @@ -13,7 +13,7 @@ struct svfs_private { }; struct svfs_dir { - uint_t count; + unsigned int count; char *unix_dir; struct svfs_dirfile { char *name; @@ -30,6 +30,6 @@ struct svfs_file { struct search_state { struct search_state *next, *prev; uint16_t handle; - uint_t current_index; + unsigned int current_index; struct svfs_dir *dir; }; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 3d12c5efc9..9069e6c2ac 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -223,7 +223,7 @@ struct ntvfs_context { struct ntvfs_async_state { struct ntvfs_async_state *prev, *next; /* the async handling infos */ - uint_t state; + unsigned int state; void *private_data; void (*send_fn)(struct ntvfs_request *); NTSTATUS status; diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index 8e462d99f4..74e7b6c452 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -13,7 +13,7 @@ struct svfs_private { }; struct svfs_dir { - uint_t count; + unsigned int count; char *unix_dir; struct svfs_dirfile { char *name; @@ -30,6 +30,6 @@ struct svfs_file { struct search_state { struct search_state *next, *prev; uint16_t handle; - uint_t current_index; + unsigned int current_index; struct svfs_dir *dir; }; -- cgit From 3590835ee606fe06c5ea5bf5ed7beba6dd087c60 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 9 May 2006 15:50:35 +0000 Subject: r15522: allow cifs:map_trans2 per share metze (This used to be commit da82e2bc45c23cc46f3013b38078229755b4ea61) --- source4/ntvfs/cifs/vfs_cifs.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 586e0ebb98..fd58d2c8bd 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -39,6 +39,7 @@ struct cvfs_private { struct ntvfs_module_context *ntvfs; struct async_info *pending; BOOL map_generic; + BOOL map_trans2; }; @@ -173,6 +174,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, private->map_generic = lp_parm_bool(ntvfs->ctx->config.snum, "cifs", "mapgeneric", False); + private->map_trans2 = lp_parm_bool(ntvfs->ctx->config.snum, + "cifs", "maptrans2", False); + return NT_STATUS_OK; } @@ -873,6 +877,10 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + if (!private->map_trans2) { + return NT_STATUS_NOT_IMPLEMENTED; + } + SETUP_PID; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -979,10 +987,7 @@ NTSTATUS ntvfs_cifs_init(void) ops.async_setup = cvfs_async_setup; ops.cancel = cvfs_cancel; ops.notify = cvfs_notify; - - if (lp_parm_bool(-1, "cifs", "maptrans2", False)) { - ops.trans2 = cvfs_trans2; - } + ops.trans2 = cvfs_trans2; /* register ourselves with the NTVFS subsystem. We register under the name 'cifs'. */ -- cgit From 53f005f6aaa2aa2eb599e6787e2c700a1d44d2a2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 13 May 2006 18:12:53 +0000 Subject: r15572: Trim build/m4/rewrite.m4 a bit more, remove unused tests. (This used to be commit d72c5c8f755277eb22e1f6834d98202f00c09934) --- source4/ntvfs/unixuid/config.m4 | 1 + 1 file changed, 1 insertion(+) create mode 100644 source4/ntvfs/unixuid/config.m4 (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/config.m4 b/source4/ntvfs/unixuid/config.m4 new file mode 100644 index 0000000000..cb870d9e16 --- /dev/null +++ b/source4/ntvfs/unixuid/config.m4 @@ -0,0 +1 @@ +AC_CHECK_FUNCS(setgroups) -- cgit From 172a83d72491f90f6191be1040ef8b2e1789bd2e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 13 May 2006 19:14:12 +0000 Subject: r15573: Fix build of systems that have iconv headers in non-standard locations Split of system/locale.h header from system/iconv.h Previously, iconv wasn't being used on these systems (This used to be commit aa6d66fda69779d1c2948a1aca85dbd5208f1cba) --- source4/ntvfs/posix/pvfs_shortname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index eb797dc7aa..8e26db3ed5 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -21,8 +21,8 @@ */ #include "includes.h" +#include "system/locale.h" #include "vfs_posix.h" -#include "system/iconv.h" /* this mangling scheme uses the following format -- cgit From 452ef0b40dc01a1a31c92b54ae771e06bb2d0de1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 14 May 2006 20:33:04 +0000 Subject: r15603: True isn't a valid parameter here, PVFS_WAIT_TIMEOUT is... (both are '1') metze (This used to be commit de9d04abcceae7b1e21f521d0bb2fa5129c237b2) --- source4/ntvfs/posix/pvfs_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 4dbb13cb42..0558fd52ea 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -258,7 +258,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request * /* an exact match! we can cancel it, which is equivalent to triggering the timeout early */ - pvfs_pending_lock_continue(p ,True); + pvfs_pending_lock_continue(p, PVFS_WAIT_TIMEOUT); return NT_STATUS_OK; } } -- cgit From 8dbffb37d53f1ef4f8b160c8452c13ac6a471e4d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 May 2006 10:45:38 +0000 Subject: r15612: look at the lock_type and not at the notify_ptr being NULL or not metze (This used to be commit 7fa6d736913af2d1d2215ca1a04ed8763ccb3d45) --- source4/ntvfs/common/brlock.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index bc9d8b1288..80c4350eac 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -411,7 +411,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, lock->fnum == fnum && lock->start == start && lock->size == size && - lock->notify_ptr == NULL) { + lock->lock_type < PENDING_READ_LOCK) { /* found it - delete it */ if (count == 1) { if (tdb_delete(brl->w->tdb, kbuf) != 0) { @@ -487,7 +487,8 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, for (i=0; inotify_ptr == notify_ptr && + if (lock->lock_type >= PENDING_READ_LOCK && + lock->notify_ptr == notify_ptr && lock->context.server == brl->server) { /* found it - delete it */ if (count == 1) { -- cgit From be0bd9fa336464e7c1fa2ab7cc5cd34075d595ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 May 2006 11:43:25 +0000 Subject: r15613: the snum doesn't identify the tcon, but the brl_context pointer does metze (This used to be commit 5e256f4b78441269de2e53c9582f3237e4220f6c) --- source4/ntvfs/common/brlock.c | 19 +++++++++---------- source4/ntvfs/posix/vfs_posix.c | 3 +-- 2 files changed, 10 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 80c4350eac..07f1593c2e 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -41,6 +41,7 @@ as it is applied consistently. */ +struct brl_context; /* the lock context contains the elements that define whether one lock is the same as another lock @@ -48,7 +49,7 @@ struct lock_context { uint32_t server; uint16_t smbpid; - int snum; + struct brl_context *ctx; }; /* The data in brlock records is an unsorted linear array of these @@ -66,7 +67,6 @@ struct lock_struct { struct brl_context { struct tdb_wrap *w; uint32_t server; - int snum; struct messaging_context *messaging_ctx; struct lock_struct last_lock; }; @@ -77,7 +77,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, int snum, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, struct messaging_context *messaging_ctx) { char *path; @@ -98,7 +98,6 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, int snum, } brl->server = server; - brl->snum = snum; brl->messaging_ctx = messaging_ctx; ZERO_STRUCT(brl->last_lock); @@ -113,7 +112,7 @@ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx { return (ctx1->server == ctx2->server && ctx1->smbpid == ctx2->smbpid && - ctx1->snum == ctx2->snum); + ctx1->ctx == ctx2->ctx); } /* @@ -200,7 +199,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) { if (lock->context.server == brl->last_lock.context.server && - lock->context.snum == brl->last_lock.context.snum && + lock->context.ctx == brl->last_lock.context.ctx && lock->fnum == brl->last_lock.fnum && lock->start == brl->last_lock.start && lock->size == brl->last_lock.size) { @@ -263,7 +262,7 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.snum = brl->snum; + lock.context.ctx = brl; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -398,7 +397,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, context.smbpid = smbpid; context.server = brl->server; - context.snum = brl->snum; + context.ctx = brl; /* there are existing locks - find a match */ locks = (struct lock_struct *)dbuf.dptr; @@ -549,7 +548,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; - lock.context.snum = brl->snum; + lock.context.ctx = brl; lock.start = start; lock.size = size; lock.fnum = fnum; @@ -602,7 +601,7 @@ NTSTATUS brl_close(struct brl_context *brl, for (i=0; icontext.snum == brl->snum && + if (lock->context.ctx == brl && lock->context.server == brl->server && lock->fnum == fnum) { /* found it - delete it */ diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 2d40ceb85d..eeee00313b 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -171,8 +171,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = pvfs; pvfs->brl_context = brl_init(pvfs, - pvfs->ntvfs->ctx->server_id, - pvfs->ntvfs->ctx->config.snum, + pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx); if (pvfs->brl_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; -- cgit From 5e6d1ea2618851ef99522a806f36916127e5294a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 May 2006 12:22:00 +0000 Subject: r15614: the byte range locking error handling caches the last failed lock per file handle and not per tree connect metze (This used to be commit 5d825261c0b8341f0a7f0f6d96d83807352566f4) --- source4/ntvfs/common/brlock.c | 132 +++++++++++++++++++++++++++------------- source4/ntvfs/posix/pvfs_lock.c | 33 +++++----- source4/ntvfs/posix/pvfs_open.c | 47 +++++++------- source4/ntvfs/posix/vfs_posix.h | 6 +- 4 files changed, 133 insertions(+), 85 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 07f1593c2e..b5df434435 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -57,21 +57,27 @@ struct lock_context { size of the record */ struct lock_struct { struct lock_context context; + uint16_t fnum; uint64_t start; uint64_t size; - uint16_t fnum; enum brl_type lock_type; void *notify_ptr; }; +/* this struct is attached to on oprn file handle */ +struct brl_handle { + DATA_BLOB key; + uint16_t fnum; + struct lock_struct last_lock; +}; + +/* this struct is typicaly attached to tcon */ struct brl_context { struct tdb_wrap *w; uint32_t server; struct messaging_context *messaging_ctx; - struct lock_struct last_lock; }; - /* Open up the brlock.tdb database. Close it down using talloc_free(). We need the messaging_ctx to allow for @@ -89,7 +95,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, } path = smbd_tmp_path(brl, "brlock.tdb"); - brl->w = tdb_wrap_open(brl, path, 0, + brl->w = tdb_wrap_open(brl, path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); talloc_free(path); if (brl->w == NULL) { @@ -99,11 +105,25 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, brl->server = server; brl->messaging_ctx = messaging_ctx; - ZERO_STRUCT(brl->last_lock); return brl; } +struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, uint16_t fnum) +{ + struct brl_handle *brlh; + + brlh = talloc(mem_ctx, struct brl_handle); + if (brlh == NULL) { + return NULL; + } + + brlh->key = *file_key; + brlh->fnum = fnum; + ZERO_STRUCT(brlh->last_lock); + + return brlh; +} /* see if two locking contexts are equal @@ -196,24 +216,47 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck is the same as this one and changes its error code. I wonder if any app depends on this? */ -static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *lock) +static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *lock) { - if (lock->context.server == brl->last_lock.context.server && - lock->context.ctx == brl->last_lock.context.ctx && - lock->fnum == brl->last_lock.fnum && - lock->start == brl->last_lock.start && - lock->size == brl->last_lock.size) { + /* + * this function is only called for non pending lock! + */ + + /* + * if the notify_ptr is non NULL, + * it means that we're at the end of a pending lock + * and the real lock is requested after the timout went by + * In this case we need to remember the last_lock and always + * give FILE_LOCK_CONFLICT + */ + if (lock->notify_ptr) { + brlh->last_lock = *lock; return NT_STATUS_FILE_LOCK_CONFLICT; } - brl->last_lock = *lock; - if (lock->start >= 0xEF000000 && - (lock->start >> 63) == 0) { - /* amazing the little things you learn with a test - suite. Locks beyond this offset (as a 64 bit - number!) always generate the conflict error code, - unless the top bit is set */ + + /* + * amazing the little things you learn with a test + * suite. Locks beyond this offset (as a 64 bit + * number!) always generate the conflict error code, + * unless the top bit is set + */ + if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { + brlh->last_lock = *lock; return NT_STATUS_FILE_LOCK_CONFLICT; } + + /* + * if the current lock matches the last failed lock on the file handle + * and starts at the same offset, then FILE_LOCK_CONFLICT should be returned + */ + if (lock->context.server == brlh->last_lock.context.server && + lock->context.ctx == brlh->last_lock.context.ctx && + lock->fnum == brlh->last_lock.fnum && + lock->start == brlh->last_lock.start) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + brlh->last_lock = *lock; return NT_STATUS_LOCK_NOT_GRANTED; } @@ -225,9 +268,8 @@ static NTSTATUS brl_lock_failed(struct brl_context *brl, struct lock_struct *loc notification is sent, identified by the notify_ptr */ NTSTATUS brl_lock(struct brl_context *brl, - DATA_BLOB *file_key, + struct brl_handle *brlh, uint16_t smbpid, - uint16_t fnum, uint64_t start, uint64_t size, enum brl_type lock_type, void *notify_ptr) @@ -237,8 +279,8 @@ NTSTATUS brl_lock(struct brl_context *brl, struct lock_struct lock, *locks=NULL; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -251,7 +293,12 @@ NTSTATUS brl_lock(struct brl_context *brl, preventing the real lock gets removed */ if (lock_type >= PENDING_READ_LOCK) { enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); - status = brl_lock(brl, file_key, smbpid, fnum, start, size, rw, NULL); + + /* here we need to force that the last_lock isn't overwritten */ + lock = brlh->last_lock; + status = brl_lock(brl, brlh, smbpid, start, size, rw, NULL); + brlh->last_lock = lock; + if (NT_STATUS_IS_OK(status)) { tdb_chainunlock(brl->w->tdb, kbuf); return NT_STATUS_OK; @@ -263,9 +310,10 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; + lock.fnum = brlh->fnum; + lock.context.ctx = brl; lock.start = start; lock.size = size; - lock.fnum = fnum; lock.lock_type = lock_type; lock.notify_ptr = notify_ptr; @@ -275,7 +323,7 @@ NTSTATUS brl_lock(struct brl_context *brl, count = dbuf.dsize / sizeof(*locks); for (i=0; i= PENDING_READ_LOCK) { - return brl_lock_failed(brl, &lock); + return NT_STATUS_LOCK_NOT_GRANTED; } return NT_STATUS_OK; @@ -371,9 +419,8 @@ static void brl_notify_all(struct brl_context *brl, Unlock a range of bytes. */ NTSTATUS brl_unlock(struct brl_context *brl, - DATA_BLOB *file_key, + struct brl_handle *brlh, uint16_t smbpid, - uint16_t fnum, uint64_t start, uint64_t size) { TDB_DATA kbuf, dbuf; @@ -382,8 +429,8 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_context context; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -407,7 +454,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_struct *lock = &locks[i]; if (brl_same_context(&lock->context, &context) && - lock->fnum == fnum && + lock->fnum == brlh->fnum && lock->start == start && lock->size == size && lock->lock_type < PENDING_READ_LOCK) { @@ -458,7 +505,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, getting it. In either case they no longer need to be notified. */ NTSTATUS brl_remove_pending(struct brl_context *brl, - DATA_BLOB *file_key, + struct brl_handle *brlh, void *notify_ptr) { TDB_DATA kbuf, dbuf; @@ -466,8 +513,8 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -528,8 +575,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, Test if we are allowed to perform IO on a region of an open file */ NTSTATUS brl_locktest(struct brl_context *brl, - DATA_BLOB *file_key, - uint16_t fnum, + struct brl_handle *brlh, uint16_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) @@ -538,8 +584,8 @@ NTSTATUS brl_locktest(struct brl_context *brl, int count, i; struct lock_struct lock, *locks; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; dbuf = tdb_fetch(brl->w->tdb, kbuf); if (dbuf.dptr == NULL) { @@ -549,9 +595,9 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; + lock.fnum = brlh->fnum; lock.start = start; lock.size = size; - lock.fnum = fnum; lock.lock_type = lock_type; /* there are existing locks - make sure they don't conflict */ @@ -574,15 +620,15 @@ NTSTATUS brl_locktest(struct brl_context *brl, Remove any locks associated with a open file. */ NTSTATUS brl_close(struct brl_context *brl, - DATA_BLOB *file_key, int fnum) + struct brl_handle *brlh) { TDB_DATA kbuf, dbuf; int count, i, dcount=0; struct lock_struct *locks; NTSTATUS status; - kbuf.dptr = file_key->data; - kbuf.dsize = file_key->length; + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -603,7 +649,7 @@ NTSTATUS brl_close(struct brl_context *brl, if (lock->context.ctx == brl && lock->context.server == brl->server && - lock->fnum == fnum) { + lock->fnum == brlh->fnum) { /* found it - delete it */ if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 0558fd52ea..99b694665d 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -41,8 +41,7 @@ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, } return brl_locktest(pvfs->brl_context, - &f->handle->brl_locking_key, - f->fnum, + f->brl_handle, smbpid, offset, count, rw); } @@ -73,9 +72,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, /* undo the locks we just did */ for (i=i-1;i>=0;i--) { brl_unlock(pvfs->brl_context, - &f->handle->brl_locking_key, + f->brl_handle, locks[i].pid, - f->fnum, locks[i].offset, locks[i].count); f->lock_count--; @@ -120,13 +118,17 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas if (reason == PVFS_WAIT_CANCEL) { status = NT_STATUS_FILE_LOCK_CONFLICT; } else { + /* + * here it's important to pass the pending pointer + * because with this we'll get the correct error code + * FILE_LOCK_CONFLICT in the error case + */ status = brl_lock(pvfs->brl_context, - &f->handle->brl_locking_key, + f->brl_handle, req->smbpid, - f->fnum, locks[pending->pending_lock].offset, locks[pending->pending_lock].count, - rw, NULL); + rw, pending); } if (NT_STATUS_IS_OK(status)) { f->lock_count++; @@ -138,7 +140,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas if (NT_STATUS_IS_OK(status) || timed_out) { NTSTATUS status2; status2 = brl_remove_pending(pvfs->brl_context, - &f->handle->brl_locking_key, pending); + f->brl_handle, pending); if (!NT_STATUS_IS_OK(status2)) { DEBUG(0,("pvfs_lock: failed to remove pending lock - %s\n", nt_errstr(status2))); } @@ -171,9 +173,8 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas } status = brl_lock(pvfs->brl_context, - &f->handle->brl_locking_key, + f->brl_handle, req->smbpid, - f->fnum, locks[i].offset, locks[i].count, rw, pending); @@ -216,7 +217,7 @@ void pvfs_lock_close(struct pvfs_state *pvfs, struct pvfs_file *f) if (f->lock_count || f->pending_list) { DEBUG(5,("pvfs_lock: removing %.0f locks on close\n", (double)f->lock_count)); - brl_close(f->pvfs->brl_context, &f->handle->brl_locking_key, f->fnum); + brl_close(f->pvfs->brl_context, f->brl_handle); f->lock_count = 0; } @@ -338,9 +339,8 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, for (i=0;ilockx.in.ulock_cnt;i++) { status = brl_unlock(pvfs->brl_context, - &f->handle->brl_locking_key, + f->brl_handle, locks[i].pid, - f->fnum, locks[i].offset, locks[i].count); if (!NT_STATUS_IS_OK(status)) { @@ -357,9 +357,8 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } status = brl_lock(pvfs->brl_context, - &f->handle->brl_locking_key, + f->brl_handle, locks[i].pid, - f->fnum, locks[i].offset, locks[i].count, rw, pending); @@ -381,9 +380,8 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, /* undo the locks we just did */ for (i=i-1;i>=0;i--) { brl_unlock(pvfs->brl_context, - &f->handle->brl_locking_key, + f->brl_handle, locks[i].pid, - f->fnum, locks[i].offset, locks[i].count); f->lock_count--; @@ -395,4 +393,3 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } - diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 9570fa08d9..3bbf840154 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -277,13 +277,13 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->share_access = io->generic.in.share_access; f->impersonation = io->generic.in.impersonation; f->access_mask = access_mask; + f->brl_handle = NULL; f->notify_buffer = NULL; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); f->handle->fd = -1; f->handle->odb_locking_key = data_blob(NULL, 0); - f->handle->brl_locking_key = data_blob(NULL, 0); f->handle->create_options = io->generic.in.create_options; f->handle->seek_offset = 0; f->handle->position = 0; @@ -526,32 +526,37 @@ static int pvfs_fnum_destructor(void *p) account of file streams (each stream is a separate byte range locking space) */ -static NTSTATUS pvfs_brl_locking_key(struct pvfs_filename *name, - TALLOC_CTX *mem_ctx, DATA_BLOB *key) +static NTSTATUS pvfs_brl_locking_handle(TALLOC_CTX *mem_ctx, + struct pvfs_filename *name, + uint16_t fnum, + struct brl_handle **_h) { - DATA_BLOB odb_key; + DATA_BLOB odb_key, key; NTSTATUS status; + struct brl_handle *h; + status = pvfs_locking_key(name, mem_ctx, &odb_key); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + NT_STATUS_NOT_OK_RETURN(status); + if (name->stream_name == NULL) { - *key = odb_key; - return NT_STATUS_OK; - } - *key = data_blob_talloc(mem_ctx, NULL, - odb_key.length + strlen(name->stream_name) + 1); - if (key->data == NULL) { - return NT_STATUS_NO_MEMORY; + key = odb_key; + } else { + key = data_blob_talloc(mem_ctx, NULL, + odb_key.length + strlen(name->stream_name) + 1); + NT_STATUS_HAVE_NO_MEMORY(key.data); + memcpy(key.data, odb_key.data, odb_key.length); + memcpy(key.data + odb_key.length, + name->stream_name, strlen(name->stream_name) + 1); + data_blob_free(&odb_key); } - memcpy(key->data, odb_key.data, odb_key.length); - memcpy(key->data + odb_key.length, - name->stream_name, strlen(name->stream_name)+1); - data_blob_free(&odb_key); + + h = brl_create_handle(mem_ctx, &key, fnum); + NT_STATUS_HAVE_NO_MEMORY(h); + + *_h = h; return NT_STATUS_OK; } - /* create a new file */ @@ -665,7 +670,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, goto cleanup_delete; } - status = pvfs_brl_locking_key(name, f->handle, &f->handle->brl_locking_key); + status = pvfs_brl_locking_handle(f, name, fnum, &f->brl_handle); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; } @@ -1168,7 +1173,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_brl_locking_key(name, f->handle, &f->handle->brl_locking_key); + status = pvfs_brl_locking_handle(f, name, f->fnum, &f->brl_handle); if (!NT_STATUS_IS_OK(status)) { idr_remove(pvfs->files.idtree, f->fnum); return status; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 335cfdf4e0..39481c03b1 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -134,9 +134,6 @@ struct pvfs_file_handle { /* a unique file key to be used for open file locking */ DATA_BLOB odb_locking_key; - /* a unique file key to be used for byte range locking */ - DATA_BLOB brl_locking_key; - uint32_t create_options; /* this is set by the mode_information level. What does it do? */ @@ -178,6 +175,9 @@ struct pvfs_file { /* a list of pending locks - used for locking cancel operations */ struct pvfs_pending_lock *pending_list; + /* a file handle to be used for byte range locking */ + struct brl_handle *brl_handle; + /* a count of active locks - used to avoid calling brl_close on file close */ uint64_t lock_count; -- cgit From 799113e1f9f199a38e52e33c69c592bc39f2a57a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 May 2006 12:32:23 +0000 Subject: r15693: fix the logic for the "cifs:map_trans2" parameter we need to return NOT_IMPLEMENTED when mapping is desired metze (This used to be commit 09aeb387a0a2f96704d20ecb26f92d4e3d178100) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index fd58d2c8bd..5eaab631db 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -877,7 +877,7 @@ static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - if (!private->map_trans2) { + if (private->map_trans2) { return NT_STATUS_NOT_IMPLEMENTED; } -- cgit From e6da54799ca20277de43357ba73412fbb675aa8f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 18 May 2006 12:34:37 +0000 Subject: r15694: for the cifs backend it's desired that we pull and repush the packets with our parsing code for the most stuff. So make cifs:maptrans2=yes the default. metze (This used to be commit 2a9e55fafc1368496bec4c4870070cfa0a19ca5e) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 5eaab631db..e12fd3de2f 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -175,7 +175,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, "cifs", "mapgeneric", False); private->map_trans2 = lp_parm_bool(ntvfs->ctx->config.snum, - "cifs", "maptrans2", False); + "cifs", "maptrans2", True); return NT_STATUS_OK; } -- cgit From 472c0886254b82c2feffea734a80c4d29bd773b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 May 2006 14:32:42 +0000 Subject: r15716: disable the cifs_posix ntvfs backend as it will not be updated with coming ntvfs subsystem changes metze (This used to be commit 69e7a454747acaad9ae4099d0ed5b4a5f3643ad7) --- source4/ntvfs/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index c40e103082..8bf506b253 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -31,6 +31,7 @@ OBJ_FILES = \ ################################################ # Start MODULE ntvfs_cifs_posix_cli [MODULE::ntvfs_cifs_posix] +ENABLE = NO INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h -- cgit From 7f0e17e9030ad734977f66c2cc27faec501154a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 May 2006 15:10:39 +0000 Subject: r15718: - split the SMBflush with the 0xFFFF wildcard fnum into a different level metze (This used to be commit 95bf41b4d4ec96349802955e364fe44ef85f9077) --- source4/ntvfs/nbench/vfs_nbench.c | 13 +++++++++++-- source4/ntvfs/posix/pvfs_flush.c | 22 +++++++++++++--------- source4/ntvfs/simple/vfs_simple.c | 18 ++++++++++++++++-- 3 files changed, 40 insertions(+), 13 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 77de979153..963d422cf0 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -534,10 +534,19 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, static void nbench_flush_send(struct ntvfs_request *req) { union smb_flush *io = req->async_states->private_data; + uint16_t fnum; + + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: + fnum = io->flush.in.file.fnum; + break; + case RAW_FLUSH_ALL: + fnum = 0xFFFF; + break; + } nbench_log(req, "Flush %d %s\n", - io->flush.in.file.fnum, - get_nt_error_c_code(req->async_states->status)); + fnum, get_nt_error_c_code(req->async_states->status)); PASS_THRU_REP_POST(req); } diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index d21f257201..c1d8820c43 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -46,23 +46,27 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - if (io->flush.in.file.fnum != 0xFFFF) { + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: f = pvfs_find_fd(pvfs, req, io->flush.in.file.fnum); if (!f) { return NT_STATUS_INVALID_HANDLE; } pvfs_flush_file(pvfs, f); return NT_STATUS_OK; - } - if (!(pvfs->flags & PVFS_FLAG_STRICT_SYNC)) { - return NT_STATUS_OK; - } + case RAW_FLUSH_ALL: + if (!(pvfs->flags & PVFS_FLAG_STRICT_SYNC)) { + return NT_STATUS_OK; + } - /* they are asking to flush all open files */ - for (f=pvfs->files.list;f;f=f->next) { - pvfs_flush_file(pvfs, f); + /* they are asking to flush all open files */ + for (f=pvfs->files.list;f;f=f->next) { + pvfs_flush_file(pvfs, f); + } + + return NT_STATUS_OK; } - return NT_STATUS_OK; + return NT_STATUS_INVALID_LEVEL; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 35c18e3f1c..1698f57aee 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -549,8 +549,22 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_flush *io) { - fsync(io->flush.in.file.fnum); - return NT_STATUS_OK; + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; + + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: + fsync(io->flush.in.file.fnum); + return NT_STATUS_OK; + + case RAW_FLUSH_ALL: + for (f=private->open_files;f;f=f->next) { + fsync(f->fd); + } + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; } /* -- cgit From 9ef33f5f5c786b83311ca088357fb2f0aa72fc9e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 08:15:22 +0000 Subject: r15734: This is a major change to the NTVFS subsystem: - to use a struct ntvfs_handle instead of a uint16_t fnum. (to make it independend from the frontend protocol) - the allocation of handles now is provided by the frontend (smbsrv_*) via callbacks and not by each backend module - this also makes sure that file handles are only passed to the ntvfs subsystem when the tcon and session matches, so modules can rely on this and need to check this. - this allows multiple modules in the ntvfs module chain to allocate file handles. This can be used for virtual files like "\\$Extend\\$Quota:$Q:$INDEX_ALLOCATION"... - also this will make SMB2 with 128 bit file handles possible metze (This used to be commit 287fc1c22d670f6e568014b420f7f4cb31dc7958) --- source4/ntvfs/cifs/vfs_cifs.c | 188 ++++++++++++++++++++++-------- source4/ntvfs/cifs_posix_cli/vfs_simple.c | 4 + source4/ntvfs/common/brlock.c | 22 ++-- source4/ntvfs/ipc/vfs_ipc.c | 106 ++++++++--------- source4/ntvfs/nbench/vfs_nbench.c | 68 +++++++---- source4/ntvfs/ntvfs.h | 38 +++++- source4/ntvfs/ntvfs_generic.c | 46 ++++---- source4/ntvfs/ntvfs_interface.c | 6 +- source4/ntvfs/ntvfs_util.c | 97 +++++++++++++++ source4/ntvfs/posix/pvfs_flush.c | 2 +- source4/ntvfs/posix/pvfs_ioctl.c | 2 +- source4/ntvfs/posix/pvfs_lock.c | 4 +- source4/ntvfs/posix/pvfs_notify.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 154 ++++++++++-------------- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_read.c | 2 +- source4/ntvfs/posix/pvfs_seek.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_write.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 4 - source4/ntvfs/posix/vfs_posix.h | 5 +- source4/ntvfs/simple/svfs.h | 3 + source4/ntvfs/simple/vfs_simple.c | 81 +++++++++---- 23 files changed, 538 insertions(+), 304 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index e12fd3de2f..c669414e09 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,12 +32,19 @@ #include "ntvfs/ntvfs.h" #include "include/dlinklist.h" +struct cvfs_file { + struct cvfs_file *prev, *next; + uint16_t fnum; + struct ntvfs_handle *h; +}; + /* this is stored in ntvfs_private */ struct cvfs_private { struct smbcli_tree *tree; struct smbcli_transport *transport; struct ntvfs_module_context *ntvfs; struct async_info *pending; + struct cvfs_file *files; BOOL map_generic; BOOL map_trans2; }; @@ -49,11 +56,24 @@ struct async_info { struct cvfs_private *cvfs; struct ntvfs_request *req; struct smbcli_request *c_req; + struct cvfs_file *f; void *parms; }; #define SETUP_PID private->tree->session->pid = req->smbpid +#define SETUP_FILE do { \ + struct cvfs_file *f; \ + f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \ + if (!f) return NT_STATUS_INVALID_HANDLE; \ + io->generic.in.file.fnum = f->fnum; \ +} while (0) + +#define SETUP_PID_AND_FILE do { \ + SETUP_PID; \ + SETUP_FILE; \ +} while (0) + /* a handler for oplock break events from the server - these need to be passed along to the client @@ -62,9 +82,22 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin { struct cvfs_private *private = p_private; NTSTATUS status; + struct ntvfs_handle *h = NULL; + struct cvfs_file *f; + + for (f=private->files; f; f=f->next) { + if (f->fnum != fnum) continue; + h = f->h; + break; + } + + if (!h) { + DEBUG(5,("vfs_cifs: ignoring oplock break level %d for fnum %d\n", level, fnum)); + return True; + } DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); - status = ntvfs_send_oplock_break(private->ntvfs, fnum, level); + status = ntvfs_send_oplock_break(private->ntvfs, h, level); if (!NT_STATUS_IS_OK(status)) return False; return True; } @@ -227,7 +260,7 @@ static void async_simple(struct smbcli_request *c_req) /* save some typing for the simple functions */ -#define ASYNC_RECV_TAIL(io, async_fn) do { \ +#define ASYNC_RECV_TAIL_F(io, async_fn, file) do { \ if (!c_req) return NT_STATUS_UNSUCCESSFUL; \ { \ struct async_info *async; \ @@ -235,6 +268,7 @@ static void async_simple(struct smbcli_request *c_req) if (!async) return NT_STATUS_NO_MEMORY; \ async->parms = io; \ async->req = req; \ + async->f = file; \ async->cvfs = private; \ async->c_req = c_req; \ DLIST_ADD(private->pending, async); \ @@ -246,6 +280,8 @@ static void async_simple(struct smbcli_request *c_req) return NT_STATUS_OK; \ } while (0) +#define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL) + #define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) /* @@ -287,12 +323,12 @@ static void async_ioctl(struct smbcli_request *c_req) ioctl interface */ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_ioctl *io) + struct ntvfs_request *req, union smb_ioctl *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + SETUP_PID_AND_FILE; /* see if the front end will allow us to perform this function asynchronously. */ @@ -309,7 +345,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, check if a directory exists */ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_chkpath *cp) + struct ntvfs_request *req, union smb_chkpath *cp) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -341,7 +377,7 @@ static void async_qpathinfo(struct smbcli_request *c_req) return info on a pathname */ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *info) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -373,20 +409,20 @@ static void async_qfileinfo(struct smbcli_request *c_req) query info on a open file */ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fileinfo *info) + struct ntvfs_request *req, union smb_fileinfo *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + SETUP_PID_AND_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_fileinfo(private->tree, req, info); + return smb_raw_fileinfo(private->tree, req, io); } - c_req = smb_raw_fileinfo_send(private->tree, info); + c_req = smb_raw_fileinfo_send(private->tree, io); - ASYNC_RECV_TAIL(info, async_qfileinfo); + ASYNC_RECV_TAIL(io, async_qfileinfo); } @@ -394,7 +430,7 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, set info on a pathname */ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_setfileinfo *st) + struct ntvfs_request *req, union smb_setfileinfo *st) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -417,9 +453,21 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, static void async_open(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; + struct cvfs_private *cvfs = async->cvfs; struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_open_recv(c_req, req, async->parms); + struct cvfs_file *f = async->f; + union smb_open *io = async->parms; + union smb_handle *file; talloc_free(async); + req->async_states->status = smb_raw_open_recv(c_req, req, io); + SMB_OPEN_OUT_FILE(io, file); + f->fnum = file->fnum; + file->ntvfs = NULL; + if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; + req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f); + if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; + file->ntvfs = f->h; +failed: req->async_states->send_fn(req); } @@ -427,10 +475,13 @@ static void async_open(struct smbcli_request *c_req) open a file */ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_open *io) + struct ntvfs_request *req, union smb_open *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + struct ntvfs_handle *h; + struct cvfs_file *f; + NTSTATUS status; SETUP_PID; @@ -439,20 +490,39 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(ntvfs, req, io); } + status = ntvfs_handle_new(ntvfs, req, &h); + NT_STATUS_NOT_OK_RETURN(status); + + f = talloc_zero(h, struct cvfs_file); + NT_STATUS_HAVE_NO_MEMORY(f); + f->h = h; + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_open(private->tree, req, io); + union smb_handle *file; + + status = smb_raw_open(private->tree, req, io); + NT_STATUS_NOT_OK_RETURN(status); + + SMB_OPEN_OUT_FILE(io, file); + f->fnum = file->fnum; + file->ntvfs = NULL; + status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f); + NT_STATUS_NOT_OK_RETURN(status); + file->ntvfs = f->h; + + return NT_STATUS_OK; } c_req = smb_raw_open_send(private->tree, io); - ASYNC_RECV_TAIL(io, async_open); + ASYNC_RECV_TAIL_F(io, async_open, f); } /* create a directory */ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_mkdir *md) + struct ntvfs_request *req, union smb_mkdir *md) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -472,7 +542,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, remove a directory */ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_rmdir *rd) + struct ntvfs_request *req, struct smb_rmdir *rd) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -491,7 +561,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, rename a set of files */ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_rename *ren) + struct ntvfs_request *req, union smb_rename *ren) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -511,7 +581,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, copy a set of files */ static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_copy *cp) + struct ntvfs_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; } @@ -532,25 +602,27 @@ static void async_read(struct smbcli_request *c_req) read from a file */ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_read *rd) + struct ntvfs_request *req, union smb_read *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; SETUP_PID; - if (rd->generic.level != RAW_READ_GENERIC && + if (io->generic.level != RAW_READ_GENERIC && private->map_generic) { - return ntvfs_map_read(ntvfs, req, rd); + return ntvfs_map_read(ntvfs, req, io); } + SETUP_FILE; + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_read(private->tree, rd); + return smb_raw_read(private->tree, io); } - c_req = smb_raw_read_send(private->tree, rd); + c_req = smb_raw_read_send(private->tree, io); - ASYNC_RECV_TAIL(rd, async_read); + ASYNC_RECV_TAIL(io, async_read); } /* @@ -569,25 +641,26 @@ static void async_write(struct smbcli_request *c_req) write to a file */ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_write *wr) + struct ntvfs_request *req, union smb_write *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; SETUP_PID; - if (wr->generic.level != RAW_WRITE_GENERIC && + if (io->generic.level != RAW_WRITE_GENERIC && private->map_generic) { - return ntvfs_map_write(ntvfs, req, wr); + return ntvfs_map_write(ntvfs, req, io); } + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_write(private->tree, wr); + return smb_raw_write(private->tree, io); } - c_req = smb_raw_write_send(private->tree, wr); + c_req = smb_raw_write_send(private->tree, io); - ASYNC_RECV_TAIL(wr, async_write); + ASYNC_RECV_TAIL(io, async_write); } /* @@ -612,7 +685,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + SETUP_PID_AND_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_seek(private->tree, io); @@ -634,6 +707,14 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, struct smbcli_request *c_req; SETUP_PID; + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: + SETUP_FILE; + break; + case RAW_FLUSH_ALL: + io->generic.in.file.fnum = 0xFFFF; + break; + } if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_flush(private->tree, io); @@ -648,7 +729,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, close a file */ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_close *io) + struct ntvfs_request *req, union smb_close *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -659,6 +740,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, private->map_generic) { return ntvfs_map_close(ntvfs, req, io); } + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_close(private->tree, io); @@ -673,7 +755,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, exit - closing files open by the pid */ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req) + struct ntvfs_request *req) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -693,7 +775,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, logoff - closing files open by the user */ static NTSTATUS cvfs_logoff(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req) + struct ntvfs_request *req) { /* we can't do this right in the cifs backend .... */ return NT_STATUS_OK; @@ -736,23 +818,24 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, lock a byte range */ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_lock *lck) + struct ntvfs_request *req, union smb_lock *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; SETUP_PID; - if (lck->generic.level != RAW_LOCK_GENERIC && + if (io->generic.level != RAW_LOCK_GENERIC && private->map_generic) { - return ntvfs_map_lock(ntvfs, req, lck); + return ntvfs_map_lock(ntvfs, req, io); } + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_lock(private->tree, lck); + return smb_raw_lock(private->tree, io); } - c_req = smb_raw_lock_send(private->tree, lck); + c_req = smb_raw_lock_send(private->tree, io); SIMPLE_ASYNC_TAIL; } @@ -761,17 +844,17 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, */ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - union smb_setfileinfo *info) + union smb_setfileinfo *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + SETUP_PID_AND_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_setfileinfo(private->tree, info); + return smb_raw_setfileinfo(private->tree, io); } - c_req = smb_raw_setfileinfo_send(private->tree, info); + c_req = smb_raw_setfileinfo_send(private->tree, io); SIMPLE_ASYNC_TAIL; } @@ -793,7 +876,7 @@ static void async_fsinfo(struct smbcli_request *c_req) return filesystem space info */ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fsinfo *fs) + struct ntvfs_request *req, union smb_fsinfo *fs) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; @@ -813,7 +896,7 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, return print queue info */ static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_lpq *lpq) + struct ntvfs_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; } @@ -916,14 +999,19 @@ static void async_changenotify(struct smbcli_request *c_req) /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info) + struct smb_notify *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; int saved_timeout = private->transport->options.request_timeout; + struct cvfs_file *f; SETUP_PID; + f = ntvfs_handle_get_backend_data(io->in.file.ntvfs, ntvfs); + if (!f) return NT_STATUS_INVALID_HANDLE; + io->in.file.fnum = f->fnum; + /* this request doesn't make sense unless its async */ if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return NT_STATUS_INVALID_PARAMETER; @@ -933,11 +1021,11 @@ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, forever */ private->transport->options.request_timeout = 0; - c_req = smb_raw_changenotify_send(private->tree, info); + c_req = smb_raw_changenotify_send(private->tree, io); private->transport->options.request_timeout = saved_timeout; - ASYNC_RECV_TAIL(info, async_changenotify); + ASYNC_RECV_TAIL(io, async_changenotify); } /* diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c index bbe52d9db1..cf28a02806 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_simple.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_simple.c @@ -19,6 +19,10 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* this module needs to be converted to use ntvfs_handle's! */ +#define fnum _XXX_use_ntvfs_handle_not_fnum_XXX_ + /* this implements a very simple NTVFS filesystem backend. diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index b5df434435..2816c563b8 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -57,7 +57,7 @@ struct lock_context { size of the record */ struct lock_struct { struct lock_context context; - uint16_t fnum; + struct ntvfs_handle *ntvfs; uint64_t start; uint64_t size; enum brl_type lock_type; @@ -67,7 +67,7 @@ struct lock_struct { /* this struct is attached to on oprn file handle */ struct brl_handle { DATA_BLOB key; - uint16_t fnum; + struct ntvfs_handle *ntvfs; struct lock_struct last_lock; }; @@ -109,7 +109,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, return brl; } -struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, uint16_t fnum) +struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) { struct brl_handle *brlh; @@ -119,7 +119,7 @@ struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, DATA_BLOB *file_key, u } brlh->key = *file_key; - brlh->fnum = fnum; + brlh->ntvfs = ntvfs; ZERO_STRUCT(brlh->last_lock); return brlh; @@ -173,7 +173,7 @@ static BOOL brl_conflict(struct lock_struct *lck1, } if (brl_same_context(&lck1->context, &lck2->context) && - lck2->lock_type == READ_LOCK && lck1->fnum == lck2->fnum) { + lck2->lock_type == READ_LOCK && lck1->ntvfs == lck2->ntvfs) { return False; } @@ -202,7 +202,7 @@ static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck * in smbtorture. */ if (brl_same_context(&lck1->context, &lck2->context) && - lck1->fnum == lck2->fnum && + lck1->ntvfs == lck2->ntvfs && (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { return False; } @@ -251,7 +251,7 @@ static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *loc */ if (lock->context.server == brlh->last_lock.context.server && lock->context.ctx == brlh->last_lock.context.ctx && - lock->fnum == brlh->last_lock.fnum && + lock->ntvfs == brlh->last_lock.ntvfs && lock->start == brlh->last_lock.start) { return NT_STATUS_FILE_LOCK_CONFLICT; } @@ -310,7 +310,7 @@ NTSTATUS brl_lock(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; - lock.fnum = brlh->fnum; + lock.ntvfs = brlh->ntvfs; lock.context.ctx = brl; lock.start = start; lock.size = size; @@ -454,7 +454,7 @@ NTSTATUS brl_unlock(struct brl_context *brl, struct lock_struct *lock = &locks[i]; if (brl_same_context(&lock->context, &context) && - lock->fnum == brlh->fnum && + lock->ntvfs == brlh->ntvfs && lock->start == start && lock->size == size && lock->lock_type < PENDING_READ_LOCK) { @@ -595,7 +595,7 @@ NTSTATUS brl_locktest(struct brl_context *brl, lock.context.smbpid = smbpid; lock.context.server = brl->server; lock.context.ctx = brl; - lock.fnum = brlh->fnum; + lock.ntvfs = brlh->ntvfs; lock.start = start; lock.size = size; lock.lock_type = lock_type; @@ -649,7 +649,7 @@ NTSTATUS brl_close(struct brl_context *brl, if (lock->context.ctx == brl && lock->context.server == brl->server && - lock->fnum == brlh->fnum) { + lock->ntvfs == brlh->ntvfs) { /* found it - delete it */ if (count > 1 && i < count-1) { memmove(&locks[i], &locks[i+1], diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 6ef380c4eb..fdad41145b 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -32,16 +32,12 @@ #include "ntvfs/ipc/proto.h" #include "rpc_server/dcerpc_server.h" -#define IPC_BASE_FNUM 0x400 - /* this is the private structure used to keep the state of an open ipc$ connection. It needs to keep information about all open pipes */ struct ipc_private { struct ntvfs_module_context *ntvfs; - struct idr_context *idtree_fnum; - struct dcesrv_context *dcesrv; /* a list of open pipes */ @@ -49,41 +45,43 @@ struct ipc_private { struct pipe_state *next, *prev; struct ipc_private *private; const char *pipe_name; - uint16_t fnum; + struct ntvfs_handle *handle; 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 auth_session_info *session_info; - - /* we need to remember the client pid that - opened the file so SMBexit works */ - uint16_t smbpid; } *pipe_list; }; /* - find a open pipe give a file descriptor + find a open pipe give a file handle */ -static struct pipe_state *pipe_state_find(struct ipc_private *private, uint16_t fnum, - struct auth_session_info *session_info) +static struct pipe_state *pipe_state_find(struct ipc_private *private, struct ntvfs_handle *handle) { struct pipe_state *s; void *p; - p = idr_find(private->idtree_fnum, fnum); + p = ntvfs_handle_get_backend_data(handle, private->ntvfs); if (!p) return NULL; s = talloc_get_type(p, struct pipe_state); - - if (s->session_info != session_info) { - return NULL; - } + if (!s) return NULL; return s; } +/* + find a open pipe give a wire fnum +*/ +static struct pipe_state *pipe_state_find_key(struct ipc_private *private, struct ntvfs_request *req, const DATA_BLOB *key) +{ + struct ntvfs_handle *h; + + h = ntvfs_handle_search_by_wire_key(private->ntvfs, req, key); + if (!h) return NULL; + + return pipe_state_find(private, h); +} + /* connect to a share - always works @@ -109,9 +107,6 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, private->ntvfs = ntvfs; private->pipe_list = NULL; - private->idtree_fnum = idr_init(private); - NT_STATUS_HAVE_NO_MEMORY(private->idtree_fnum); - /* setup the DCERPC server subsystem */ status = dcesrv_init_ipc_context(private, &private->dcesrv); NT_STATUS_NOT_OK_RETURN(status); @@ -182,7 +177,6 @@ static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs, static int ipc_fd_destructor(void *ptr) { struct pipe_state *p = ptr; - idr_remove(p->private->idtree_fnum, p->fnum); DLIST_REMOVE(p->private->pipe_list, p); return 0; } @@ -212,9 +206,12 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct dcerpc_binding *ep_description; struct ipc_private *private = ntvfs->private_data; - int fnum; + struct ntvfs_handle *h; + + status = ntvfs_handle_new(ntvfs, req, &h); + NT_STATUS_NOT_OK_RETURN(status); - p = talloc(req, struct pipe_state); + p = talloc(h, struct pipe_state); NT_STATUS_HAVE_NO_MEMORY(p); ep_description = talloc(req, struct dcerpc_binding); @@ -225,12 +222,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname); NT_STATUS_HAVE_NO_MEMORY(p->pipe_name); - fnum = idr_get_new_above(private->idtree_fnum, p, IPC_BASE_FNUM, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - - p->fnum = fnum; + p->handle = h; p->ipc_state = 0x5ff; /* @@ -248,14 +240,11 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, status = dcesrv_endpoint_search_connect(private->dcesrv, p, ep_description, - req->session_info, + h->session_info, ntvfs->ctx->event_ctx, 0, &p->dce_conn); - if (!NT_STATUS_IS_OK(status)) { - idr_remove(private->idtree_fnum, p->fnum); - return status; - } + NT_STATUS_NOT_OK_RETURN(status); p->dce_conn->transport.private_data = private; p->dce_conn->transport.report_output_data = NULL; @@ -264,16 +253,14 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, DLIST_ADD(private->pipe_list, p); - p->smbpid = req->smbpid; - p->session_info = req->session_info; p->private = private; - *ps = p; - - talloc_steal(private, p); - talloc_set_destructor(p, ipc_fd_destructor); + status = ntvfs_handle_set_backend_data(h, private->ntvfs, p); + NT_STATUS_NOT_OK_RETURN(status); + + *ps = p; return NT_STATUS_OK; } @@ -292,7 +279,7 @@ static NTSTATUS ipc_open_ntcreatex(struct ntvfs_module_context *ntvfs, } ZERO_STRUCT(oi->ntcreatex.out); - oi->ntcreatex.out.file.fnum = p->fnum; + oi->ntcreatex.out.file.ntvfs= p->handle; oi->ntcreatex.out.ipc_state = p->ipc_state; oi->ntcreatex.out.file_type = FILE_TYPE_MESSAGE_MODE_PIPE; @@ -315,7 +302,7 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, } ZERO_STRUCT(oi->openx.out); - oi->openx.out.file.fnum = p->fnum; + oi->openx.out.file.ntvfs= p->handle; oi->openx.out.ftype = 2; oi->openx.out.devstate = p->ipc_state; @@ -401,7 +388,6 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, { struct ipc_private *private = ntvfs->private_data; DATA_BLOB data; - uint16_t fnum; struct pipe_state *p; NTSTATUS status = NT_STATUS_OK; @@ -409,9 +395,7 @@ static NTSTATUS ipc_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(ntvfs, req, rd); } - fnum = rd->readx.in.file.fnum; - - p = pipe_state_find(private, fnum, req->session_info); + p = pipe_state_find(private, rd->readx.in.file.ntvfs); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -444,7 +428,6 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, { struct ipc_private *private = ntvfs->private_data; DATA_BLOB data; - uint16_t fnum; struct pipe_state *p; NTSTATUS status; @@ -452,11 +435,10 @@ static NTSTATUS ipc_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(ntvfs, req, wr); } - fnum = wr->writex.in.file.fnum; data.data = discard_const_p(void, wr->writex.in.data); data.length = wr->writex.in.count; - p = pipe_state_find(private, fnum, req->session_info); + p = pipe_state_find(private, wr->writex.in.file.ntvfs); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -505,7 +487,7 @@ static NTSTATUS ipc_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(ntvfs, req, io); } - p = pipe_state_find(private, io->close.in.file.fnum, req->session_info); + p = pipe_state_find(private, io->close.in.file.ntvfs); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -526,8 +508,8 @@ static NTSTATUS ipc_exit(struct ntvfs_module_context *ntvfs, for (p=private->pipe_list; p; p=next) { next = p->next; - if (p->session_info == req->session_info && - p->smbpid == req->smbpid) { + if (p->handle->session_info == req->session_info && + p->handle->smbpid == req->smbpid) { talloc_free(p); } } @@ -546,7 +528,7 @@ static NTSTATUS ipc_logoff(struct ntvfs_module_context *ntvfs, for (p=private->pipe_list; p; p=next) { next = p->next; - if (p->session_info == req->session_info) { + if (p->handle->session_info == req->session_info) { talloc_free(p); } } @@ -674,9 +656,12 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, struct pipe_state *p; struct ipc_private *private = ntvfs->private_data; NTSTATUS status; + DATA_BLOB fnum_key; /* the fnum is in setup[1] */ - p = pipe_state_find(private, trans->in.setup[1], req->session_info); + fnum_key = data_blob_const(&trans->in.setup[1], sizeof(trans->in.setup[1])); + + p = pipe_state_find_key(private, req, &fnum_key); if (!p) { return NT_STATUS_INVALID_HANDLE; } @@ -715,13 +700,16 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, /* SMBtrans - set named pipe state */ static NTSTATUS ipc_set_nm_pipe_state(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_trans2 *trans) + struct ntvfs_request *req, struct smb_trans2 *trans) { struct ipc_private *private = ntvfs->private_data; struct pipe_state *p; + DATA_BLOB fnum_key; /* the fnum is in setup[1] */ - p = pipe_state_find(private, trans->in.setup[1], req->session_info); + fnum_key = data_blob_const(&trans->in.setup[1], sizeof(trans->in.setup[1])); + + p = pipe_state_find_key(private, req, &fnum_key); if (!p) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 963d422cf0..2df3b95494 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -54,6 +54,26 @@ static void nbench_log(struct ntvfs_request *req, free(s); } +static char *nbench_ntvfs_handle_string(struct ntvfs_request *req, struct ntvfs_handle *h) +{ + DATA_BLOB key; + uint16_t fnum = 0; + + key = ntvfs_handle_get_wire_key(h, req); + + switch (key.length) { + case 2: /* SMB fnum */ + fnum = SVAL(key.data, 0); + break; + default: + DEBUG(0,("%s: invalid wire handle size: %u\n", + __FUNCTION__, key.length)); + break; + } + + return talloc_asprintf(req, "%u", fnum); +} + /* this pass through macro operates on request contexts, and disables async calls. @@ -237,8 +257,8 @@ static void nbench_qfileinfo_send(struct ntvfs_request *req) { union smb_fileinfo *info = req->async_states->private_data; - nbench_log(req, "QUERY_FILE_INFORMATION %d %d %s\n", - info->generic.in.file.fnum, + nbench_log(req, "QUERY_FILE_INFORMATION %s %d %s\n", + nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs), info->generic.level, get_nt_error_c_code(req->async_states->status)); @@ -292,11 +312,11 @@ static void nbench_open_send(struct ntvfs_request *req) if (!NT_STATUS_IS_OK(req->async_states->status)) { ZERO_STRUCT(io->ntcreatex.out); } - nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %d %s\n", + nbench_log(req, "NTCreateX \"%s\" 0x%x 0x%x %s %s\n", io->ntcreatex.in.fname, io->ntcreatex.in.create_options, io->ntcreatex.in.open_disposition, - io->ntcreatex.out.file.fnum, + nbench_ntvfs_handle_string(req, io->ntcreatex.out.file.ntvfs), get_nt_error_c_code(req->async_states->status)); break; @@ -430,8 +450,8 @@ static void nbench_read_send(struct ntvfs_request *req) if (!NT_STATUS_IS_OK(req->async_states->status)) { ZERO_STRUCT(rd->readx.out); } - nbench_log(req, "ReadX %d %d %d %d %s\n", - rd->readx.in.file.fnum, + nbench_log(req, "ReadX %s %d %d %d %s\n", + nbench_ntvfs_handle_string(req, rd->readx.in.file.ntvfs), (int)rd->readx.in.offset, rd->readx.in.maxcnt, rd->readx.out.nread, @@ -468,8 +488,8 @@ static void nbench_write_send(struct ntvfs_request *req) if (!NT_STATUS_IS_OK(req->async_states->status)) { ZERO_STRUCT(wr->writex.out); } - nbench_log(req, "WriteX %d %d %d %d %s\n", - wr->writex.in.file.fnum, + nbench_log(req, "WriteX %s %d %d %d %s\n", + nbench_ntvfs_handle_string(req, wr->writex.in.file.ntvfs), (int)wr->writex.in.offset, wr->writex.in.count, wr->writex.out.nwritten, @@ -480,8 +500,8 @@ static void nbench_write_send(struct ntvfs_request *req) if (!NT_STATUS_IS_OK(req->async_states->status)) { ZERO_STRUCT(wr->write.out); } - nbench_log(req, "Write %d %d %d %d %s\n", - wr->write.in.file.fnum, + nbench_log(req, "Write %s %d %d %d %s\n", + nbench_ntvfs_handle_string(req, wr->write.in.file.ntvfs), wr->write.in.offset, wr->write.in.count, wr->write.out.nwritten, @@ -534,20 +554,20 @@ static NTSTATUS nbench_seek(struct ntvfs_module_context *ntvfs, static void nbench_flush_send(struct ntvfs_request *req) { union smb_flush *io = req->async_states->private_data; - uint16_t fnum; switch (io->generic.level) { case RAW_FLUSH_FLUSH: - fnum = io->flush.in.file.fnum; + nbench_log(req, "Flush %s %s\n", + nbench_ntvfs_handle_string(req, io->flush.in.file.ntvfs), + get_nt_error_c_code(req->async_states->status)); break; case RAW_FLUSH_ALL: - fnum = 0xFFFF; + nbench_log(req, "Flush %d %s\n", + 0xFFFF, + get_nt_error_c_code(req->async_states->status)); break; } - nbench_log(req, "Flush %d %s\n", - fnum, get_nt_error_c_code(req->async_states->status)); - PASS_THRU_REP_POST(req); } @@ -571,8 +591,8 @@ static void nbench_close_send(struct ntvfs_request *req) switch (io->generic.level) { case RAW_CLOSE_CLOSE: - nbench_log(req, "Close %d %s\n", - io->close.in.file.fnum, + nbench_log(req, "Close %s %s\n", + nbench_ntvfs_handle_string(req, io->close.in.file.ntvfs), get_nt_error_c_code(req->async_states->status)); break; @@ -686,15 +706,15 @@ static void nbench_lock_send(struct ntvfs_request *req) if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.lock_cnt == 1 && lck->lockx.in.ulock_cnt == 0) { - nbench_log(req, "LockX %d %d %d %s\n", - lck->lockx.in.file.fnum, + nbench_log(req, "LockX %s %d %d %s\n", + nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs), (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); } else if (lck->generic.level == RAW_LOCK_LOCKX && lck->lockx.in.ulock_cnt == 1) { - nbench_log(req, "UnlockX %d %d %d %s\n", - lck->lockx.in.file.fnum, + nbench_log(req, "UnlockX %s %d %d %s\n", + nbench_ntvfs_handle_string(req, lck->lockx.in.file.ntvfs), (int)lck->lockx.in.locks[0].offset, (int)lck->lockx.in.locks[0].count, get_nt_error_c_code(req->async_states->status)); @@ -722,8 +742,8 @@ static void nbench_setfileinfo_send(struct ntvfs_request *req) { union smb_setfileinfo *info = req->async_states->private_data; - nbench_log(req, "SET_FILE_INFORMATION %d %d %s\n", - info->generic.in.file.fnum, + nbench_log(req, "SET_FILE_INFORMATION %s %d %s\n", + nbench_ntvfs_handle_string(req, info->generic.in.file.ntvfs), info->generic.level, get_nt_error_c_code(req->async_states->status)); diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 9069e6c2ac..cf541de81e 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -191,7 +191,7 @@ struct ntvfs_context { struct { void *private_data; - NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level); + NTSTATUS (*handler)(void *private_data, struct ntvfs_handle *handle, uint8_t level); } oplock; struct { @@ -199,8 +199,16 @@ struct ntvfs_context { struct socket_address *(*get_my_addr)(void *private_data, TALLOC_CTX *mem_ctx); struct socket_address *(*get_peer_addr)(void *private_data, TALLOC_CTX *mem_ctx); } client; -}; + struct { + void *private_data; + NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h); + NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h); + void (*destroy)(void *private_data, struct ntvfs_handle *h); + struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key); + DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx); + } handles; +}; /* a set of flags to control handling of request structures */ #define NTVFS_ASYNC_STATE_ASYNC (1<<1) /* the backend will answer this one later */ @@ -253,6 +261,28 @@ struct ntvfs_request { /* the system time when the request arrived */ struct timeval request_time; } statistics; + + struct { + void *private_data; + } frontend_data; +}; + +struct ntvfs_handle { + struct ntvfs_context *ctx; + + struct auth_session_info *session_info; + + uint16_t smbpid; + + struct ntvfs_handle_data { + struct ntvfs_handle_data *prev, *next; + struct ntvfs_module_context *owner; + void *private_data;/* this must be a valid talloc pointer */ + } *backend_data; + + struct { + void *private_data; + } frontend_data; }; /* this structure is used by backends to determine the size of some critical types */ @@ -264,6 +294,8 @@ struct ntvfs_critical_sizes { int sizeof_ntvfs_ops; int sizeof_ntvfs_async_state; int sizeof_ntvfs_request; + int sizeof_ntvfs_handle; + int sizeof_ntvfs_handle_data; }; #define NTVFS_CURRENT_CRITICAL_SIZES(c) \ @@ -275,6 +307,8 @@ struct ntvfs_critical_sizes { .sizeof_ntvfs_ops = sizeof(struct ntvfs_ops), \ .sizeof_ntvfs_async_state = sizeof(struct ntvfs_async_state), \ .sizeof_ntvfs_request = sizeof(struct ntvfs_request), \ + .sizeof_ntvfs_handle = sizeof(struct ntvfs_handle), \ + .sizeof_ntvfs_handle_data = sizeof(struct ntvfs_handle_data), \ } struct messaging_context; diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index b04a3af21e..5058225ceb 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -153,7 +153,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, switch (io->generic.level) { case RAW_OPEN_OPEN: - io->openold.out.file.fnum = io2->generic.out.file.fnum; + io->openold.out.file.ntvfs = io2->generic.out.file.ntvfs; io->openold.out.attrib = io2->generic.out.attrib; io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openold.out.size = io2->generic.out.size; @@ -161,7 +161,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, break; case RAW_OPEN_OPENX: - io->openx.out.file.fnum = io2->generic.out.file.fnum; + io->openx.out.file.ntvfs = io2->generic.out.file.ntvfs; io->openx.out.attrib = io2->generic.out.attrib; io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->openx.out.size = io2->generic.out.size; @@ -181,7 +181,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, break; case RAW_OPEN_T2OPEN: - io->t2open.out.file.fnum = io2->generic.out.file.fnum; + io->t2open.out.file.ntvfs = io2->generic.out.file.ntvfs; io->t2open.out.attrib = io2->generic.out.attrib; io->t2open.out.write_time = nt_time_to_unix(io2->generic.out.write_time); io->t2open.out.size = io2->generic.out.size; @@ -194,12 +194,12 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_MKNEW: case RAW_OPEN_CREATE: - io->mknew.out.file.fnum = io2->generic.out.file.fnum; + io->mknew.out.file.ntvfs= io2->generic.out.file.ntvfs; write_time = io->mknew.in.write_time; break; case RAW_OPEN_CTEMP: - io->ctemp.out.file.fnum = io2->generic.out.file.fnum; + io->ctemp.out.file.ntvfs= io2->generic.out.file.ntvfs; io->ctemp.out.name = talloc_strdup(req, io2->generic.in.fname + strlen(io->ctemp.in.directory) + 1); NT_STATUS_HAVE_NO_MEMORY(io->ctemp.out.name); @@ -218,7 +218,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, sf = talloc(req, union smb_setfileinfo); NT_STATUS_HAVE_NO_MEMORY(sf); sf->generic.level = RAW_SFILEINFO_STANDARD; - sf->generic.in.file.fnum = io2->generic.out.file.fnum; + sf->generic.in.file.ntvfs = io2->generic.out.file.ntvfs; sf->standard.in.create_time = 0; sf->standard.in.write_time = write_time; sf->standard.in.access_time = 0; @@ -229,7 +229,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, sf = talloc(req, union smb_setfileinfo); NT_STATUS_HAVE_NO_MEMORY(sf); sf->generic.level = RAW_SFILEINFO_END_OF_FILE_INFORMATION; - sf->generic.in.file.fnum = io2->generic.out.file.fnum; + sf->generic.in.file.ntvfs = io2->generic.out.file.ntvfs; sf->end_of_file_info.in.size = set_size; status = ntvfs->ops->setfileinfo(ntvfs, req, sf); if (NT_STATUS_IS_OK(status)) { @@ -859,7 +859,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs, /* ask the backend for the generic info */ info2->generic.level = RAW_FILEINFO_GENERIC; - info2->generic.in.file.fnum = info->generic.in.file.fnum; + info2->generic.in.file.ntvfs= info->generic.in.file.ntvfs; /* only used by the simple backend, which doesn't do async */ req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; @@ -941,7 +941,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, } lck2->generic.level = RAW_LOCK_GENERIC; - lck2->generic.in.file.fnum = lck->lock.in.file.fnum; + lck2->generic.in.file.ntvfs= lck->lock.in.file.ntvfs; lck2->generic.in.mode = 0; lck2->generic.in.timeout = 0; lck2->generic.in.locks = locks; @@ -988,10 +988,10 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - lck->unlock.level = RAW_LOCK_UNLOCK; - lck->unlock.in.file.fnum= wr->writeunlock.in.file.fnum; - lck->unlock.in.count = wr->writeunlock.in.count; - lck->unlock.in.offset = wr->writeunlock.in.offset; + lck->unlock.level = RAW_LOCK_UNLOCK; + lck->unlock.in.file.ntvfs = wr->writeunlock.in.file.ntvfs; + lck->unlock.in.count = wr->writeunlock.in.count; + lck->unlock.in.offset = wr->writeunlock.in.offset; if (lck->unlock.in.count != 0) { /* do the lock sync for now */ @@ -1011,7 +1011,7 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, } cl->close.level = RAW_CLOSE_CLOSE; - cl->close.in.file.fnum = wr->writeclose.in.file.fnum; + cl->close.in.file.ntvfs = wr->writeclose.in.file.ntvfs; cl->close.in.write_time = wr->writeclose.in.mtime; if (wr2->generic.in.count != 0) { @@ -1062,7 +1062,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITE: - wr2->writex.in.file.fnum = wr->write.in.file.fnum; + wr2->writex.in.file.ntvfs= wr->write.in.file.ntvfs; wr2->writex.in.offset = wr->write.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = wr->write.in.remaining; @@ -1072,7 +1072,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITEUNLOCK: - wr2->writex.in.file.fnum = wr->writeunlock.in.file.fnum; + wr2->writex.in.file.ntvfs= wr->writeunlock.in.file.ntvfs; wr2->writex.in.offset = wr->writeunlock.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = wr->writeunlock.in.remaining; @@ -1082,7 +1082,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_WRITECLOSE: - wr2->writex.in.file.fnum = wr->writeclose.in.file.fnum; + wr2->writex.in.file.ntvfs= wr->writeclose.in.file.ntvfs; wr2->writex.in.offset = wr->writeclose.in.offset; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = 0; @@ -1092,7 +1092,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, break; case RAW_WRITE_SPLWRITE: - wr2->writex.in.file.fnum = wr->splwrite.in.file.fnum; + wr2->writex.in.file.ntvfs= wr->splwrite.in.file.ntvfs; wr2->writex.in.offset = 0; wr2->writex.in.wmode = 0; wr2->writex.in.remaining = 0; @@ -1164,7 +1164,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, break; case RAW_READ_READ: - rd2->readx.in.file.fnum = rd->read.in.file.fnum; + rd2->readx.in.file.ntvfs= rd->read.in.file.ntvfs; rd2->readx.in.offset = rd->read.in.offset; rd2->readx.in.mincnt = rd->read.in.count; rd2->readx.in.maxcnt = rd->read.in.count; @@ -1174,7 +1174,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, break; case RAW_READ_READBRAW: - rd2->readx.in.file.fnum = rd->readbraw.in.file.fnum; + rd2->readx.in.file.ntvfs= rd->readbraw.in.file.ntvfs; rd2->readx.in.offset = rd->readbraw.in.offset; rd2->readx.in.mincnt = rd->readbraw.in.mincnt; rd2->readx.in.maxcnt = rd->readbraw.in.maxcnt; @@ -1194,13 +1194,13 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, goto done; } lck->lock.level = RAW_LOCK_LOCK; - lck->lock.in.file.fnum = rd->lockread.in.file.fnum; + lck->lock.in.file.ntvfs = rd->lockread.in.file.ntvfs; lck->lock.in.count = rd->lockread.in.count; lck->lock.in.offset = rd->lockread.in.offset; status = ntvfs->ops->lock(ntvfs, req, lck); req->async_states->state = state; - rd2->readx.in.file.fnum = rd->lockread.in.file.fnum; + rd2->readx.in.file.ntvfs= rd->lockread.in.file.ntvfs; rd2->readx.in.offset = rd->lockread.in.offset; rd2->readx.in.mincnt = rd->lockread.in.count; rd2->readx.in.maxcnt = rd->lockread.in.count; @@ -1238,7 +1238,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, case RAW_CLOSE_SPLCLOSE: cl2->close.level = RAW_CLOSE_CLOSE; - cl2->close.in.file.fnum = cl->splclose.in.file.fnum; + cl2->close.in.file.ntvfs= cl->splclose.in.file.ntvfs; break; } diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index c26832d96e..67cbe8df22 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -668,7 +668,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, /* oplock helpers */ _PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs, - NTSTATUS (*handler)(void *private_data, uint16_t fnum, uint8_t level), + NTSTATUS (*handler)(void *private_data, struct ntvfs_handle *handle, uint8_t level), void *private_data) { ntvfs->oplock.handler = handler; @@ -677,13 +677,13 @@ _PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs, } _PUBLIC_ NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs, - uint16_t fnum, uint8_t level) + struct ntvfs_handle *handle, uint8_t level) { if (!ntvfs->ctx->oplock.handler) { return NT_STATUS_OK; } - return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, fnum, level); + return ntvfs->ctx->oplock.handler(ntvfs->ctx->oplock.private_data, handle, level); } /* client connection callback */ diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 52f03430ce..de19a9c352 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -98,3 +98,100 @@ _PUBLIC_ void ntvfs_async_state_pop(struct ntvfs_request *req) talloc_free(async); } + +_PUBLIC_ NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct ntvfs_handle **h) +{ + return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h); +} + +_PUBLIC_ NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h, + struct ntvfs_module_context *ntvfs, + TALLOC_CTX *private_data) +{ + struct ntvfs_handle_data *d; + BOOL first_time = h->backend_data?False:True; + + for (d=h->backend_data; d; d = d->next) { + if (d->owner != ntvfs) continue; + d->private_data = talloc_steal(d, private_data); + return NT_STATUS_OK; + } + + d = talloc(h, struct ntvfs_handle_data); + NT_STATUS_HAVE_NO_MEMORY(d); + d->owner = ntvfs; + d->private_data = talloc_steal(d, private_data); + + DLIST_ADD(h->backend_data, d); + + if (first_time) { + NTSTATUS status; + status = h->ctx->handles.make_valid(h->ctx->handles.private_data, h); + NT_STATUS_NOT_OK_RETURN(status); + } + + return NT_STATUS_OK; +} + +_PUBLIC_ void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h, + struct ntvfs_module_context *ntvfs) +{ + struct ntvfs_handle_data *d; + + for (d=h->backend_data; d; d = d->next) { + if (d->owner != ntvfs) continue; + return d->private_data; + } + + return NULL; +} + +_PUBLIC_ void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h, + struct ntvfs_module_context *ntvfs) +{ + struct ntvfs_handle_data *d,*n; + + for (d=h->backend_data; d; d = n) { + n = d->next; + if (d->owner != ntvfs) continue; + DLIST_REMOVE(h->backend_data, d); + talloc_free(d); + d = NULL; + } + + if (h->backend_data) return; + + /* if there's no backend_data anymore, destroy the handle */ + h->ctx->handles.destroy(h->ctx->handles.private_data, h); +} + +_PUBLIC_ struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + const DATA_BLOB *key) +{ + return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key); +} + +_PUBLIC_ DATA_BLOB ntvfs_handle_get_wire_key(struct ntvfs_handle *h, TALLOC_CTX *mem_ctx) +{ + return h->ctx->handles.get_wire_key(h->ctx->handles.private_data, h, mem_ctx); +} + +_PUBLIC_ NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs, + NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h), + NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h), + void (*destroy)(void *private_data, struct ntvfs_handle *h), + struct ntvfs_handle *(*search_by_wire_key)(void *private_data, struct ntvfs_request *req, const DATA_BLOB *key), + DATA_BLOB (*get_wire_key)(void *private_data, struct ntvfs_handle *handle, TALLOC_CTX *mem_ctx), + void *private_data) +{ + ntvfs->handles.create_new = create_new; + ntvfs->handles.make_valid = make_valid; + ntvfs->handles.destroy = destroy; + ntvfs->handles.search_by_wire_key = search_by_wire_key; + ntvfs->handles.get_wire_key = get_wire_key; + ntvfs->handles.private_data = private_data; + return NT_STATUS_OK; +} diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index c1d8820c43..7bd973ed4e 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -48,7 +48,7 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, switch (io->generic.level) { case RAW_FLUSH_FLUSH: - f = pvfs_find_fd(pvfs, req, io->flush.in.file.fnum); + f = pvfs_find_fd(pvfs, req, io->flush.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 829da47a12..417458edf0 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -42,7 +42,7 @@ static NTSTATUS pvfs_ntioctl(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - f = pvfs_find_fd(pvfs, req, io->ntioctl.in.file.fnum); + f = pvfs_find_fd(pvfs, req, io->ntioctl.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 99b694665d..8dcee5f983 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -244,7 +244,7 @@ static NTSTATUS pvfs_lock_cancel(struct pvfs_state *pvfs, struct ntvfs_request * /* check if the lock request matches exactly - you can only cancel with exact matches */ if (p->lck->lockx.in.ulock_cnt == lck->lockx.in.ulock_cnt && p->lck->lockx.in.lock_cnt == lck->lockx.in.lock_cnt && - p->lck->lockx.in.file.fnum == lck->lockx.in.file.fnum && + p->lck->lockx.in.file.ntvfs== lck->lockx.in.file.ntvfs && p->lck->lockx.in.mode == (lck->lockx.in.mode & ~LOCKING_ANDX_CANCEL_LOCK)) { int i; @@ -286,7 +286,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return ntvfs_map_lock(ntvfs, req, lck); } - f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.fnum); + f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index ea4c0b2bc6..dfe1737060 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -203,7 +203,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct notify_pending *pending; - f = pvfs_find_fd(pvfs, req, info->in.file.fnum); + f = pvfs_find_fd(pvfs, req, info->in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3bbf840154..fd382ba1d9 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -28,40 +28,29 @@ #include "messaging/messaging.h" #include "librpc/gen_ndr/xattr.h" -/* - create file handles with convenient numbers for sniffers -*/ -#define PVFS_MIN_FILE_FNUM 0x100 -#define PVFS_MIN_NEW_FNUM 0x200 -#define PVFS_MIN_DIR_FNUM 0x300 - /* find open file handle given fnum */ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, - struct ntvfs_request *req, uint16_t fnum) + struct ntvfs_request *req, struct ntvfs_handle *h) { + void *p; struct pvfs_file *f; - f = idr_find(pvfs->files.idtree, fnum); - if (f == NULL) { - return NULL; - } + p = ntvfs_handle_get_backend_data(h, pvfs->ntvfs); + if (!p) return NULL; - if (f->fnum != fnum) { - smb_panic("pvfs_find_fd: idtree_fnum corruption\n"); - } + f = talloc_get_type(p, struct pvfs_file); + if (!f) return NULL; if (req->session_info != f->session_info) { - DEBUG(2,("pvfs_find_fd: attempt to use wrong session for fnum %d\n", - fnum)); + DEBUG(2,("pvfs_find_fd: attempt to use wrong session for handle %p\n",h)); return NULL; } return f; } - /* cleanup a open directory handle */ @@ -114,8 +103,10 @@ static int pvfs_dir_handle_destructor(void *p) static int pvfs_dir_fnum_destructor(void *p) { struct pvfs_file *f = p; + DLIST_REMOVE(f->pvfs->files.list, f); - idr_remove(f->pvfs->files.idtree, f->fnum); + ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs); + return 0; } @@ -125,7 +116,7 @@ static int pvfs_dir_fnum_destructor(void *p) static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, struct ntvfs_request *req, struct pvfs_filename *name, - int fd, int fnum, + int fd, struct pvfs_file *f, union smb_open *io) { NTSTATUS status; @@ -150,7 +141,7 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, * but the user doesn't have SeSecurityPrivilege * - w2k3 allows it */ - set.set_secdesc.in.file.fnum = fnum; + set.set_secdesc.in.file.ntvfs = f->ntvfs; set.set_secdesc.in.secinfo_flags = SECINFO_DACL; set.set_secdesc.in.sd = io->ntcreatex.in.sec_desc; @@ -197,7 +188,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, union smb_open *io) { struct pvfs_file *f; - int fnum; + struct ntvfs_handle *h; NTSTATUS status; uint32_t create_action; uint32_t access_mask = io->generic.in.access_mask; @@ -242,7 +233,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_INVALID_PARAMETER; } - f = talloc(req, struct pvfs_file); + status = ntvfs_handle_new(pvfs->ntvfs, req, &h); + NT_STATUS_NOT_OK_RETURN(status); + + f = talloc(h, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; } @@ -252,11 +246,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_DIR_FNUM, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - if (name->exists) { /* check the security descriptor */ status = pvfs_access_check(pvfs, req, name, &access_mask); @@ -264,11 +253,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, status = pvfs_access_check_create(pvfs, req, name, &access_mask); } if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, fnum); return status; } - f->fnum = fnum; + f->ntvfs = h; f->session_info = req->session_info; f->smbpid = req->smbpid; f->pvfs = pvfs; @@ -297,12 +285,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, del_on_close = False; } - if (name->exists) { /* form the lock context used for opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, f->fnum); return status; } @@ -313,7 +299,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ - idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -323,7 +308,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, name->full_name, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, f->fnum); talloc_free(lck); return status; } @@ -342,7 +326,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, mode_t mode = pvfs_fileperms(pvfs, attrib); if (mkdir(name->full_name, mode) == -1) { - idr_remove(pvfs->files.idtree, fnum); return pvfs_map_errno(pvfs,errno); } @@ -353,7 +336,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, goto cleanup_delete; } - status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, fnum, io); + status = pvfs_open_setup_eas_acl(pvfs, req, name, -1, f, io); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; } @@ -361,7 +344,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* form the lock context used for opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, f->fnum); return status; } @@ -371,7 +353,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ - idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -396,15 +377,17 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } if (!name->exists) { - idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_OBJECT_NAME_NOT_FOUND; } /* the open succeeded, keep this handle permanently */ - talloc_steal(pvfs, f); + status = ntvfs_handle_set_backend_data(h, pvfs->ntvfs, f); + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; + } io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.out.file.fnum = f->fnum; + io->generic.out.file.ntvfs = h; io->generic.out.create_action = create_action; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -420,7 +403,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_OK; cleanup_delete: - idr_remove(pvfs->files.idtree, fnum); rmdir(name->full_name); return status; } @@ -510,11 +492,11 @@ static int pvfs_handle_destructor(void *p) */ static int pvfs_fnum_destructor(void *p) { - struct pvfs_file *f = p; + struct pvfs_file *f = talloc_get_type(p, struct pvfs_file); DLIST_REMOVE(f->pvfs->files.list, f); pvfs_lock_close(f->pvfs, f); - idr_remove(f->pvfs->files.idtree, f->fnum); + ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs); return 0; } @@ -527,8 +509,8 @@ static int pvfs_fnum_destructor(void *p) locking space) */ static NTSTATUS pvfs_brl_locking_handle(TALLOC_CTX *mem_ctx, - struct pvfs_filename *name, - uint16_t fnum, + struct pvfs_filename *name, + struct ntvfs_handle *ntvfs, struct brl_handle **_h) { DATA_BLOB odb_key, key; @@ -550,7 +532,7 @@ static NTSTATUS pvfs_brl_locking_handle(TALLOC_CTX *mem_ctx, data_blob_free(&odb_key); } - h = brl_create_handle(mem_ctx, &key, fnum); + h = brl_create_handle(mem_ctx, ntvfs, &key); NT_STATUS_HAVE_NO_MEMORY(h); *_h = h; @@ -567,7 +549,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, { struct pvfs_file *f; NTSTATUS status; - int flags, fnum, fd; + struct ntvfs_handle *h; + int flags, fd; struct odb_lock *lck; uint32_t create_options = io->generic.in.create_options; uint32_t share_access = io->generic.in.share_access; @@ -606,20 +589,14 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, flags = O_RDONLY; } - f = talloc(req, struct pvfs_file); - if (f == NULL) { - return NT_STATUS_NO_MEMORY; - } + status = ntvfs_handle_new(pvfs->ntvfs, req, &h); + NT_STATUS_NOT_OK_RETURN(status); - f->handle = talloc(f, struct pvfs_file_handle); - if (f->handle == NULL) { - return NT_STATUS_NO_MEMORY; - } + f = talloc(h, struct pvfs_file); + NT_STATUS_HAVE_NO_MEMORY(f); - fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_NEW_FNUM, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; - } + f->handle = talloc(f, struct pvfs_file_handle); + NT_STATUS_HAVE_NO_MEMORY(f->handle); attrib = io->ntcreatex.in.file_attr | FILE_ATTRIBUTE_ARCHIVE; mode = pvfs_fileperms(pvfs, attrib); @@ -627,7 +604,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* create the file */ fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode); if (fd == -1) { - idr_remove(pvfs->files.idtree, fnum); return pvfs_map_errno(pvfs, errno); } @@ -637,7 +613,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, if (name->stream_name) { status = pvfs_stream_create(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, fnum); close(fd); return status; } @@ -646,7 +621,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* re-resolve the open fd */ status = pvfs_resolve_name_fd(pvfs, fd, name); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, fnum); close(fd); return status; } @@ -658,7 +632,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } - status = pvfs_open_setup_eas_acl(pvfs, req, name, fd, fnum, io); + status = pvfs_open_setup_eas_acl(pvfs, req, name, fd, f, io); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; } @@ -670,7 +644,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, goto cleanup_delete; } - status = pvfs_brl_locking_handle(f, name, fnum, &f->brl_handle); + status = pvfs_brl_locking_handle(f, name, h, &f->brl_handle); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; } @@ -708,7 +682,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, /* bad news, we must have hit a race - we don't delete the file here as the most likely scenario is that someone else created the file at the same time */ - idr_remove(pvfs->files.idtree, fnum); close(fd); return status; } @@ -717,7 +690,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, oplock_granted = OPLOCK_BATCH; } - f->fnum = fnum; + f->ntvfs = h; f->session_info = req->session_info; f->smbpid = req->smbpid; f->pvfs = pvfs; @@ -746,7 +719,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, talloc_set_destructor(f->handle, pvfs_handle_destructor); io->generic.out.oplock_level = oplock_granted; - io->generic.out.file.fnum = f->fnum; + io->generic.out.file.ntvfs = f->ntvfs; io->generic.out.create_action = NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -760,7 +733,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, io->generic.out.is_directory = 0; /* success - keep the file handle */ - talloc_steal(pvfs, f); + status = ntvfs_handle_set_backend_data(h, pvfs->ntvfs, f); + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; + } notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, @@ -770,7 +746,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return NT_STATUS_OK; cleanup_delete: - idr_remove(pvfs->files.idtree, fnum); close(fd); unlink(name->full_name); return status; @@ -873,6 +848,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f2; struct pvfs_filename *name; + NTSTATUS status; /* search for an existing open with the right parameters. Note the magic ntcreatex options flag, which is set in the @@ -919,7 +895,7 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, name = f->handle->name; io->generic.out.oplock_level = OPLOCK_NONE; - io->generic.out.file.fnum = f->fnum; + io->generic.out.file.ntvfs = f->ntvfs; io->generic.out.create_action = NTCREATEX_ACTION_EXISTED; io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; @@ -931,8 +907,9 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, io->generic.out.file_type = FILE_TYPE_DISK; io->generic.out.ipc_state = 0; io->generic.out.is_directory = 0; - - talloc_steal(f->pvfs, f); + + status = ntvfs_handle_set_backend_data(f->ntvfs, ntvfs, f); + NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; } @@ -1009,8 +986,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, int flags; struct pvfs_filename *name; struct pvfs_file *f; + struct ntvfs_handle *h; NTSTATUS status; - int fnum, fd; + int fd; struct odb_lock *lck; uint32_t create_options; uint32_t share_access; @@ -1128,7 +1106,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } - f = talloc(req, struct pvfs_file); + status = ntvfs_handle_new(pvfs->ntvfs, req, &h); + NT_STATUS_NOT_OK_RETURN(status); + + f = talloc(h, struct pvfs_file); if (f == NULL) { return NT_STATUS_NO_MEMORY; } @@ -1138,13 +1119,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - /* allocate a fnum */ - fnum = idr_get_new_above(pvfs->files.idtree, f, PVFS_MIN_FILE_FNUM, UINT16_MAX); - if (fnum == -1) { - return NT_STATUS_TOO_MANY_OPENED_FILES; - } - - f->fnum = fnum; + f->ntvfs = h; f->session_info = req->session_info; f->smbpid = req->smbpid; f->pvfs = pvfs; @@ -1169,13 +1144,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, f->fnum); return status; } - status = pvfs_brl_locking_handle(f, name, f->fnum, &f->brl_handle); + status = pvfs_brl_locking_handle(f, name, h, &f->brl_handle); if (!NT_STATUS_IS_OK(status)) { - idr_remove(pvfs->files.idtree, f->fnum); return status; } @@ -1186,7 +1159,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, name->full_name)); /* we were supposed to do a blocking lock, so something is badly wrong! */ - idr_remove(pvfs->files.idtree, fnum); return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -1288,8 +1260,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_free(lck); + status = ntvfs_handle_set_backend_data(h, ntvfs, f); + NT_STATUS_NOT_OK_RETURN(status); + io->generic.out.oplock_level = oplock_granted; - io->generic.out.file.fnum = f->fnum; + io->generic.out.file.ntvfs = h; io->generic.out.create_action = stream_existed? NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED; io->generic.out.create_time = name->dos.create_time; @@ -1303,9 +1278,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, io->generic.out.ipc_state = 0; io->generic.out.is_directory = 0; - /* success - keep the file handle */ - talloc_steal(f->pvfs, f); - return NT_STATUS_OK; } @@ -1328,7 +1300,7 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return ntvfs_map_close(ntvfs, req, io); } - f = pvfs_find_fd(pvfs, req, io->close.in.file.fnum); + f = pvfs_find_fd(pvfs, req, io->close.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index e4e69a8289..2d43c5a582 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -336,7 +336,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, NTSTATUS status; uint32_t access_needed; - f = pvfs_find_fd(pvfs, req, info->generic.in.file.fnum); + f = pvfs_find_fd(pvfs, req, info->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 411fbd9c27..13e8264000 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -41,7 +41,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return ntvfs_map_read(ntvfs, req, rd); } - f = pvfs_find_fd(pvfs, req, rd->readx.in.file.fnum); + f = pvfs_find_fd(pvfs, req, rd->readx.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index dbfb4e1c3d..7365f33b15 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -35,7 +35,7 @@ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, struct pvfs_file_handle *h; NTSTATUS status; - f = pvfs_find_fd(pvfs, req, io->lseek.in.file.fnum); + f = pvfs_find_fd(pvfs, req, io->lseek.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index e85f52fc2c..2665b9e5f5 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -262,7 +262,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, uint32_t access_needed; uint32_t change_mask = 0; - f = pvfs_find_fd(pvfs, req, info->generic.in.file.fnum); + f = pvfs_find_fd(pvfs, req, info->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 1da1985550..9f58281919 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -40,7 +40,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, return ntvfs_map_write(ntvfs, req, wr); } - f = pvfs_find_fd(pvfs, req, wr->writex.in.file.fnum); + f = pvfs_find_fd(pvfs, req, wr->writex.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index eeee00313b..1682a94ac9 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -194,10 +194,6 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - /* allocate the fnum id -> ptr tree */ - pvfs->files.idtree = idr_init(pvfs); - NT_STATUS_HAVE_NO_MEMORY(pvfs->files.idtree); - /* allocate the search handle -> ptr tree */ pvfs->search.idtree = idr_init(pvfs); NT_STATUS_HAVE_NO_MEMORY(pvfs->search.idtree); diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 39481c03b1..63ee3395f8 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -63,9 +63,6 @@ struct pvfs_state { uint32_t alloc_size_rounding; struct { - /* an id tree mapping open file handle -> struct pvfs_file */ - struct idr_context *idtree; - /* the open files as DLINKLIST */ struct pvfs_file *list; } files; @@ -156,7 +153,7 @@ struct pvfs_file_handle { struct pvfs_file { struct pvfs_file *next, *prev; struct pvfs_file_handle *handle; - uint16_t fnum; + struct ntvfs_handle *ntvfs; struct pvfs_state *pvfs; diff --git a/source4/ntvfs/simple/svfs.h b/source4/ntvfs/simple/svfs.h index 74e7b6c452..e5ad3b95d9 100644 --- a/source4/ntvfs/simple/svfs.h +++ b/source4/ntvfs/simple/svfs.h @@ -1,5 +1,7 @@ struct svfs_private { + struct ntvfs_module_context *ntvfs; + /* the base directory */ char *connectpath; @@ -24,6 +26,7 @@ struct svfs_dir { struct svfs_file { struct svfs_file *next, *prev; int fd; + struct ntvfs_handle *handle; char *name; }; diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 1698f57aee..e0f0083630 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -55,7 +55,8 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, int snum = ntvfs->ctx->config.snum; private = talloc(ntvfs, struct svfs_private); - + NT_STATUS_HAVE_NO_MEMORY(private); + private->ntvfs = ntvfs; private->next_search_handle = 0; private->connectpath = talloc_strdup(private, lp_pathname(snum)); private->open_files = NULL; @@ -91,15 +92,18 @@ static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs) /* find open file handle given fd */ -static struct svfs_file *find_fd(struct svfs_private *private, int fd) +static struct svfs_file *find_fd(struct svfs_private *private, struct ntvfs_handle *handle) { struct svfs_file *f; - for (f=private->open_files;f;f=f->next) { - if (f->fd == fd) { - return f; - } - } - return NULL; + void *p; + + p = ntvfs_handle_get_backend_data(handle, private->ntvfs); + if (!p) return NULL; + + f = talloc_get_type(p, struct svfs_file); + if (!f) return NULL; + + return f; } /* @@ -282,12 +286,12 @@ static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, return ntvfs_map_qfileinfo(ntvfs, req, info); } - f = find_fd(private, info->generic.in.file.fnum); + f = find_fd(private, info->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (fstat(info->generic.in.file.fnum, &st) == -1) { + if (fstat(f->fd, &st) == -1) { return map_nt_error_from_unix(errno); } @@ -308,6 +312,8 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, struct svfs_file *f; int create_flags, rdwr_flags; BOOL readonly; + NTSTATUS status; + struct ntvfs_handle *handle; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(ntvfs, req, io); @@ -379,7 +385,10 @@ do_open: return map_nt_error_from_unix(errno); } - f = talloc(ntvfs, struct svfs_file); + status = ntvfs_handle_new(ntvfs, req, &handle); + NT_STATUS_NOT_OK_RETURN(status); + + f = talloc(handle, struct svfs_file); NT_STATUS_HAVE_NO_MEMORY(f); f->fd = fd; f->name = talloc_strdup(f, unix_path); @@ -387,13 +396,16 @@ do_open: DLIST_ADD(private->open_files, f); + status = ntvfs_handle_set_backend_data(handle, ntvfs, f); + NT_STATUS_NOT_OK_RETURN(status); + ZERO_STRUCT(io->generic.out); unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); unix_to_nt_time(&io->generic.out.access_time, st.st_atime); unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); - io->generic.out.file.fnum = fd; + io->generic.out.file.ntvfs = handle; io->generic.out.alloc_size = st.st_size; io->generic.out.size = st.st_size; io->generic.out.attrib = svfs_unix_to_dos_attrib(st.st_mode); @@ -483,13 +495,20 @@ static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_read *rd) { + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; ssize_t ret; if (rd->generic.level != RAW_READ_READX) { return NT_STATUS_NOT_SUPPORTED; } - ret = pread(rd->readx.in.file.fnum, + f = find_fd(private, rd->readx.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + ret = pread(f->fd, rd->readx.out.data, rd->readx.in.maxcnt, rd->readx.in.offset); @@ -510,6 +529,8 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *wr) { + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; ssize_t ret; if (wr->generic.level != RAW_WRITE_WRITEX) { @@ -518,7 +539,12 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, CHECK_READ_ONLY(req); - ret = pwrite(wr->writex.in.file.fnum, + f = find_fd(private, wr->writex.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + ret = pwrite(f->fd, wr->writex.in.data, wr->writex.in.count, wr->writex.in.offset); @@ -554,7 +580,11 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, switch (io->generic.level) { case RAW_FLUSH_FLUSH: - fsync(io->flush.in.file.fnum); + f = find_fd(private, io->flush.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + fsync(f->fd); return NT_STATUS_OK; case RAW_FLUSH_ALL: @@ -582,12 +612,12 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; } - f = find_fd(private, io->close.in.file.fnum); + f = find_fd(private, io->close.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (close(io->close.in.file.fnum) == -1) { + if (close(f->fd) == -1) { return map_nt_error_from_unix(errno); } @@ -662,15 +692,21 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *info) { + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; struct utimbuf unix_times; - int fd; CHECK_READ_ONLY(req); - + + f = find_fd(private, info->generic.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + switch (info->generic.level) { case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: - if (ftruncate(info->end_of_file_info.in.file.fnum, + if (ftruncate(f->fd, info->end_of_file_info.in.size) == -1) { return map_nt_error_from_unix(errno); } @@ -678,8 +714,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_SETATTRE: unix_times.actime = info->setattre.in.access_time; unix_times.modtime = info->setattre.in.write_time; - fd = info->setattre.in.file.fnum; - + if (unix_times.actime == 0 && unix_times.modtime == 0) { break; } @@ -690,7 +725,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, } /* Set the date on this file */ - if (svfs_file_utime(fd, &unix_times) != 0) { + if (svfs_file_utime(f->fd, &unix_times) != 0) { return NT_STATUS_ACCESS_DENIED; } break; -- cgit From 1a60ed5aa86c41e86ea046d54a378bbd45ce7709 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 09:54:10 +0000 Subject: r15738: make the code more readable metze (This used to be commit 5114cab66294aa4fce586bb47a90ae32450ddbf3) --- source4/ntvfs/posix/pvfs_ioctl.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 417458edf0..3744530a7a 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -65,18 +65,13 @@ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_ioctl *io) { - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - switch (io->generic.level) { case RAW_IOCTL_IOCTL: - status = pvfs_ioctl_old(ntvfs, req, io); - break; + return pvfs_ioctl_old(ntvfs, req, io); case RAW_IOCTL_NTIOCTL: - status = pvfs_ntioctl(ntvfs, req, io); - break; + return pvfs_ntioctl(ntvfs, req, io); } - return status; + return NT_STATUS_INVALID_LEVEL; } - -- cgit From e306c5bf129a981693bd251d45597f1e584ee850 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 10:46:38 +0000 Subject: r15741: move smb2 request structures into the main smb request structs as new levels metze (This used to be commit 91806353174704857dfcc15a730af7232cfde660) --- source4/ntvfs/cifs/vfs_cifs.c | 2 ++ source4/ntvfs/nbench/vfs_nbench.c | 4 ++++ source4/ntvfs/simple/vfs_simple.c | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c669414e09..2b4f9bb8c5 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -714,6 +714,8 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, case RAW_FLUSH_ALL: io->generic.in.file.fnum = 0xFFFF; break; + case RAW_FLUSH_SMB2: + return NT_STATUS_INVALID_LEVEL; } if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 2df3b95494..f7834a9751 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -566,6 +566,10 @@ static void nbench_flush_send(struct ntvfs_request *req) 0xFFFF, get_nt_error_c_code(req->async_states->status)); break; + default: + nbench_log(req, "Flush-%d - NOT HANDLED\n", + io->generic.level); + break; } PASS_THRU_REP_POST(req); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index e0f0083630..9e5d4ae922 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -580,7 +580,9 @@ static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, switch (io->generic.level) { case RAW_FLUSH_FLUSH: - f = find_fd(private, io->flush.in.file.ntvfs); + case RAW_FLUSH_SMB2: + /* ignore the additional unknown option in SMB2 */ + f = find_fd(private, io->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } -- cgit From 35d6a53ff7b7b906d9a42bad5b7647a2abc6a3f6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 16:10:22 +0000 Subject: r15750: don't clear after setting metze (This used to be commit 0e23d2a45a4507051bb3453387b82e7a9f4433ea) --- source4/ntvfs/ntvfs_generic.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 5058225ceb..a4cc0ff396 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -454,7 +454,6 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, case RAW_OPEN_CTEMP: io2->generic.in.file_attr = io->ctemp.in.attrib; - io2->generic.in.file_attr = 0; io2->generic.in.fname = talloc_asprintf(io2, "%s\\SRV%s", io->ctemp.in.directory, -- cgit From 6af051409a0a1bcda9e2673bab1652690ab88fea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 16:53:44 +0000 Subject: r15752: - add generic mapping for RAW_OPEN_SMB2 metze (This used to be commit d26144f9575f1e53bfb837024d964a3324d38728) --- source4/ntvfs/ntvfs_generic.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index a4cc0ff396..8b80e9db80 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -205,6 +205,22 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(io->ctemp.out.name); break; + case RAW_OPEN_SMB2: + io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; + io->smb2.out.oplock_flags = 0; + io->smb2.out.create_action = io2->generic.out.create_action; + io->smb2.out.create_time = io2->generic.out.create_time; + io->smb2.out.access_time = io2->generic.out.access_time; + io->smb2.out.write_time = io2->generic.out.write_time; + io->smb2.out.change_time = io2->generic.out.change_time; + io->smb2.out.alloc_size = io2->generic.out.alloc_size; + io->smb2.out.size = io2->generic.out.size; + /*io->smb2.out.file_attr = io2->generic.out.attrib; would this be correct? */ + io->smb2.out.file_attr = 0; + io->smb2.out._pad = 0; + io->smb2.out.blob = data_blob(NULL, 0); + break; + default: return NT_STATUS_INVALID_LEVEL; } @@ -467,6 +483,22 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, NTCREATEX_SHARE_ACCESS_WRITE; status = ntvfs->ops->open(ntvfs, req, io2); break; + case RAW_OPEN_SMB2: + io2->generic.in.flags = 0; + io2->generic.in.root_fid = 0; + io2->generic.in.access_mask = io->smb2.in.access_mask; + io2->generic.in.alloc_size = 0; + io2->generic.in.file_attr = io->smb2.in.file_attr; + io2->generic.in.share_access = io->smb2.in.share_access; + io2->generic.in.open_disposition= io->smb2.in.open_disposition; + io2->generic.in.create_options = io->smb2.in.create_options; + io2->generic.in.impersonation = io->smb2.in.impersonation; + io2->generic.in.security_flags = 0; + io2->generic.in.fname = io->smb2.in.fname; + io2->generic.in.sec_desc = NULL; + io2->generic.in.ea_list = NULL; + status = ntvfs->ops->open(ntvfs, req, io2); + break; default: status = NT_STATUS_INVALID_LEVEL; -- cgit From 183fb2bd4b51fbf6d5660b84804b6f79bf9db36f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 17:20:34 +0000 Subject: r15754: - implement SMB2 Close - add RAW_CLOSE_SMB2 generic mapping metze (This used to be commit 41bc3cfc822bfc2fe4413f93a180fc4507005282) --- source4/ntvfs/ntvfs_generic.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 8b80e9db80..89481e5038 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1268,8 +1268,15 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; case RAW_CLOSE_SPLCLOSE: - cl2->close.level = RAW_CLOSE_CLOSE; - cl2->close.in.file.ntvfs= cl->splclose.in.file.ntvfs; + cl2->generic.level = RAW_CLOSE_CLOSE; + cl2->generic.in.file.ntvfs = cl->splclose.in.file.ntvfs; + break; + + case RAW_CLOSE_SMB2: + cl2->generic.level = RAW_CLOSE_CLOSE; + cl2->generic.in.file.ntvfs = cl->smb2.in.file.ntvfs; + /* SMB2 Close has output parameter, but we just zero them */ + ZERO_STRUCT(cl->smb2.out); break; } -- cgit From 772c4928404bc26e5cc7cfdcba1f931ee0d0de82 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 18:56:08 +0000 Subject: r15757: - add RAW_WRITE_SMB2 => generic mapping - implement SMB2 Write metze (This used to be commit 5ab6f304f8b91c0362fd57429cc24126b241bd51) --- source4/ntvfs/ntvfs_generic.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 89481e5038..119fef2c6d 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1056,6 +1056,14 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, case RAW_WRITE_SPLWRITE: break; + + case RAW_WRITE_SMB2: + wr->smb2.out._pad = 0; + wr->smb2.out.nwritten = wr2->generic.out.nwritten; + wr->smb2.out.unknown1 = 0; + wr->smb2.out._bug = 0; + break; + default: return NT_STATUS_INVALID_LEVEL; } @@ -1131,6 +1139,15 @@ _PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, wr2->writex.in.data = wr->splwrite.in.data; status = ntvfs->ops->write(ntvfs, req, wr2); break; + + case RAW_WRITE_SMB2: + wr2->writex.in.file.ntvfs= wr->smb2.in.file.ntvfs; + wr2->writex.in.offset = wr->smb2.in.offset; + wr2->writex.in.wmode = 0; + wr2->writex.in.remaining = 0; + wr2->writex.in.count = wr->smb2.in.data.length; + wr2->writex.in.data = wr->smb2.in.data.data; + status = ntvfs->ops->write(ntvfs, req, wr2); } return ntvfs_map_async_finish(req, status); -- cgit From 49012954d055f2b7ed5a796f767e5c0535d80558 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 18:57:32 +0000 Subject: r15758: - handle RAW_FLUSH_SMB2 in the posix ntvfs backend - Implement SMB2 Flush metze (This used to be commit 41d87ebe355cd34d35a93d1e90cd2680363cb5d3) --- source4/ntvfs/posix/pvfs_flush.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 7bd973ed4e..2e64dc983d 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -48,7 +48,9 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, switch (io->generic.level) { case RAW_FLUSH_FLUSH: - f = pvfs_find_fd(pvfs, req, io->flush.in.file.ntvfs); + case RAW_FLUSH_SMB2: + /* TODO: take care of io->smb2.in.unknown */ + f = pvfs_find_fd(pvfs, req, io->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } -- cgit From e23cc70a72e6582e91bcfdaf1d6ed2191e7e23a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 20 May 2006 19:03:06 +0000 Subject: r15760: - add RAW_READ_SMB2 => generic mapping - Implement SMB2 Read metze (This used to be commit d0ac0c5af44ba5aa8b18106c2ac26c0d194e59b4) --- source4/ntvfs/ntvfs_generic.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 119fef2c6d..922093a0a9 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1165,13 +1165,16 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, { switch (rd->generic.level) { case RAW_READ_READ: - rd->read.out.nread = rd2->generic.out.nread; + rd->read.out.nread = rd2->generic.out.nread; break; case RAW_READ_READBRAW: - rd->readbraw.out.nread = rd2->generic.out.nread; + rd->readbraw.out.nread = rd2->generic.out.nread; break; case RAW_READ_LOCKREAD: - rd->lockread.out.nread = rd2->generic.out.nread; + rd->lockread.out.nread = rd2->generic.out.nread; + break; + case RAW_READ_SMB2: + rd->smb2.out.data.length= rd2->generic.out.nread; break; default: return NT_STATUS_INVALID_LEVEL; @@ -1259,6 +1262,22 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, status = ntvfs->ops->read(ntvfs, req, rd2); } break; + + case RAW_READ_SMB2: + if (rd->smb2.in.length > UINT16_MAX) { + DEBUG(0,("%s: mapping SMB2 => generic length to large %u!\n", + __FUNCTION__, rd->smb2.in.length)); + status = NT_STATUS_FOOBAR; + goto done; + } + rd2->readx.in.file.ntvfs= rd->smb2.in.file.ntvfs; + rd2->readx.in.offset = rd->smb2.in.offset; + rd2->readx.in.mincnt = rd->smb2.in.length; + rd2->readx.in.maxcnt = rd->smb2.in.length; + rd2->readx.in.remaining = 0; + rd2->readx.out.data = rd->smb2.out.data.data; + status = ntvfs->ops->read(ntvfs, req, rd2); + break; } done: -- cgit From 017855b766892090837791822f7380a32c30480d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 08:24:11 +0000 Subject: r15767: we need to free here metze (This used to be commit 98890052fec7ba4a8bf4e07a6b000d04d768f581) --- source4/ntvfs/ntvfs_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index de19a9c352..fec119b653 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -58,8 +58,8 @@ _PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, T DLIST_ADD(req->async_states, async); return req; - failed: + talloc_free(req); return NULL; } -- cgit From 8b4da058bcc49a91b332d2999a34e0bb45e0f680 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 08:29:56 +0000 Subject: r15768: make it possible that the caller of the ntvfs_subsystem doesn't provide handle callbacks metze (This used to be commit dfd07e6f890ebe11d77d39f65c3f6850c9b9c37e) --- source4/ntvfs/ntvfs_util.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index fec119b653..d99d040378 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -103,6 +103,9 @@ _PUBLIC_ NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct ntvfs_handle **h) { + if (!ntvfs->ctx->handles.create_new) { + return NT_STATUS_NOT_IMPLEMENTED; + } return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h); } @@ -171,6 +174,9 @@ _PUBLIC_ struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_modul struct ntvfs_request *req, const DATA_BLOB *key) { + if (!ntvfs->ctx->handles.search_by_wire_key) { + return NULL; + } return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key); } -- cgit From e941cc3003f84de4d7846c4f19ce5d006e9f8e98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 11:39:50 +0000 Subject: r15772: pass the messaging context and server_id to the dcerpc server subsystem metze (This used to be commit fb1debf219089188d1a8233ab3ff4ff314f7df0b) --- source4/ntvfs/ipc/vfs_ipc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index fdad41145b..2e7c538c3f 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -242,6 +242,8 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs, ep_description, h->session_info, ntvfs->ctx->event_ctx, + ntvfs->ctx->msg_ctx, + ntvfs->ctx->server_id, 0, &p->dce_conn); NT_STATUS_NOT_OK_RETURN(status); -- cgit From 0f2c93016d870adc4eb4e7072c05a8ef8273cb0c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 12:56:49 +0000 Subject: r15774: take care of the SYSTEM_SECURITY flag metze (This used to be commit 98f58d710a4fe1cd3581b1fb25c4f0c0236b5092) --- source4/ntvfs/posix/pvfs_acl.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 3826b2f157..3d276431dc 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -350,7 +350,9 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL; /* owner and root get extra permissions */ - if (uid == 0 || uid == name->st.st_uid) { + if (uid == 0) { + max_bits |= SEC_STD_ALL | SEC_FLAG_SYSTEM_SECURITY; + } else if (uid == name->st.st_uid) { max_bits |= SEC_STD_ALL; } @@ -359,6 +361,10 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, return NT_STATUS_OK; } + if (uid != 0 && (*access_mask & SEC_FLAG_SYSTEM_SECURITY)) { + return NT_STATUS_PRIVILEGE_NOT_HELD; + } + if (*access_mask & ~max_bits) { return NT_STATUS_ACCESS_DENIED; } -- cgit From 225d6485eb896bfa50b564aabfe20967edd008e4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 May 2006 06:18:40 +0000 Subject: r15797: fixed a notify bug, where a notify_remove() is beyond the current max depth (This used to be commit 2ebcfcc6dadd4a420431c733bb12fe7719057fd6) --- source4/ntvfs/common/notify.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 2d880dd5c4..57cbce3863 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -447,6 +447,11 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) return status; } + if (depth >= notify->array->num_depths) { + notify_unlock(notify); + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + /* we only have to search at the depth of this element */ d = ¬ify->array->depth[depth]; -- cgit From d9bdfb0a0720907151b71086be289a0f6ec2bb98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 22 May 2006 17:21:38 +0000 Subject: r15814: add SMB2 Lock interface structure metze (This used to be commit 8f1850ef65dc8c860912639d787d82399d015f13) --- source4/ntvfs/ntvfs_generic.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 922093a0a9..3283ee673d 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -969,6 +969,9 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, lck2->generic.in.ulock_cnt = 1; lck2->generic.in.lock_cnt = 0; break; + + case RAW_LOCK_SMB2: + return NT_STATUS_INVALID_LEVEL; } lck2->generic.level = RAW_LOCK_GENERIC; -- cgit From ae034247efdd380ecf0588846ca2fe959e4d1e48 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 May 2006 03:52:57 +0000 Subject: r15825: there are quite subtle semantics with change notify events being sent when a context (such as a tree connect) is destroyed. The behaviour was changed by the ntvfs memory leak fix, and this patch is needed to make it all work again. (This used to be commit a7ad4df7cd6cdf88fd49698840a072a4474a318a) --- source4/ntvfs/posix/pvfs_notify.c | 42 +++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index dfe1737060..bd1e1b9d89 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -25,6 +25,7 @@ #include "lib/messaging/irpc.h" #include "messaging/messaging.h" #include "dlinklist.h" +#include "lib/events/events.h" /* pending notifies buffer, hung off struct pvfs_file for open directories that have used change notify */ @@ -43,10 +44,23 @@ struct pvfs_notify_buffer { } *pending; }; +/* + send a notify on the next event run. +*/ +void pvfs_notify_send_next(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) +{ + struct ntvfs_request *req = talloc_get_type(ptr, struct ntvfs_request); + talloc_free(req); + req->async_states->send_fn(req); +} + + /* send a reply to a pending notify request */ -static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS status) +static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, + NTSTATUS status, BOOL immediate) { struct notify_pending *pending = notify_buffer->pending; struct ntvfs_request *req; @@ -57,7 +71,7 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS /* on buffer overflow return no changes and destroys the notify buffer */ notify_buffer->num_changes = 0; while (notify_buffer->pending) { - pvfs_notify_send(notify_buffer, NT_STATUS_OK); + pvfs_notify_send(notify_buffer, NT_STATUS_OK, immediate); } talloc_free(notify_buffer); return; @@ -86,7 +100,18 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS } req->async_states->status = status; - req->async_states->send_fn(req); + + if (immediate) { + req->async_states->send_fn(req); + return; + } + + /* we can't call pvfs_notify_send() directly here, as that + would free the request, and the ntvfs modules above us + could use it, so call it on the next event */ + talloc_reference(notify_buffer, req); + event_add_timed(req->ctx->event_ctx, + req, timeval_zero(), pvfs_notify_send_next, req); } /* @@ -97,7 +122,7 @@ static int pvfs_notify_destructor(void *ptr) struct pvfs_notify_buffer *n = talloc_get_type(ptr, struct pvfs_notify_buffer); notify_remove(n->f->pvfs->notify_context, n); n->f->notify_buffer = NULL; - pvfs_notify_send(n, NT_STATUS_OK); + pvfs_notify_send(n, NT_STATUS_OK, True); return 0; } @@ -140,7 +165,7 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) /* send what we have, unless its the first part of a rename */ if (ev->action != NOTIFY_ACTION_OLD_NAME) { - pvfs_notify_send(n, NT_STATUS_OK); + pvfs_notify_send(n, NT_STATUS_OK, True); } } @@ -185,9 +210,9 @@ static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason) struct pvfs_notify_buffer *notify_buffer = talloc_get_type(private, struct pvfs_notify_buffer); if (reason == PVFS_WAIT_CANCEL) { - pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED); + pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED, False); } else { - pvfs_notify_send(notify_buffer, NT_STATUS_OK); + pvfs_notify_send(notify_buffer, NT_STATUS_OK, True); } } @@ -251,7 +276,8 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } - pvfs_notify_send(f->notify_buffer, NT_STATUS_OK); + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + pvfs_notify_send(f->notify_buffer, NT_STATUS_OK, False); return NT_STATUS_OK; } -- cgit From 507e502c352ff53952fa704f1bde5accc0bd8f1a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 May 2006 03:53:23 +0000 Subject: r15826: ensure we don't dereference sec when NULL (This used to be commit b6bf6b17cd92a3869c49209bc8ea8ef8c6c25cdd) --- source4/ntvfs/unixuid/vfs_unixuid.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 9afb2b1380..b12339b2c8 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -191,7 +191,8 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, NTSTATUS status2; \ struct unix_sec_ctx *sec; \ status = unixuid_setup_security(ntvfs, req, &sec); \ - if (NT_STATUS_IS_OK(status)) status = ntvfs_next_##op args; \ + NT_STATUS_NOT_OK_RETURN(status); \ + status = ntvfs_next_##op args; \ status2 = set_unix_security(sec); \ if (!NT_STATUS_IS_OK(status2)) smb_panic("Unable to reset security context"); \ } while (0) -- cgit From d8223e4b94afe04f6b2fcf1a8ee4ba2d5cf16d22 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 23 May 2006 06:19:35 +0000 Subject: r15833: fixed two delete on close memory leaks (This used to be commit f3274e8f78f28a51313e98934b208c2deb9ae9ea) --- source4/ntvfs/posix/pvfs_open.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index fd382ba1d9..2102de29f5 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -58,7 +58,7 @@ static int pvfs_dir_handle_destructor(void *p) { struct pvfs_file_handle *h = p; int open_count; - char *path; + char *path = NULL; if (h->name->stream_name == NULL && pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && @@ -75,6 +75,8 @@ static int pvfs_dir_handle_destructor(void *p) } } + talloc_free(path); + if (h->have_opendb_entry) { struct odb_lock *lck; NTSTATUS status; @@ -414,7 +416,7 @@ static int pvfs_handle_destructor(void *p) { struct pvfs_file_handle *h = p; int open_count; - char *path; + char *path = NULL; /* the write time is no longer sticky */ if (h->sticky_write_time) { @@ -464,6 +466,8 @@ static int pvfs_handle_destructor(void *p) } } + talloc_free(path); + if (h->have_opendb_entry) { struct odb_lock *lck; NTSTATUS status; -- cgit From 971d30bb201f5c3faff5f575d26882eb79f7955a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:34:11 +0000 Subject: r15854: more talloc_set_destructor() typesafe fixes (This used to be commit 61c6100617589ac6df4f527877241464cacbf8b3) --- source4/ntvfs/cifs/vfs_cifs.c | 3 +-- source4/ntvfs/common/notify.c | 3 +-- source4/ntvfs/common/opendb.c | 3 +-- source4/ntvfs/ipc/vfs_ipc.c | 3 +-- source4/ntvfs/posix/pvfs_dirlist.c | 3 +-- source4/ntvfs/posix/pvfs_notify.c | 3 +-- source4/ntvfs/posix/pvfs_open.c | 17 +++++------------ 7 files changed, 11 insertions(+), 24 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2b4f9bb8c5..47b89ff662 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -237,9 +237,8 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) /* destroy an async info structure */ -static int async_info_destructor(void *p) +static int async_info_destructor(struct async_info *async) { - struct async_info *async = talloc_get_type(p, struct async_info); DLIST_REMOVE(async->cvfs->pending, async); return 0; } diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 57cbce3863..222bd7a927 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -63,9 +63,8 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private, /* destroy the notify context */ -static int notify_destructor(void *p) +static int notify_destructor(struct notify_context *notify) { - struct notify_context *notify = talloc_get_type(p, struct notify_context); messaging_deregister(notify->messaging_ctx, MSG_PVFS_NOTIFY, notify); notify_remove_all(notify); return 0; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 395e6c6dbf..d83ecdc6f2 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -100,9 +100,8 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, /* destroy a lock on the database */ -static int odb_lock_destructor(void *ptr) +static int odb_lock_destructor(struct odb_lock *lck) { - struct odb_lock *lck = ptr; tdb_chainunlock(lck->odb->w->tdb, lck->key); return 0; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 2e7c538c3f..03e026e423 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -174,9 +174,8 @@ static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs, /* destroy a open pipe structure */ -static int ipc_fd_destructor(void *ptr) +static int ipc_fd_destructor(struct pipe_state *p) { - struct pipe_state *p = ptr; DLIST_REMOVE(p->private->pipe_list, p); return 0; } diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 517f5b68d0..c351f6ba41 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -84,9 +84,8 @@ static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filen /* destroy an open search */ -static int pvfs_dirlist_destructor(void *ptr) +static int pvfs_dirlist_destructor(struct pvfs_dir *dir) { - struct pvfs_dir *dir = ptr; if (dir->dir) closedir(dir->dir); return 0; } diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index bd1e1b9d89..64aeac0696 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -117,9 +117,8 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, /* destroy a notify buffer. Called when the handle is closed */ -static int pvfs_notify_destructor(void *ptr) +static int pvfs_notify_destructor(struct pvfs_notify_buffer *n) { - struct pvfs_notify_buffer *n = talloc_get_type(ptr, struct pvfs_notify_buffer); notify_remove(n->f->pvfs->notify_context, n); n->f->notify_buffer = NULL; pvfs_notify_send(n, NT_STATUS_OK, True); diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 2102de29f5..74f9b44c5c 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -54,9 +54,8 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, /* cleanup a open directory handle */ -static int pvfs_dir_handle_destructor(void *p) +static int pvfs_dir_handle_destructor(struct pvfs_file_handle *h) { - struct pvfs_file_handle *h = p; int open_count; char *path = NULL; @@ -102,10 +101,8 @@ static int pvfs_dir_handle_destructor(void *p) /* cleanup a open directory fnum */ -static int pvfs_dir_fnum_destructor(void *p) +static int pvfs_dir_fnum_destructor(struct pvfs_file *f) { - struct pvfs_file *f = p; - DLIST_REMOVE(f->pvfs->files.list, f); ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs); @@ -412,9 +409,8 @@ cleanup_delete: /* destroy a struct pvfs_file_handle */ -static int pvfs_handle_destructor(void *p) +static int pvfs_handle_destructor(struct pvfs_file_handle *h) { - struct pvfs_file_handle *h = p; int open_count; char *path = NULL; @@ -494,10 +490,8 @@ static int pvfs_handle_destructor(void *p) /* destroy a struct pvfs_file */ -static int pvfs_fnum_destructor(void *p) +static int pvfs_fnum_destructor(struct pvfs_file *f) { - struct pvfs_file *f = talloc_get_type(p, struct pvfs_file); - DLIST_REMOVE(f->pvfs->files.list, f); pvfs_lock_close(f->pvfs, f); ntvfs_handle_remove_backend_data(f->ntvfs, f->pvfs->ntvfs); @@ -768,9 +762,8 @@ struct pvfs_open_retry { }; /* destroy a pending open request */ -static int pvfs_retry_destructor(void *ptr) +static int pvfs_retry_destructor(struct pvfs_open_retry *r) { - struct pvfs_open_retry *r = ptr; struct pvfs_state *pvfs = r->ntvfs->private_data; if (r->odb_locking_key.data) { struct odb_lock *lck; -- cgit From 92acfc07998da1546182579ad12a063f025c9286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2006 07:35:06 +0000 Subject: r15855: more talloc_set_destructor() typesafe fixes. nearly done ... (This used to be commit 396d82a231b6e3a91178db08b706626d4d4b420c) --- source4/ntvfs/posix/pvfs_search.c | 3 +-- source4/ntvfs/posix/pvfs_wait.c | 3 +-- source4/ntvfs/posix/vfs_posix.c | 3 +-- source4/ntvfs/sysdep/inotify.c | 6 ++---- 4 files changed, 5 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 32bef1ae53..4d218fbe9c 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -35,9 +35,8 @@ /* destroy an open search */ -static int pvfs_search_destructor(void *ptr) +static int pvfs_search_destructor(struct pvfs_search_state *search) { - struct pvfs_search_state *search = ptr; DLIST_REMOVE(search->pvfs->search.list, search); idr_remove(search->pvfs->search.idtree, search->handle); return 0; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 5750c0fe08..90c9b60efe 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -102,9 +102,8 @@ static void pvfs_wait_timeout(struct event_context *ev, /* destroy a pending wait */ -static int pvfs_wait_destructor(void *ptr) +static int pvfs_wait_destructor(struct pvfs_wait *pwait) { - struct pvfs_wait *pwait = ptr; if (pwait->msg_type != -1) { messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait); } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 1682a94ac9..e7ef9bafd8 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -104,9 +104,8 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) } } -static int pvfs_state_destructor(void *ptr) +static int pvfs_state_destructor(struct pvfs_state *pvfs) { - struct pvfs_state *pvfs = talloc_get_type(ptr, struct pvfs_state); struct pvfs_file *f, *fn; struct pvfs_search_state *s, *sn; diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 33c4ff4928..5348006543 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -82,9 +82,8 @@ struct watch_context { /* destroy the inotify private context */ -static int inotify_destructor(void *ptr) +static int inotify_destructor(struct inotify_private *in) { - struct inotify_private *in = talloc_get_type(ptr, struct inotify_private); close(in->fd); return 0; } @@ -308,9 +307,8 @@ static uint32_t inotify_map(struct notify_entry *e) /* destroy a watch */ -static int watch_destructor(void *ptr) +static int watch_destructor(struct watch_context *w) { - struct watch_context *w = talloc_get_type(ptr, struct watch_context); struct inotify_private *in = w->in; int wd = w->wd; DLIST_REMOVE(w->in->watches, w); -- cgit From f719eb9598d4d82d5fec2d13b67f7a5b2e86e4df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 25 May 2006 04:46:38 +0000 Subject: r15880: the ntvfs_handle changes broke rpc on big-endian boxes, as the uint16_t fnum was being byte order converted twice in the ipc server. Metze, can you have a look at this? This change does make rpc work again, but perhaps you might like to approach it differently (This used to be commit 50246e6282087fdf7050ea052ad516dc620d6c7e) --- source4/ntvfs/ipc/vfs_ipc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 03e026e423..31233968e7 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -658,9 +658,11 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, struct ipc_private *private = ntvfs->private_data; NTSTATUS status; DATA_BLOB fnum_key; + uint16_t fnum; - /* the fnum is in setup[1] */ - fnum_key = data_blob_const(&trans->in.setup[1], sizeof(trans->in.setup[1])); + /* the fnum is in setup[1], a 16 bit value */ + SSVAL(&fnum, 0, trans->in.setup[1]); + fnum_key = data_blob_const(&fnum, 2); p = pipe_state_find_key(private, req, &fnum_key); if (!p) { -- cgit From b0bcd8a2010c8426f45a3d3c1f9911754f9e2936 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 30 May 2006 20:23:55 +0000 Subject: r15970: add a more verbose comment to tridge's fix for bigendian hosts. tridge: I'm fine with this fix metze (This used to be commit f38b042ded6ec9b243c15d7710261708f208d289) --- source4/ntvfs/ipc/vfs_ipc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 31233968e7..e93e32f4e4 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -660,7 +660,12 @@ static NTSTATUS ipc_dcerpc_cmd(struct ntvfs_module_context *ntvfs, DATA_BLOB fnum_key; uint16_t fnum; - /* the fnum is in setup[1], a 16 bit value */ + /* + * the fnum is in setup[1], a 16 bit value + * the setup[*] values are already in host byteorder + * but ntvfs_handle_search_by_wire_key() expects + * network byteorder + */ SSVAL(&fnum, 0, trans->in.setup[1]); fnum_key = data_blob_const(&fnum, 2); -- cgit From f6a3c29ede4482bdad7362bc990fe567c5714163 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Jun 2006 14:06:30 +0000 Subject: r16004: - move #ifdef outof the real functions - hopefully all build-farm hosts have ENOTSUP... metze (This used to be commit 62c64f1ddc71436aab6a2f3f2ecc3e6dcb752db9) --- source4/ntvfs/posix/xattr_system.c | 51 +++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 4101b69ed7..757ccefe11 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -23,6 +23,45 @@ #include "includes.h" #include "vfs_posix.h" +#if !defined(HAVE_XATTR_SUPPORT) +static ssize_t _none_fgetxattr(int fd, const char *name, void *value, size_t size) +{ + errno = ENOTSUP; + return -1; +} +static ssize_t _none_getxattr(const char *path, const char *name, void *value, size_t size) +{ + errno = ENOTSUP; + return -1; +} +static ssize_t _none_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) +{ + errno = ENOTSUP; + return -1; +} +static ssize_t _none_setxattr(const char *path, const char *name, void *value, size_t size, int flags) +{ + errno = ENOTSUP; + return -1; +} +static ssize_t _none_fremovexattr(int fd, const char *name) +{ + errno = ENOTSUP; + return -1; +} +static ssize_t _none_removexattr(const char *path, const char *name) +{ + errno = ENOTSUP; + return -1; +} +#define fgetxattr _none_fgetxattr +#define getxattr _none_getxattr +#define fsetxattr _none_fsetxattr +#define setxattr _none_setxattr +#define fremovexattr _none_fremovexattr +#define removexattr _none_removexattr +#endif + /* pull a xattr as a blob, from either a file or a file descriptor */ @@ -34,7 +73,6 @@ NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs, size_t estimated_size, DATA_BLOB *blob) { -#if HAVE_XATTR_SUPPORT int ret; *blob = data_blob_talloc(mem_ctx, NULL, estimated_size+16); @@ -67,9 +105,6 @@ again: blob->length = ret; return NT_STATUS_OK; -#else - return NT_STATUS_NOT_SUPPORTED; -#endif } /* @@ -81,7 +116,6 @@ NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs, int fd, const DATA_BLOB *blob) { -#if HAVE_XATTR_SUPPORT int ret; if (fd != -1) { @@ -94,9 +128,6 @@ NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs, } return NT_STATUS_OK; -#else - return NT_STATUS_NOT_SUPPORTED; -#endif } @@ -106,7 +137,6 @@ NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs, NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name, const char *fname, int fd) { -#if HAVE_XATTR_SUPPORT int ret; if (fd != -1) { @@ -119,9 +149,6 @@ NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name, } return NT_STATUS_OK; -#else - return NT_STATUS_NOT_SUPPORTED; -#endif } /* -- cgit From 8f553ab4a1e5f2affb614c0824d4d77291343861 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Jun 2006 14:22:56 +0000 Subject: r16005: add support for XATTR's on MacOS Thanks to Bjoern Jacke for his help. metze (This used to be commit 8f8480e453ced38cbf27d0a1a45843c5eb126016) --- source4/ntvfs/posix/config.m4 | 17 +++++++++++++++++ source4/ntvfs/posix/xattr_system.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 8d8b07810c..3ae424a4bf 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -29,6 +29,23 @@ AC_SEARCH_LIBS_EXT(flistxattr, [attr], XATTR_LIBS) AC_CHECK_FUNC_EXT(flistxattr, $XATTR_LIBS) SMB_EXT_LIB(XATTR,[${XATTR_LIBS}],[${XATTR_CFLAGS}],[${XATTR_CPPFLAGS}],[${XATTR_LDFLAGS}]) if test x"$ac_cv_func_ext_flistxattr" = x"yes"; then + AC_CACHE_CHECK([whether xattr interface takes additional options], smb_attr_cv_xattr_add_opt, + [old_LIBS=$LIBS + LIBS="$LIBS $XATTRLIBS" + AC_TRY_COMPILE([ + #include + #if HAVE_ATTR_XATTR_H + #include + #elif HAVE_SYS_XATTR_H + #include + #endif + ],[ + getxattr(NULL, NULL, NULL, 0, 0, 0); + ],smb_attr_cv_xattr_add_opt=yes,smb_attr_cv_xattr_add_opt=no) + LIBS=$old_LIBS)]) + if test x"$smb_attr_cv_xattr_add_opt" = x"yes"; then + AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [xattr functions have additional options]) + fi AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) SMB_ENABLE(XATTR,YES) fi diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 757ccefe11..58edf47bfc 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -23,7 +23,38 @@ #include "includes.h" #include "vfs_posix.h" -#if !defined(HAVE_XATTR_SUPPORT) +#if defined(HAVE_XATTR_SUPPORT) && defined(XATTR_ADDITIONAL_OPTIONS) +static ssize_t _wrap_fgetxattr(int fd, const char *name, void *value, size_t size) +{ + return fgetxattr(fd, name, value, size, 0, 0); +} +static ssize_t _wrap_getxattr(const char *path, const char *name, void *value, size_t size) +{ + return getxattr(path, name, value, size, 0, 0); +} +static ssize_t _wrap_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) +{ + return fsetxattr(fd, name, value, size, 0, flags); +} +static ssize_t _wrap_setxattr(const char *path, const char *name, void *value, size_t size, int flags) +{ + return setxattr(path, name, value, size, 0, flags); +} +static ssize_t _wrap_fremovexattr(int fd, const char *name) +{ + return fremovexattr(fd, name, 0); +} +static ssize_t _wrap_removexattr(const char *path, const char *name) +{ + return removexattr(path, name, 0); +} +#define fgetxattr _wrap_fgetxattr +#define getxattr _wrap_getxattr +#define fsetxattr _wrap_fsetxattr +#define setxattr _wrap_setxattr +#define fremovexattr _wrap_fremovexattr +#define removexattr _wrap_removexattr +#elif !defined(HAVE_XATTR_SUPPORT) static ssize_t _none_fgetxattr(int fd, const char *name, void *value, size_t size) { errno = ENOTSUP; -- cgit From 9a9a99b90a086af0ec67a46932c0b2322e716cea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Jun 2006 14:26:15 +0000 Subject: r16006: only (f)getxattr returns ssize_t metze (This used to be commit d4af8da7c9b4c510ceb1ef96f6ff4bbf717a16d9) --- source4/ntvfs/posix/xattr_system.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 58edf47bfc..81bac6caec 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -32,19 +32,19 @@ static ssize_t _wrap_getxattr(const char *path, const char *name, void *value, s { return getxattr(path, name, value, size, 0, 0); } -static ssize_t _wrap_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) +static int _wrap_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) { return fsetxattr(fd, name, value, size, 0, flags); } -static ssize_t _wrap_setxattr(const char *path, const char *name, void *value, size_t size, int flags) +static int _wrap_setxattr(const char *path, const char *name, void *value, size_t size, int flags) { return setxattr(path, name, value, size, 0, flags); } -static ssize_t _wrap_fremovexattr(int fd, const char *name) +static int _wrap_fremovexattr(int fd, const char *name) { return fremovexattr(fd, name, 0); } -static ssize_t _wrap_removexattr(const char *path, const char *name) +static int _wrap_removexattr(const char *path, const char *name) { return removexattr(path, name, 0); } @@ -65,22 +65,22 @@ static ssize_t _none_getxattr(const char *path, const char *name, void *value, s errno = ENOTSUP; return -1; } -static ssize_t _none_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) +static int _none_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) { errno = ENOTSUP; return -1; } -static ssize_t _none_setxattr(const char *path, const char *name, void *value, size_t size, int flags) +static int _none_setxattr(const char *path, const char *name, void *value, size_t size, int flags) { errno = ENOTSUP; return -1; } -static ssize_t _none_fremovexattr(int fd, const char *name) +static int _none_fremovexattr(int fd, const char *name) { errno = ENOTSUP; return -1; } -static ssize_t _none_removexattr(const char *path, const char *name) +static int _none_removexattr(const char *path, const char *name) { errno = ENOTSUP; return -1; -- cgit From 22367ca76eaa2e84cee81fdbb005486ec857e64d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Jun 2006 14:38:50 +0000 Subject: r16008: make debugging easier, and use the os name in the function name (I'll add a bsd wrapping later) metze (This used to be commit 2ce4a2da29dd18b92580014cc765c0f950fb74df) --- source4/ntvfs/posix/xattr_system.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 81bac6caec..11d8df2933 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -24,36 +24,36 @@ #include "vfs_posix.h" #if defined(HAVE_XATTR_SUPPORT) && defined(XATTR_ADDITIONAL_OPTIONS) -static ssize_t _wrap_fgetxattr(int fd, const char *name, void *value, size_t size) +static ssize_t _wrap_darwin_fgetxattr(int fd, const char *name, void *value, size_t size) { return fgetxattr(fd, name, value, size, 0, 0); } -static ssize_t _wrap_getxattr(const char *path, const char *name, void *value, size_t size) +static ssize_t _wrap_darwin_getxattr(const char *path, const char *name, void *value, size_t size) { return getxattr(path, name, value, size, 0, 0); } -static int _wrap_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) +static int _wrap_darwin_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) { return fsetxattr(fd, name, value, size, 0, flags); } -static int _wrap_setxattr(const char *path, const char *name, void *value, size_t size, int flags) +static int _wrap_darwin_setxattr(const char *path, const char *name, void *value, size_t size, int flags) { return setxattr(path, name, value, size, 0, flags); } -static int _wrap_fremovexattr(int fd, const char *name) +static int _wrap_darwin_fremovexattr(int fd, const char *name) { return fremovexattr(fd, name, 0); } -static int _wrap_removexattr(const char *path, const char *name) +static int _wrap_darwin_removexattr(const char *path, const char *name) { return removexattr(path, name, 0); } -#define fgetxattr _wrap_fgetxattr -#define getxattr _wrap_getxattr -#define fsetxattr _wrap_fsetxattr -#define setxattr _wrap_setxattr -#define fremovexattr _wrap_fremovexattr -#define removexattr _wrap_removexattr +#define fgetxattr _wrap_darwin_fgetxattr +#define getxattr _wrap_darwin_getxattr +#define fsetxattr _wrap_darwin_fsetxattr +#define setxattr _wrap_darwin_setxattr +#define fremovexattr _wrap_darwin_fremovexattr +#define removexattr _wrap_darwin_removexattr #elif !defined(HAVE_XATTR_SUPPORT) static ssize_t _none_fgetxattr(int fd, const char *name, void *value, size_t size) { -- cgit From b20d76085bdc2680c5890c0126f2955cf3807e5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Jun 2006 14:57:18 +0000 Subject: r16009: fix the build metze (This used to be commit d53562f126c374ff93f368cb2e8a247762b3395b) --- source4/ntvfs/posix/config.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index 3ae424a4bf..a90b7af982 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -42,7 +42,7 @@ if test x"$ac_cv_func_ext_flistxattr" = x"yes"; then ],[ getxattr(NULL, NULL, NULL, 0, 0, 0); ],smb_attr_cv_xattr_add_opt=yes,smb_attr_cv_xattr_add_opt=no) - LIBS=$old_LIBS)]) + LIBS=$old_LIBS]) if test x"$smb_attr_cv_xattr_add_opt" = x"yes"; then AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [xattr functions have additional options]) fi -- cgit From 18cc835e8af99a9c10e5f9b5562bac2f8f0d74b4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 2 Jun 2006 21:10:19 +0000 Subject: r16013: hopefully fix the configure check for darwin metze (This used to be commit 88b7d4206407aba74f3f6d56a8c88ef847731b12) --- source4/ntvfs/posix/config.m4 | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index a90b7af982..fb4362f755 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -39,6 +39,9 @@ if test x"$ac_cv_func_ext_flistxattr" = x"yes"; then #elif HAVE_SYS_XATTR_H #include #endif + #ifndef NULL + #define NULL ((void *)0) + #endif ],[ getxattr(NULL, NULL, NULL, 0, 0, 0); ],smb_attr_cv_xattr_add_opt=yes,smb_attr_cv_xattr_add_opt=no) -- cgit From dc4ccc6f6575bc98f17eccebd7e058eedaff02aa Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 3 Jun 2006 09:38:22 +0000 Subject: r16024: OpenBSD doesn't have ENOTSUP so use ENOSYS metze (This used to be commit 505d55de69e1c5a9e763534dd392caac79e49ff1) --- source4/ntvfs/posix/pvfs_xattr.c | 6 ++++-- source4/ntvfs/posix/xattr_system.c | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 09f1c9fdc8..e5b4fdaa90 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -47,8 +47,10 @@ static NTSTATUS pull_xattr_blob(struct pvfs_state *pvfs, fd, estimated_size, blob); /* if the filesystem doesn't support them, then tell pvfs not to try again */ - if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { - DEBUG(5,("pvfs_xattr: xattr not supported in filesystem\n")); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)|| + NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)|| + NT_STATUS_EQUAL(status, NT_STATUS_INVALID_SYSTEM_SERVICE)) { + DEBUG(5,("pvfs_xattr: xattr not supported in filesystem: %s\n", nt_errstr(status))); pvfs->flags &= ~PVFS_FLAG_XATTR_ENABLE; status = NT_STATUS_NOT_FOUND; } diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 11d8df2933..958f57e0fd 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -57,32 +57,32 @@ static int _wrap_darwin_removexattr(const char *path, const char *name) #elif !defined(HAVE_XATTR_SUPPORT) static ssize_t _none_fgetxattr(int fd, const char *name, void *value, size_t size) { - errno = ENOTSUP; + errno = ENOSYS; return -1; } static ssize_t _none_getxattr(const char *path, const char *name, void *value, size_t size) { - errno = ENOTSUP; + errno = ENOSYS; return -1; } static int _none_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) { - errno = ENOTSUP; + errno = ENOSYS; return -1; } static int _none_setxattr(const char *path, const char *name, void *value, size_t size, int flags) { - errno = ENOTSUP; + errno = ENOSYS; return -1; } static int _none_fremovexattr(int fd, const char *name) { - errno = ENOTSUP; + errno = ENOSYS; return -1; } static int _none_removexattr(const char *path, const char *name) { - errno = ENOTSUP; + errno = ENOSYS; return -1; } #define fgetxattr _none_fgetxattr -- cgit From ca62ddd8d901cce923d1cda958793054f80b1f57 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jun 2006 21:48:29 +0000 Subject: r16051: Move the XATTR compatability code into a new file, so I can use it for the getntacl utility. Andrew Bartlett (This used to be commit b1e0d4747b412929e1d4e24d6d9e504df3ddc824) --- source4/ntvfs/posix/config.m4 | 32 --------------- source4/ntvfs/posix/config.mk | 2 +- source4/ntvfs/posix/xattr_system.c | 83 ++++---------------------------------- 3 files changed, 8 insertions(+), 109 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index fb4362f755..c2cdf0ecaf 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -21,38 +21,6 @@ if test x"$ac_cv_decl_have_stat_tv_nsec" = x"yes"; then AC_DEFINE(HAVE_STAT_TV_NSEC,1,[Whether stat has tv_nsec nanosecond fields]) fi -dnl ############################################ -dnl use flistxattr as the key function for having -dnl sufficient xattr support for posix xattr backend -AC_CHECK_HEADERS(sys/attributes.h attr/xattr.h sys/xattr.h) -AC_SEARCH_LIBS_EXT(flistxattr, [attr], XATTR_LIBS) -AC_CHECK_FUNC_EXT(flistxattr, $XATTR_LIBS) -SMB_EXT_LIB(XATTR,[${XATTR_LIBS}],[${XATTR_CFLAGS}],[${XATTR_CPPFLAGS}],[${XATTR_LDFLAGS}]) -if test x"$ac_cv_func_ext_flistxattr" = x"yes"; then - AC_CACHE_CHECK([whether xattr interface takes additional options], smb_attr_cv_xattr_add_opt, - [old_LIBS=$LIBS - LIBS="$LIBS $XATTRLIBS" - AC_TRY_COMPILE([ - #include - #if HAVE_ATTR_XATTR_H - #include - #elif HAVE_SYS_XATTR_H - #include - #endif - #ifndef NULL - #define NULL ((void *)0) - #endif - ],[ - getxattr(NULL, NULL, NULL, 0, 0, 0); - ],smb_attr_cv_xattr_add_opt=yes,smb_attr_cv_xattr_add_opt=no) - LIBS=$old_LIBS]) - if test x"$smb_attr_cv_xattr_add_opt" = x"yes"; then - AC_DEFINE(XATTR_ADDITIONAL_OPTIONS, 1, [xattr functions have additional options]) - fi - AC_DEFINE(HAVE_XATTR_SUPPORT,1,[Whether we have xattr support]) - SMB_ENABLE(XATTR,YES) -fi - AC_CHECK_HEADERS(blkid/blkid.h) AC_SEARCH_LIBS_EXT(blkid_get_cache, [blkid], BLKID_LIBS) AC_CHECK_FUNC_EXT(blkid_get_cache, $BLKID_LIBS) diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index dde49a5531..2835fc4575 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -32,6 +32,6 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o -PUBLIC_DEPENDENCIES = NDR_XATTR XATTR BLKID ntvfs_common MESSAGING +PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 958f57e0fd..9dca13e5c2 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -22,76 +22,7 @@ #include "includes.h" #include "vfs_posix.h" - -#if defined(HAVE_XATTR_SUPPORT) && defined(XATTR_ADDITIONAL_OPTIONS) -static ssize_t _wrap_darwin_fgetxattr(int fd, const char *name, void *value, size_t size) -{ - return fgetxattr(fd, name, value, size, 0, 0); -} -static ssize_t _wrap_darwin_getxattr(const char *path, const char *name, void *value, size_t size) -{ - return getxattr(path, name, value, size, 0, 0); -} -static int _wrap_darwin_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) -{ - return fsetxattr(fd, name, value, size, 0, flags); -} -static int _wrap_darwin_setxattr(const char *path, const char *name, void *value, size_t size, int flags) -{ - return setxattr(path, name, value, size, 0, flags); -} -static int _wrap_darwin_fremovexattr(int fd, const char *name) -{ - return fremovexattr(fd, name, 0); -} -static int _wrap_darwin_removexattr(const char *path, const char *name) -{ - return removexattr(path, name, 0); -} -#define fgetxattr _wrap_darwin_fgetxattr -#define getxattr _wrap_darwin_getxattr -#define fsetxattr _wrap_darwin_fsetxattr -#define setxattr _wrap_darwin_setxattr -#define fremovexattr _wrap_darwin_fremovexattr -#define removexattr _wrap_darwin_removexattr -#elif !defined(HAVE_XATTR_SUPPORT) -static ssize_t _none_fgetxattr(int fd, const char *name, void *value, size_t size) -{ - errno = ENOSYS; - return -1; -} -static ssize_t _none_getxattr(const char *path, const char *name, void *value, size_t size) -{ - errno = ENOSYS; - return -1; -} -static int _none_fsetxattr(int fd, const char *name, void *value, size_t size, int flags) -{ - errno = ENOSYS; - return -1; -} -static int _none_setxattr(const char *path, const char *name, void *value, size_t size, int flags) -{ - errno = ENOSYS; - return -1; -} -static int _none_fremovexattr(int fd, const char *name) -{ - errno = ENOSYS; - return -1; -} -static int _none_removexattr(const char *path, const char *name) -{ - errno = ENOSYS; - return -1; -} -#define fgetxattr _none_fgetxattr -#define getxattr _none_getxattr -#define fsetxattr _none_fsetxattr -#define setxattr _none_setxattr -#define fremovexattr _none_fremovexattr -#define removexattr _none_removexattr -#endif +#include "lib/util/wrap_xattr.h" /* pull a xattr as a blob, from either a file or a file descriptor @@ -113,9 +44,9 @@ NTSTATUS pull_xattr_blob_system(struct pvfs_state *pvfs, again: if (fd != -1) { - ret = fgetxattr(fd, attr_name, blob->data, estimated_size); + ret = wrap_fgetxattr(fd, attr_name, blob->data, estimated_size); } else { - ret = getxattr(fname, attr_name, blob->data, estimated_size); + ret = wrap_getxattr(fname, attr_name, blob->data, estimated_size); } if (ret == -1 && errno == ERANGE) { estimated_size *= 2; @@ -150,9 +81,9 @@ NTSTATUS push_xattr_blob_system(struct pvfs_state *pvfs, int ret; if (fd != -1) { - ret = fsetxattr(fd, attr_name, blob->data, blob->length, 0); + ret = wrap_fsetxattr(fd, attr_name, blob->data, blob->length, 0); } else { - ret = setxattr(fname, attr_name, blob->data, blob->length, 0); + ret = wrap_setxattr(fname, attr_name, blob->data, blob->length, 0); } if (ret == -1) { return pvfs_map_errno(pvfs, errno); @@ -171,9 +102,9 @@ NTSTATUS delete_xattr_system(struct pvfs_state *pvfs, const char *attr_name, int ret; if (fd != -1) { - ret = fremovexattr(fd, attr_name); + ret = wrap_fremovexattr(fd, attr_name); } else { - ret = removexattr(fname, attr_name); + ret = wrap_removexattr(fname, attr_name); } if (ret == -1) { return pvfs_map_errno(pvfs, errno); -- cgit From 7743106635b4720385aebba75c13598276ceeedb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Jun 2006 17:36:06 +0000 Subject: r16468: implement SMB2_ALL_INFORMATION in the posix backend metze (This used to be commit 1bce493cbc003db37e9ea94c20019990e1eb785a) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 41 +++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 2d43c5a582..c805a4a555 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -196,7 +196,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, info->standard_info.out.alloc_size = name->dos.alloc_size; info->standard_info.out.size = name->st.st_size; info->standard_info.out.nlink = name->dos.nlink; - info->standard_info.out.delete_pending = 0; + info->standard_info.out.delete_pending = 0; /* only for qfileinfo */ info->standard_info.out.directory = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; return NT_STATUS_OK; @@ -221,7 +221,7 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, info->all_info.out.alloc_size = name->dos.alloc_size; info->all_info.out.size = name->st.st_size; info->all_info.out.nlink = name->dos.nlink; - info->all_info.out.delete_pending = 0; + info->all_info.out.delete_pending = 0; /* only set by qfileinfo */ info->all_info.out.directory = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; info->all_info.out.ea_size = name->dos.ea_size; @@ -251,15 +251,15 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, return NT_STATUS_OK; case RAW_FILEINFO_ACCESS_INFORMATION: - info->access_information.out.access_flags = 0; + info->access_information.out.access_flags = 0; /* only set by qfileinfo */ return NT_STATUS_OK; case RAW_FILEINFO_POSITION_INFORMATION: - info->position_information.out.position = 0; + info->position_information.out.position = 0; /* only set by qfileinfo */ return NT_STATUS_OK; case RAW_FILEINFO_MODE_INFORMATION: - info->mode_information.out.mode = 0; + info->mode_information.out.mode = 0; /* only set by qfileinfo */ return NT_STATUS_OK; case RAW_FILEINFO_ALIGNMENT_INFORMATION: @@ -283,6 +283,27 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, case RAW_FILEINFO_SEC_DESC: return pvfs_acl_query(pvfs, req, name, fd, info); + + case RAW_FILEINFO_SMB2_ALL_INFORMATION: + info->all_info2.out.create_time = name->dos.create_time; + info->all_info2.out.access_time = name->dos.access_time; + info->all_info2.out.write_time = name->dos.write_time; + info->all_info2.out.change_time = name->dos.change_time; + info->all_info2.out.attrib = name->dos.attrib; + info->all_info2.out.unknown1 = 0; + info->all_info2.out.alloc_size = name->dos.alloc_size; + info->all_info2.out.size = name->st.st_size; + info->all_info2.out.nlink = name->dos.nlink; + info->all_info2.out.delete_pending = 0; /* only set by qfileinfo */ + info->all_info2.out.directory = + (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; + info->all_info2.out.file_id = name->dos.file_id; + info->all_info2.out.ea_size = name->dos.ea_size; + info->all_info2.out.access_mask = 0; /* only set by qfileinfo */ + info->all_info2.out.position = 0; /* only set by qfileinfo */ + info->all_info2.out.mode = 0; /* only set by qfileinfo */ + info->all_info2.out.fname.s = name->original_name; + return NT_STATUS_OK; } return NT_STATUS_INVALID_LEVEL; @@ -386,6 +407,16 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, info->mode_information.out.mode = h->mode; break; + case RAW_FILEINFO_SMB2_ALL_INFORMATION: + if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { + info->all_info.out.delete_pending = 1; + info->all_info.out.nlink--; + } + info->all_info2.out.position = h->position; + info->all_info2.out.access_mask = f->access_mask; + info->all_info2.out.mode = h->mode; + break; + default: break; } -- cgit From d63dd113ae2c7f4f6d64def00a488548e805bc7e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Jun 2006 22:16:58 +0000 Subject: r16699: the layout of SMB2 Read and Write is identical... so we know that the 9th bytes is just uninitialized padding metze (This used to be commit f97a21b970ed23973cced2c67b5bc9ecd7afee88) --- source4/ntvfs/ntvfs_generic.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 3283ee673d..5987ff4ba6 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1064,7 +1064,6 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, wr->smb2.out._pad = 0; wr->smb2.out.nwritten = wr2->generic.out.nwritten; wr->smb2.out.unknown1 = 0; - wr->smb2.out._bug = 0; break; default: -- cgit From ef4475adc4b8da0e3acfe6d70b2afa94a1e500cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Jun 2006 08:16:59 +0000 Subject: r16706: for RAW_SFILEINFO_SETATTR attrib == 0 means set it to FILE_ATTRIB_NORMAL and attrib == FILE_ATTRIB_NORMAL means no change... but for RAW_SFILEINFO_BASIC_INFORMATION attrib == 0 means no change metze (This used to be commit e1945feda09a56b6f55bd0f7ab591f3bd069be67) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 2665b9e5f5..6c7c6dc6f7 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -493,7 +493,9 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, if (!null_time(info->setattr.in.write_time)) { unix_to_nt_time(&newstats.dos.write_time, info->setattr.in.write_time); } - if (info->setattr.in.attrib != FILE_ATTRIBUTE_NORMAL) { + if (info->setattr.in.attrib == 0) { + newstats.dos.attrib = FILE_ATTRIBUTE_NORMAL; + } else if (info->setattr.in.attrib != FILE_ATTRIBUTE_NORMAL) { newstats.dos.attrib = info->setattr.in.attrib; } break; -- cgit From c063450a1e04934f16306f7cc368d007f6ab2dc7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 1 Jul 2006 07:47:49 +0000 Subject: r16724: fix typo... metze (This used to be commit 9b036d788ceb4eeae28531db8aa5e297c775f35a) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index c805a4a555..b76cafb38a 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -409,8 +409,8 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, case RAW_FILEINFO_SMB2_ALL_INFORMATION: if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { - info->all_info.out.delete_pending = 1; - info->all_info.out.nlink--; + info->all_info2.out.delete_pending = 1; + info->all_info2.out.nlink--; } info->all_info2.out.position = h->position; info->all_info2.out.access_mask = f->access_mask; -- cgit From 30ae843cbf9cd57c052941d3e58785ae5c854624 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 1 Jul 2006 14:04:28 +0000 Subject: r16730: that is correct... metze (This used to be commit 9c3992a27948f01803650c446914aa24be2a8d7a) --- source4/ntvfs/ntvfs_generic.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 5987ff4ba6..8c48e52b5c 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -215,8 +215,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, io->smb2.out.change_time = io2->generic.out.change_time; io->smb2.out.alloc_size = io2->generic.out.alloc_size; io->smb2.out.size = io2->generic.out.size; - /*io->smb2.out.file_attr = io2->generic.out.attrib; would this be correct? */ - io->smb2.out.file_attr = 0; + io->smb2.out.file_attr = io2->generic.out.attrib; io->smb2.out._pad = 0; io->smb2.out.blob = data_blob(NULL, 0); break; -- cgit From af0a9eb52955cfae570bfdc01821f56385c860cf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Jul 2006 08:00:24 +0000 Subject: r16834: split the level's of smb_search_first/smb_search_next and the levels of smb_search_data metze (This used to be commit 78c201db8a47a71908698c4dda2add4cf85694d9) --- source4/ntvfs/nbench/vfs_nbench.c | 4 +- source4/ntvfs/posix/pvfs_search.c | 116 +++++++++++++++++++++++++------------- source4/ntvfs/simple/vfs_simple.c | 12 +++- 3 files changed, 90 insertions(+), 42 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index f7834a9751..34cf8d9565 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -819,13 +819,13 @@ static void nbench_search_first_send(struct ntvfs_request *req) union smb_search_first *io = req->async_states->private_data; switch (io->generic.level) { - case RAW_SEARCH_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_TRANS2: if (NT_STATUS_IS_ERR(req->async_states->status)) { ZERO_STRUCT(io->t2ffirst.out); } nbench_log(req, "FIND_FIRST \"%s\" %d %d %d %s\n", io->t2ffirst.in.pattern, - io->generic.level, + io->t2ffirst.data_level, io->t2ffirst.in.max_count, io->t2ffirst.out.count, get_nt_error_c_code(req->async_states->status)); diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 4d218fbe9c..794d223060 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -68,7 +68,7 @@ static void pvfs_search_setup_timer(struct pvfs_search_state *search) fill in a single search result for a given info level */ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, - enum smb_search_level level, + enum smb_search_data_level level, const char *unix_path, const char *fname, struct pvfs_search_state *search, @@ -90,9 +90,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, } switch (level) { - case RAW_SEARCH_SEARCH: - case RAW_SEARCH_FFIRST: - case RAW_SEARCH_FUNIQUE: + case RAW_SEARCH_DATA_SEARCH: shortname = pvfs_short_name(pvfs, name, name); file->search.attrib = name->dos.attrib; file->search.write_time = nt_time_to_unix(name->dos.write_time); @@ -107,7 +105,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->search.id.client_cookie = 0; return NT_STATUS_OK; - case RAW_SEARCH_STANDARD: + case RAW_SEARCH_DATA_STANDARD: file->standard.resume_key = dir_index; file->standard.create_time = nt_time_to_unix(name->dos.create_time); file->standard.access_time = nt_time_to_unix(name->dos.access_time); @@ -118,7 +116,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->standard.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_EA_SIZE: + case RAW_SEARCH_DATA_EA_SIZE: file->ea_size.resume_key = dir_index; file->ea_size.create_time = nt_time_to_unix(name->dos.create_time); file->ea_size.access_time = nt_time_to_unix(name->dos.access_time); @@ -130,7 +128,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->ea_size.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_EA_LIST: + case RAW_SEARCH_DATA_EA_LIST: file->ea_list.resume_key = dir_index; file->ea_list.create_time = nt_time_to_unix(name->dos.create_time); file->ea_list.access_time = nt_time_to_unix(name->dos.access_time); @@ -144,7 +142,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, search->ea_names, &file->ea_list.eas); - case RAW_SEARCH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_DIRECTORY_INFO: file->directory_info.file_index = dir_index; file->directory_info.create_time = name->dos.create_time; file->directory_info.access_time = name->dos.access_time; @@ -156,7 +154,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->directory_info.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: file->full_directory_info.file_index = dir_index; file->full_directory_info.create_time = name->dos.create_time; file->full_directory_info.access_time = name->dos.access_time; @@ -169,12 +167,12 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->full_directory_info.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_NAME_INFO: + case RAW_SEARCH_DATA_NAME_INFO: file->name_info.file_index = dir_index; file->name_info.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: file->both_directory_info.file_index = dir_index; file->both_directory_info.create_time = name->dos.create_time; file->both_directory_info.access_time = name->dos.access_time; @@ -188,7 +186,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->both_directory_info.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_ID_FULL_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: file->id_full_directory_info.file_index = dir_index; file->id_full_directory_info.create_time = name->dos.create_time; file->id_full_directory_info.access_time = name->dos.access_time; @@ -202,7 +200,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->id_full_directory_info.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: + case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: file->id_both_directory_info.file_index = dir_index; file->id_both_directory_info.create_time = name->dos.create_time; file->id_both_directory_info.access_time = name->dos.access_time; @@ -217,7 +215,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, file->id_both_directory_info.name.s = fname; return NT_STATUS_OK; - case RAW_SEARCH_GENERIC: + case RAW_SEARCH_DATA_GENERIC: break; } @@ -231,7 +229,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, uint_t max_count, struct pvfs_search_state *search, - enum smb_search_level level, + enum smb_search_data_level level, uint_t *reply_count, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) @@ -378,7 +376,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, talloc_set_destructor(search, pvfs_search_destructor); - status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.level, + status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.data_level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { return status; @@ -422,7 +420,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, search->last_used = time(NULL); dir = search->dir; - status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, + status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { return status; @@ -441,10 +439,10 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, /* list files in a directory matching a wildcard pattern */ -NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) +static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) { struct pvfs_dir *dir; struct pvfs_state *pvfs = ntvfs->private_data; @@ -456,10 +454,6 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; int id; - if (io->generic.level >= RAW_SEARCH_SEARCH) { - return pvfs_search_first_old(ntvfs, req, io, search_private, callback); - } - search_attrib = io->t2ffirst.in.search_attrib; pattern = io->t2ffirst.in.pattern; max_count = io->t2ffirst.in.max_count; @@ -512,7 +506,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, DLIST_ADD(pvfs->search.list, search); talloc_set_destructor(search, pvfs_search_destructor); - status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level, + status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { return status; @@ -541,10 +535,10 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, } /* continue a search */ -NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_search_next *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) +static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; @@ -553,10 +547,6 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, uint16_t handle; NTSTATUS status; - if (io->generic.level >= RAW_SEARCH_SEARCH) { - return pvfs_search_next_old(ntvfs, req, io, search_private, callback); - } - handle = io->t2fnext.in.handle; search = idr_find(pvfs->search.idtree, handle); @@ -586,7 +576,7 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, search->num_ea_names = io->t2fnext.in.num_names; search->ea_names = io->t2fnext.in.ea_names; - status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.level, + status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.data_level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { return status; @@ -605,18 +595,68 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +/* + list files in a directory matching a wildcard pattern +*/ +NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + switch (io->generic.level) { + case RAW_SEARCH_SEARCH: + case RAW_SEARCH_FFIRST: + case RAW_SEARCH_FUNIQUE: + return pvfs_search_first_old(ntvfs, req, io, search_private, callback); + + case RAW_SEARCH_TRANS2: + return pvfs_search_first_trans2(ntvfs, req, io, search_private, callback); + } + + return NT_STATUS_INVALID_LEVEL; +} + +/* continue a search */ +NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + switch (io->generic.level) { + case RAW_SEARCH_SEARCH: + case RAW_SEARCH_FFIRST: + return pvfs_search_next_old(ntvfs, req, io, search_private, callback); + + case RAW_SEARCH_FUNIQUE: + return NT_STATUS_INVALID_LEVEL; + + case RAW_SEARCH_TRANS2: + return pvfs_search_next_trans2(ntvfs, req, io, search_private, callback); + } + + return NT_STATUS_INVALID_LEVEL; +} + + /* close a search */ NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; - uint16_t handle; + uint16_t handle = 0; - if (io->generic.level == RAW_FINDCLOSE_FCLOSE) { + switch (io->generic.level) { + case RAW_FINDCLOSE_GENERIC: + return NT_STATUS_INVALID_LEVEL; + + case RAW_FINDCLOSE_FCLOSE: handle = io->fclose.in.id.handle; - } else { + break; + + case RAW_FINDCLOSE_FINDCLOSE: handle = io->findclose.in.handle; + break; } search = idr_find(pvfs->search.idtree, handle); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 9e5d4ae922..beffe2b546 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -838,7 +838,11 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, union smb_search_data file; uint_t max_count; - if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { + if (io->generic.level != RAW_SEARCH_TRANS2) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { return NT_STATUS_NOT_SUPPORTED; } @@ -908,7 +912,11 @@ static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, union smb_search_data file; uint_t max_count; - if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { + if (io->generic.level != RAW_SEARCH_TRANS2) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { return NT_STATUS_NOT_SUPPORTED; } -- cgit From 1b45214f3186e3be045d09083c27017e67017cdd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Jul 2006 07:37:05 +0000 Subject: r16868: init some uninitialized values (found by valgrind) metze (This used to be commit 1bb60b5be48fab7d84594283f58d2bc04c474b0c) --- source4/ntvfs/ntvfs_generic.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 8c48e52b5c..e0e69b25e1 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1176,6 +1176,7 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, break; case RAW_READ_SMB2: rd->smb2.out.data.length= rd2->generic.out.nread; + rd->smb2.out.unknown1 = 0; break; default: return NT_STATUS_INVALID_LEVEL; @@ -1307,11 +1308,13 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, case RAW_CLOSE_SPLCLOSE: cl2->generic.level = RAW_CLOSE_CLOSE; cl2->generic.in.file.ntvfs = cl->splclose.in.file.ntvfs; + cl2->generic.in.write_time = 0; break; case RAW_CLOSE_SMB2: cl2->generic.level = RAW_CLOSE_CLOSE; cl2->generic.in.file.ntvfs = cl->smb2.in.file.ntvfs; + cl2->generic.in.write_time = 0; /* SMB2 Close has output parameter, but we just zero them */ ZERO_STRUCT(cl->smb2.out); break; -- cgit From 42248766d410f7a5725b81e20c37c682db847b37 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Jul 2006 12:35:37 +0000 Subject: r16876: implement SMB2 Find in the posix ntvfs backend metze (This used to be commit 4f1afda488f2fb5cfcf98ef6a56157f954fdccfc) --- source4/ntvfs/posix/pvfs_open.c | 3 + source4/ntvfs/posix/pvfs_search.c | 160 ++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/vfs_posix.h | 3 + 3 files changed, 166 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 74f9b44c5c..5482bb3562 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -266,6 +266,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->access_mask = access_mask; f->brl_handle = NULL; f->notify_buffer = NULL; + f->search = NULL; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); @@ -698,6 +699,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->access_mask = access_mask; f->impersonation = io->generic.in.impersonation; f->notify_buffer = NULL; + f->search = NULL; f->handle->pvfs = pvfs; f->handle->name = talloc_steal(f->handle, name); @@ -1126,6 +1128,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->access_mask = access_mask; f->impersonation = io->generic.in.impersonation; f->notify_buffer = NULL; + f->search = NULL; f->handle->pvfs = pvfs; f->handle->fd = -1; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 794d223060..58cc1e04f3 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -58,6 +58,7 @@ static void pvfs_search_timer(struct event_context *ev, struct timed_event *te, static void pvfs_search_setup_timer(struct pvfs_search_state *search) { struct event_context *ev = search->pvfs->ntvfs->ctx->event_ctx; + if (search->handle == -1) return; talloc_free(search->te); search->te = event_add_timed(ev, search, timeval_current_ofs(search->pvfs->search.inactivity_time, 0), @@ -595,6 +596,159 @@ static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } +static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const struct smb2_find *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct pvfs_dir *dir; + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_search_state *search; + uint_t reply_count; + uint16_t max_count; + const char *pattern; + NTSTATUS status; + struct pvfs_filename *name; + struct pvfs_file *f; + + f = pvfs_find_fd(pvfs, req, io->in.file.ntvfs); + if (!f) { + return NT_STATUS_FILE_CLOSED; + } + + /* its only valid for directories */ + if (f->handle->fd != -1) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!(f->access_mask & SEC_DIR_LIST)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (f->search) { + talloc_free(f->search); + f->search = NULL; + } + + if (strequal(io->in.pattern, "")) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + if (strchr_m(io->in.pattern, '\\')) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + if (strchr_m(io->in.pattern, '/')) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + + if (strequal("", f->handle->name->original_name)) { + pattern = talloc_asprintf(req, "\\%s", io->in.pattern); + NT_STATUS_HAVE_NO_MEMORY(pattern); + } else { + pattern = talloc_asprintf(req, "\\%s\\%s", + f->handle->name->original_name, + io->in.pattern); + NT_STATUS_HAVE_NO_MEMORY(pattern); + } + + /* resolve the cifs name to a posix name */ + status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name); + NT_STATUS_NOT_OK_RETURN(status); + + if (!name->has_wildcard && !name->exists) { + return NT_STATUS_NO_SUCH_FILE; + } + + /* we initially make search a child of the request, then if we + need to keep it long term we steal it for the private + structure */ + search = talloc(req, struct pvfs_search_state); + NT_STATUS_HAVE_NO_MEMORY(search); + + /* do the actual directory listing */ + status = pvfs_list_start(pvfs, name, search, &dir); + NT_STATUS_NOT_OK_RETURN(status); + + search->pvfs = pvfs; + search->handle = -1; + search->dir = dir; + search->current_index = 0; + search->search_attrib = 0; + search->must_attrib = 0; + search->last_used = 0; + search->num_ea_names = 0; + search->ea_names = NULL; + search->te = NULL; + + if (io->in.continue_flags & SMB2_CONTINUE_FLAG_SINGLE) { + max_count = 1; + } else { + max_count = UINT16_MAX; + } + + status = pvfs_search_fill(pvfs, req, max_count, search, io->data_level, + &reply_count, search_private, callback); + NT_STATUS_NOT_OK_RETURN(status); + + /* not matching any entries is an error */ + if (reply_count == 0) { + return NT_STATUS_NO_SUCH_FILE; + } + + f->search = talloc_steal(f, search); + + return NT_STATUS_OK; +} + +static NTSTATUS pvfs_search_next_smb2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const struct smb2_find *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_search_state *search; + uint_t reply_count; + uint16_t max_count; + NTSTATUS status; + struct pvfs_file *f; + + f = pvfs_find_fd(pvfs, req, io->in.file.ntvfs); + if (!f) { + return NT_STATUS_FILE_CLOSED; + } + + /* its only valid for directories */ + if (f->handle->fd != -1) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* if there's no search started on the dir handle, it's like a search_first */ + search = f->search; + if (!search) { + return pvfs_search_first_smb2(ntvfs, req, io, search_private, callback); + } + + if (io->in.continue_flags & SMB2_CONTINUE_FLAG_RESTART) { + search->current_index = 0; + } + + if (io->in.continue_flags & SMB2_CONTINUE_FLAG_SINGLE) { + max_count = 1; + } else { + max_count = UINT16_MAX; + } + + status = pvfs_search_fill(pvfs, req, max_count, search, io->data_level, + &reply_count, search_private, callback); + NT_STATUS_NOT_OK_RETURN(status); + + /* not matching any entries is an error */ + if (reply_count == 0) { + return STATUS_NO_MORE_FILES; + } + + return NT_STATUS_OK; +} + /* list files in a directory matching a wildcard pattern */ @@ -611,6 +765,9 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, case RAW_SEARCH_TRANS2: return pvfs_search_first_trans2(ntvfs, req, io, search_private, callback); + + case RAW_SEARCH_SMB2: + return pvfs_search_first_smb2(ntvfs, req, &io->smb2, search_private, callback); } return NT_STATUS_INVALID_LEVEL; @@ -632,6 +789,9 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, case RAW_SEARCH_TRANS2: return pvfs_search_next_trans2(ntvfs, req, io, search_private, callback); + + case RAW_SEARCH_SMB2: + return pvfs_search_next_smb2(ntvfs, req, &io->smb2, search_private, callback); } return NT_STATUS_INVALID_LEVEL; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 63ee3395f8..eb738920f4 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -181,6 +181,9 @@ struct pvfs_file { /* for directories, a buffer of pending notify events */ struct pvfs_notify_buffer *notify_buffer; + + /* for directories, the state of an incomplete SMB2 Find */ + struct pvfs_search_state *search; }; /* the state of a search started with pvfs_search_first() */ -- cgit From eb75ecbccf58c641c29d3622483d9c645cea6f76 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 9 Jul 2006 09:50:41 +0000 Subject: r16889: implement SMB2 Ioctl in the frontend metze (This used to be commit 90b0ae53e40a220249b55035411e6b60ee04de7c) --- source4/ntvfs/posix/pvfs_ioctl.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 3744530a7a..513f03c8ec 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -71,6 +71,9 @@ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, case RAW_IOCTL_NTIOCTL: return pvfs_ntioctl(ntvfs, req, io); + + case RAW_IOCTL_SMB2: + return NT_STATUS_FS_DRIVER_REQUIRED; } return NT_STATUS_INVALID_LEVEL; -- cgit From 810df68c2372dfd311865d4a652ad9b16f394796 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 9 Jul 2006 09:56:13 +0000 Subject: r16890: implement DCERPC over SMB2 in the IPC backend metze (This used to be commit 5338699d0cff5da9fe7f9cd622764ea5a6b0d96b) --- source4/ntvfs/ipc/vfs_ipc.c | 105 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 95 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index e93e32f4e4..a0104cae4d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -31,6 +31,7 @@ #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" #include "rpc_server/dcerpc_server.h" +#include "libcli/raw/ioctl.h" /* this is the private structure used to keep the state of an open ipc$ connection. It needs to keep information about all open @@ -132,16 +133,6 @@ static NTSTATUS ipc_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } - -/* - ioctl interface - we don't do any -*/ -static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_ioctl *io) -{ - return NT_STATUS_ACCESS_DENIED; -} - /* check if a directory exists */ @@ -310,6 +301,34 @@ static NTSTATUS ipc_open_openx(struct ntvfs_module_context *ntvfs, return status; } +/* + open a file with SMB2 Create - used for MSRPC pipes +*/ +static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *oi) +{ + struct pipe_state *p; + NTSTATUS status; + + status = ipc_open_generic(ntvfs, req, oi->smb2.in.fname, &p); + NT_STATUS_NOT_OK_RETURN(status); + + oi->smb2.out.file.ntvfs = p->handle; + oi->smb2.out.oplock_flags = oi->smb2.in.oplock_flags; + oi->smb2.out.create_action = NTCREATEX_ACTION_EXISTED; + oi->smb2.out.create_time = 0; + oi->smb2.out.access_time = 0; + oi->smb2.out.write_time = 0; + oi->smb2.out.change_time = 0; + oi->smb2.out.alloc_size = 4096; + oi->smb2.out.size = 0; + oi->smb2.out.file_attr = FILE_ATTRIBUTE_NORMAL; + oi->smb2.out._pad = 0; + oi->smb2.out.blob = data_blob(NULL, 0); + + return status; +} + /* open a file - used for MSRPC pipes */ @@ -325,6 +344,9 @@ static NTSTATUS ipc_open(struct ntvfs_module_context *ntvfs, case RAW_OPEN_OPENX: status = ipc_open_openx(ntvfs, req, oi); break; + case RAW_OPEN_SMB2: + status = ipc_open_smb2(ntvfs, req, oi); + break; default: status = NT_STATUS_NOT_SUPPORTED; break; @@ -764,6 +786,69 @@ static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, return status; } +static NTSTATUS ipc_ioctl_smb2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_ioctl *io) +{ + struct pipe_state *p; + struct ipc_private *private = ntvfs->private_data; + NTSTATUS status; + + switch (io->smb2.in.function) { + case FSCTL_NAMED_PIPE_READ_WRITE: + break; + + default: + return NT_STATUS_FS_DRIVER_REQUIRED; + } + + p = pipe_state_find(private, io->smb2.in.file.ntvfs); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + + io->smb2.out.out = data_blob_talloc(req, NULL, io->smb2.in.max_response_size); + NT_STATUS_HAVE_NO_MEMORY(io->smb2.out.out.data); + + /* pass the data to the dcerpc server. Note that we don't + expect this to fail, and things like NDR faults are not + reported at this stage. Those sorts of errors happen in the + dcesrv_output stage */ + status = dcesrv_input(p->dce_conn, &io->smb2.in.out); + NT_STATUS_NOT_OK_RETURN(status); + + /* + now ask the dcerpc system for some output. This doesn't yet handle + async calls. Again, we only expect NT_STATUS_OK. If the call fails then + the error is encoded at the dcerpc level + */ + status = dcesrv_output(p->dce_conn, &io->smb2.out.out, ipc_trans_dcesrv_output); + NT_STATUS_IS_ERR_RETURN(status); + + io->smb2.out._pad = 0; + io->smb2.out.function = io->smb2.in.function; + io->smb2.out.unknown2 = 0; + io->smb2.out.unknown3 = 0; + io->smb2.out.in = io->smb2.in.out; + + return status; +} + +/* + ioctl interface +*/ +static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_ioctl *io) +{ + switch (io->generic.level) { + case RAW_IOCTL_SMB2: + return ipc_ioctl_smb2(ntvfs, req, io); + + default: + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_ACCESS_DENIED; +} /* -- cgit From 5468516f9af10cb3c67bc93c610c22b5383e20db Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Jul 2006 14:01:53 +0000 Subject: r16918: the SMB2 Ioctls are sometimes called with a wildcard handle the operation doesn't need a valid file handle in that case metze (This used to be commit d41a83d55945b07020349339888f3a34ac4eff4e) --- source4/ntvfs/ipc/vfs_ipc.c | 3 +++ source4/ntvfs/posix/pvfs_ioctl.c | 1 + 2 files changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index a0104cae4d..cc8b4af285 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -843,6 +843,9 @@ static NTSTATUS ipc_ioctl(struct ntvfs_module_context *ntvfs, case RAW_IOCTL_SMB2: return ipc_ioctl_smb2(ntvfs, req, io); + case RAW_IOCTL_SMB2_NO_HANDLE: + return NT_STATUS_FS_DRIVER_REQUIRED; + default: return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 513f03c8ec..8ba662d3e7 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -73,6 +73,7 @@ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, return pvfs_ntioctl(ntvfs, req, io); case RAW_IOCTL_SMB2: + case RAW_IOCTL_SMB2_NO_HANDLE: return NT_STATUS_FS_DRIVER_REQUIRED; } -- cgit From 3b36a857980b1f9fa5a6be0253e85c975f35c13f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Jul 2006 18:15:42 +0000 Subject: r16950: remove the smb mid from the ntvfs layer and keep a list of pending requests on the smbsrv_connection, to be able to match then on ntcancel metze (This used to be commit 04f0d3d03179b6060fd013b867d13caa92ec6460) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/ntvfs.h | 3 --- source4/ntvfs/ntvfs_util.c | 3 +-- source4/ntvfs/posix/pvfs_wait.c | 3 +-- 4 files changed, 3 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 47b89ff662..41ea2a652d 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -803,7 +803,7 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, /* find the matching request */ for (a=private->pending;a;a=a->next) { - if (a->req->smbmid == req->smbmid) { + if (a->req == req) { break; } } diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index cf541de81e..734df84dde 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -253,9 +253,6 @@ struct ntvfs_request { /* the smb pid is needed for locking contexts */ uint16_t smbpid; - /* the smb mid is needed for matching requests */ - uint16_t smbmid; - /* some statictics for the management tools */ struct { /* the system time when the request arrived */ diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index d99d040378..5c73b53c1c 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -28,7 +28,7 @@ _PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx, struct auth_session_info *session_info, - uint16_t smbpid, uint16_t smbmid, + uint16_t smbpid, struct timeval request_time, void *private_data, void (*send_fn)(struct ntvfs_request *), @@ -43,7 +43,6 @@ _PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, T req->async_states = NULL; req->session_info = session_info; req->smbpid = smbpid; - req->smbmid = smbmid; req->statistics.request_time = request_time; async = talloc(req, struct ntvfs_async_state); diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 90c9b60efe..d912125289 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -179,8 +179,7 @@ NTSTATUS pvfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *r struct pvfs_wait *pwait; for (pwait=pvfs->wait_list;pwait;pwait=pwait->next) { - if (req->smbmid == pwait->req->smbmid && - req->smbpid == pwait->req->smbpid) { + if (pwait->req == req) { /* trigger a cancel on the request */ pwait->reason = PVFS_WAIT_CANCEL; ntvfs_async_setup(pwait->req, pwait); -- cgit From a8958391e8fd9ddd996d2d3aff7ddeed3243fc1f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Jul 2006 14:25:50 +0000 Subject: r16980: - make struct smb_notify a union and add levels RAW_NOTIFY_NTTRANS,RAW_NOTIFY_SMB2 - parse SMB2 Notify reponse metze (This used to be commit de50e0ccddfad16ad7b254770f4c52c1abe707b9) --- source4/ntvfs/cifs/vfs_cifs.c | 10 +++++++--- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/ntvfs_interface.c | 4 ++-- source4/ntvfs/posix/pvfs_notify.c | 26 +++++++++++++++----------- source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- 5 files changed, 26 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 41ea2a652d..1e34e953a5 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -1000,18 +1000,22 @@ static void async_changenotify(struct smbcli_request *c_req) /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *io) + union smb_notify *io) { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; int saved_timeout = private->transport->options.request_timeout; struct cvfs_file *f; + if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_NOT_IMPLEMENTED; + } + SETUP_PID; - f = ntvfs_handle_get_backend_data(io->in.file.ntvfs, ntvfs); + f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); if (!f) return NT_STATUS_INVALID_HANDLE; - io->in.file.fnum = f->fnum; + io->nttrans.in.file.fnum = f->fnum; /* this request doesn't make sense unless its async */ if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 734df84dde..6916ea10fc 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -139,7 +139,7 @@ struct ntvfs_ops { /* change notify request */ NTSTATUS (*notify)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info); + union smb_notify *info); /* cancel - cancels any pending async request */ NTSTATUS (*cancel)(struct ntvfs_module_context *ntvfs, diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 67cbe8df22..fc8fccca33 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -313,7 +313,7 @@ _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) /* change notify request */ -_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, struct smb_notify *info) +_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->notify) { @@ -617,7 +617,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, */ _PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info) + union smb_notify *info) { if (!ntvfs->next || !ntvfs->next->ops->notify) { return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 64aeac0696..ffbe1f8bb7 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -40,7 +40,7 @@ struct pvfs_notify_buffer { struct notify_pending { struct notify_pending *next, *prev; struct ntvfs_request *req; - struct smb_notify *info; + union smb_notify *info; } *pending; }; @@ -64,7 +64,7 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, { struct notify_pending *pending = notify_buffer->pending; struct ntvfs_request *req; - struct smb_notify *info; + union smb_notify *info; if (notify_buffer->current_buffer_size > notify_buffer->max_buffer_size && notify_buffer->num_changes != 0) { @@ -87,15 +87,15 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, req = pending->req; info = pending->info; - info->out.num_changes = notify_buffer->num_changes; - info->out.changes = talloc_steal(req, notify_buffer->changes); + info->nttrans.out.num_changes = notify_buffer->num_changes; + info->nttrans.out.changes = talloc_steal(req, notify_buffer->changes); notify_buffer->num_changes = 0; notify_buffer->changes = NULL; notify_buffer->current_buffer_size = 0; talloc_free(pending); - if (info->out.num_changes != 0) { + if (info->nttrans.out.num_changes != 0) { status = NT_STATUS_OK; } @@ -219,7 +219,7 @@ static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason) event buffer is non-empty */ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, - struct smb_notify *info) + union smb_notify *info) { struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data, struct pvfs_state); @@ -227,7 +227,11 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct notify_pending *pending; - f = pvfs_find_fd(pvfs, req, info->in.file.ntvfs); + if (info->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + f = pvfs_find_fd(pvfs, req, info->nttrans.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } @@ -246,15 +250,15 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, create one */ if (f->notify_buffer == NULL) { status = pvfs_notify_setup(pvfs, f, - info->in.buffer_size, - info->in.completion_filter, - info->in.recursive); + info->nttrans.in.buffer_size, + info->nttrans.in.completion_filter, + info->nttrans.in.recursive); NT_STATUS_NOT_OK_RETURN(status); } /* we update the max_buffer_size on each call, but we do not update the recursive flag or filter */ - f->notify_buffer->max_buffer_size = info->in.buffer_size; + f->notify_buffer->max_buffer_size = info->nttrans.in.buffer_size; pending = talloc(f->notify_buffer, struct notify_pending); NT_STATUS_HAVE_NO_MEMORY(pending); diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index b12339b2c8..17fdb42de0 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -520,7 +520,7 @@ static NTSTATUS unixuid_cancel(struct ntvfs_module_context *ntvfs, change notify */ static NTSTATUS unixuid_notify(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_notify *info) + struct ntvfs_request *req, union smb_notify *info) { NTSTATUS status; -- cgit From 4c499cb45fa2452756642ab7017c1a9f321b73f6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 13 Jul 2006 13:51:54 +0000 Subject: r17008: on SMB2 Create the delete_on_close flag isn't ignored for existing opened files as it is for SMB. metze (This used to be commit bcf09a769e241de36abed17f22aa0534d87cf4ff) --- source4/ntvfs/posix/pvfs_open.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5482bb3562..b0d0348240 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -992,6 +992,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t create_options; uint32_t share_access; uint32_t access_mask; + BOOL del_on_close; BOOL stream_existed, stream_truncate=False; uint32_t oplock_level = OPLOCK_NONE, oplock_granted; @@ -1169,6 +1170,17 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_set_destructor(f, pvfs_fnum_destructor); talloc_set_destructor(f->handle, pvfs_handle_destructor); + /* + * Only SMB2 takes care of the delete_on_close, + * on existing files + */ + if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE && + req->ctx->protocol == PROTOCOL_SMB2) { + del_on_close = True; + } else { + del_on_close = False; + } + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { oplock_level = OPLOCK_NONE; } else if (io->ntcreatex.in.flags & NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK) { @@ -1179,8 +1191,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* see if we are allowed to open at the same time as existing opens */ status = odb_open_file(lck, f->handle, f->handle->name->stream_id, - share_access, access_mask, False, name->full_name, - oplock_level, &oplock_granted); + share_access, access_mask, del_on_close, + name->full_name, oplock_level, &oplock_granted); /* on a sharing violation we need to retry when the file is closed by the other user, or after 1 second */ -- cgit From bdf914a39d42b5ced62f59aaa38d75fe53c32aa9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 Jul 2006 11:15:10 +0000 Subject: r17087: - make pvfs_notify_next_send static - fix double free: a talloc_reference(a,b) when a is a child of b doesn't prevent talloc_free(b) from destroiying a and b. metze (This used to be commit 41acbc6645cc22d7f5f061dc5eda9b938ca018ba) --- source4/ntvfs/posix/pvfs_notify.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index ffbe1f8bb7..d6fec02305 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -47,11 +47,10 @@ struct pvfs_notify_buffer { /* send a notify on the next event run. */ -void pvfs_notify_send_next(struct event_context *ev, struct timed_event *te, - struct timeval t, void *ptr) +static void pvfs_notify_send_next(struct event_context *ev, struct timed_event *te, + struct timeval t, void *ptr) { struct ntvfs_request *req = talloc_get_type(ptr, struct ntvfs_request); - talloc_free(req); req->async_states->send_fn(req); } @@ -109,7 +108,6 @@ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, /* we can't call pvfs_notify_send() directly here, as that would free the request, and the ntvfs modules above us could use it, so call it on the next event */ - talloc_reference(notify_buffer, req); event_add_timed(req->ctx->event_ctx, req, timeval_zero(), pvfs_notify_send_next, req); } -- cgit From e1248154d6c42cd6780ce5e065a5877e983a7c9d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 17 Jul 2006 11:17:32 +0000 Subject: r17088: add ntvfs mapping function for notify metze (This used to be commit 7daf432d58ecebd10a28acd3ddbded9cb16536d0) --- source4/ntvfs/ntvfs_generic.c | 64 +++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_notify.c | 2 +- 2 files changed, 65 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index e0e69b25e1..aff05b70a8 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1327,3 +1327,67 @@ _PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, return ntvfs->ops->close(ntvfs, req, cl2); } + +/* + NTVFS notify generic to any mapper +*/ +static NTSTATUS ntvfs_map_notify_finish(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_notify *nt, + union smb_notify *nt2, + NTSTATUS status) +{ + NT_STATUS_NOT_OK_RETURN(status); + + switch (nt->nttrans.level) { + case RAW_NOTIFY_SMB2: + if (nt2->nttrans.out.num_changes == 0) { + return STATUS_NOTIFY_ENUM_DIR; + } + nt->smb2.out.num_changes = nt2->nttrans.out.num_changes; + nt->smb2.out.changes = talloc_steal(req, nt2->nttrans.out.changes); + break; + + default: + return NT_STATUS_INVALID_LEVEL; + } + + return status; +} + + +/* + NTVFS notify generic to any mapper +*/ +_PUBLIC_ NTSTATUS ntvfs_map_notify(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_notify *nt) +{ + union smb_notify *nt2; + NTSTATUS status; + + nt2 = talloc(req, union smb_notify); + NT_STATUS_HAVE_NO_MEMORY(nt2); + + status = ntvfs_map_async_setup(ntvfs, req, nt, nt2, + (second_stage_t)ntvfs_map_notify_finish); + NT_STATUS_NOT_OK_RETURN(status); + + nt2->nttrans.level = RAW_NOTIFY_NTTRANS; + + switch (nt->nttrans.level) { + case RAW_NOTIFY_NTTRANS: + status = NT_STATUS_INVALID_LEVEL; + break; + + case RAW_NOTIFY_SMB2: + nt2->nttrans.in.file.ntvfs = nt->smb2.in.file.ntvfs; + nt2->nttrans.in.buffer_size = nt->smb2.in.buffer_size; + nt2->nttrans.in.completion_filter = nt->smb2.in.completion_filter; + nt2->nttrans.in.recursive = nt->smb2.in.recursive; + status = ntvfs->ops->notify(ntvfs, req, nt2); + break; + } + + return ntvfs_map_async_finish(req, status); +} diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index d6fec02305..460bf11f40 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -226,7 +226,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, struct notify_pending *pending; if (info->nttrans.level != RAW_NOTIFY_NTTRANS) { - return NT_STATUS_NOT_IMPLEMENTED; + return ntvfs_map_notify(ntvfs, req, info); } f = pvfs_find_fd(pvfs, req, info->nttrans.in.file.ntvfs); -- cgit From 9c66f601f1520a99b9236c32bc9f03a33bd4b2aa Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 23 Jul 2006 18:43:07 +0000 Subject: r17206: Add a modular API for share configuration. Commit the classic backwards compatible module which is the default one (This used to be commit a89cc346b9296cb49929898d257a064a6c2bae86) --- source4/ntvfs/cifs/vfs_cifs.c | 33 +++++++++++++------- source4/ntvfs/cifs_posix_cli/vfs_simple.c | 9 +++--- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/common/notify.c | 10 ++++-- source4/ntvfs/ipc/rap_server.c | 41 ++++++++++++++++++++----- source4/ntvfs/ntvfs.h | 5 ++- source4/ntvfs/ntvfs_base.c | 7 ++--- source4/ntvfs/posix/vfs_posix.c | 51 +++++++++++++++++++------------ source4/ntvfs/posix/vfs_posix.h | 13 ++++++++ source4/ntvfs/print/vfs_print.c | 3 +- source4/ntvfs/simple/vfs_simple.c | 10 +++--- source4/ntvfs/sysdep/sys_notify.c | 6 ++-- source4/ntvfs/sysdep/sys_notify.h | 3 +- 13 files changed, 128 insertions(+), 65 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 1e34e953a5..edb5f7b791 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -74,6 +74,19 @@ struct async_info { SETUP_FILE; \ } while (0) +#define CIFS_SERVER "cifs:server" +#define CIFS_USER "cifs:user" +#define CIFS_PASSWORD "cifs:password" +#define CIFS_DOMAIN "cifs:domain" +#define CIFS_SHARE "cifs:share" +#define CIFS_USE_MACHINE_ACCT "cifs:use-machine-account" +#define CIFS_MAP_GENERIC "cifs:map-generic" +#define CIFS_MAP_TRANS2 "cifs:map-trans2" + +#define CIFS_USE_MACHINE_ACCT_DEFAULT False +#define CIFS_MAP_GENERIC_DEFAULT False +#define CIFS_MAP_TRANS2_DEFAULT True + /* a handler for oplock break events from the server - these need to be passed along to the client @@ -113,7 +126,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, const char *host, *user, *pass, *domain, *remote_share; struct smb_composite_connect io; struct composite_context *creq; - int snum = ntvfs->ctx->config.snum; + struct share_config *scfg = ntvfs->ctx->config; struct cli_credentials *credentials; BOOL machine_account; @@ -122,16 +135,16 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. */ - host = lp_parm_string(snum, "cifs", "server"); - user = lp_parm_string(snum, "cifs", "user"); - pass = lp_parm_string(snum, "cifs", "password"); - domain = lp_parm_string(snum, "cifs", "domain"); - remote_share = lp_parm_string(snum, "cifs", "share"); + host = share_string_option(scfg, CIFS_SERVER, NULL); + user = share_string_option(scfg, CIFS_USER, NULL); + pass = share_string_option(scfg, CIFS_PASSWORD, NULL); + domain = share_string_option(scfg, CIFS_DOMAIN, NULL); + remote_share = share_string_option(scfg, CIFS_SHARE, NULL); if (!remote_share) { remote_share = sharename; } - machine_account = lp_parm_bool(snum, "cifs", "use_machine_account", False); + machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); private = talloc_zero(ntvfs, struct cvfs_private); if (!private) { @@ -204,11 +217,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(private->transport, oplock_handler, private); - private->map_generic = lp_parm_bool(ntvfs->ctx->config.snum, - "cifs", "mapgeneric", False); + private->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT); - private->map_trans2 = lp_parm_bool(ntvfs->ctx->config.snum, - "cifs", "maptrans2", True); + private->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT); return NT_STATUS_OK; } diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c index cf28a02806..eb62336d13 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_simple.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_simple.c @@ -43,7 +43,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (lp_readonly(ntvfs->ctx->config.snum)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) /* connect to a share - used when a tree_connect operation comes @@ -56,12 +56,11 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, { struct stat st; struct svfs_private *private; - int snum = ntvfs->ctx->config.snum; private = talloc(ntvfs, struct svfs_private); private->next_search_handle = 0; - private->connectpath = talloc_strdup(private, lp_pathname(snum)); + private->connectpath = talloc_strdup(private, share_string_option(ntvfs->ctx->config, SHARE_PATH, "")); private->open_files = NULL; private->search = NULL; @@ -317,7 +316,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(ntvfs, req, io); } - readonly = lp_readonly(ntvfs->ctx->config.snum); + readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True); if (readonly) { create_flags = 0; rdwr_flags = O_RDONLY; @@ -728,7 +727,7 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(ntvfs->ctx->config.snum)); + fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name); fs->generic.out.fs_type = ntvfs->ctx->fs_type; return NT_STATUS_OK; diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index feb3613f78..c16cc09dfe 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,6 +7,6 @@ OBJ_FILES = \ brlock.o \ opendb.o \ notify.o -PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify +PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share # End LIBRARY ntvfs_common ################################################ diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 222bd7a927..dbf404d9e6 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -56,6 +56,9 @@ struct notify_list { #define NOTIFY_KEY "notify array" +#define NOTIFY_ENABLE "notify:enable" +#define NOTIFY_ENABLE_DEFAULT True + static NTSTATUS notify_remove_all(struct notify_context *notify); static void notify_handler(struct messaging_context *msg_ctx, void *private, uint32_t msg_type, uint32_t server_id, DATA_BLOB *data); @@ -77,12 +80,13 @@ static int notify_destructor(struct notify_context *notify) */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, struct messaging_context *messaging_ctx, - struct event_context *ev, int snum) + struct event_context *ev, + struct share_config *scfg) { char *path; struct notify_context *notify; - if (lp_parm_bool(snum, "notify", "enable", True) != True) { + if (share_bool_option(scfg, NOTIFY_ENABLE, NOTIFY_ENABLE_DEFAULT) != True) { return NULL; } @@ -114,7 +118,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, messaging_register(notify->messaging_ctx, notify, MSG_PVFS_NOTIFY, notify_handler); - notify->sys_notify_ctx = sys_notify_context_create(snum, notify, ev); + notify->sys_notify_ctx = sys_notify_context_create(scfg, notify, ev); return notify; } diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 8ec62dff8b..f92b02c20a 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "param/share.h" #include "libcli/rap/rap.h" #include "librpc/gen_ndr/srvsvc.h" #include "rpc_server/common/common.h" @@ -30,21 +31,45 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, struct rap_NetShareEnum *r) { - int i; + NTSTATUS nterr; + const char **snames; + struct share_context *sctx; + struct share_config *scfg; + int i, j, count; + r->out.status = 0; - r->out.available = dcesrv_common_get_count_of_shares(mem_ctx, NULL); + r->out.available = 0; + r->out.info = NULL; + + nterr = share_get_context(mem_ctx, &sctx); + if (!NT_STATUS_IS_OK(nterr)) { + return nterr; + } + + nterr = share_list_all(mem_ctx, sctx, &count, &snames); + if (!NT_STATUS_IS_OK(nterr)) { + return nterr; + } + + r->out.available = count; r->out.info = talloc_array(mem_ctx, union rap_shareenum_info, r->out.available); - for (i=0;iout.available;i++) { - strncpy(r->out.info[i].info1.name, - dcesrv_common_get_share_name(mem_ctx, NULL, i), + for (i = 0, j = 0; i < r->out.available; i++) { + if (!NT_STATUS_IS_OK(share_get_config(mem_ctx, sctx, snames[i], &scfg))) { + DEBUG(3, ("WARNING: Service [%s] disappeared after enumeration!\n", snames[i])); + continue; + } + strncpy(r->out.info[j].info1.name, + snames[i], sizeof(r->out.info[0].info1.name)); r->out.info[i].info1.pad = 0; - r->out.info[i].info1.type = dcesrv_common_get_share_type(mem_ctx, NULL, i); - r->out.info[i].info1.comment = talloc_strdup(mem_ctx, - dcesrv_common_get_share_comment(mem_ctx, NULL, i)); + r->out.info[i].info1.type = dcesrv_common_get_share_type(mem_ctx, NULL, scfg); + r->out.info[i].info1.comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, "")); + talloc_free(scfg); + j++; } + r->out.available = j; return NT_STATUS_OK; } diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 6916ea10fc..b48a5dac00 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -20,6 +20,7 @@ */ #include "libcli/raw/interfaces.h" +#include "param/share.h" /* modules can use the following to determine if the interface has changed */ /* version 1 -> 0 - make module stacking easier -- metze */ @@ -181,9 +182,7 @@ struct ntvfs_context { */ struct ntvfs_module_context *modules; - struct { - int snum; - } config; + struct share_config *config; uint32_t server_id; struct event_context *event_ctx; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 316a9e9c68..e6c4089e47 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -148,16 +148,15 @@ _PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const i #undef FIELD_DIFFERS } - /* initialise a connection structure to point at a NTVFS backend */ -NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, int snum, enum ntvfs_type type, +NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, enum ntvfs_type type, enum protocol_types protocol, struct event_context *ev, struct messaging_context *msg, uint32_t server_id, struct ntvfs_context **_ctx) { - const char **handlers = lp_ntvfs_handler(snum); + const char **handlers = share_string_list_option(mem_ctx, scfg, SHARE_NTVFS_HANDLER); int i; struct ntvfs_context *ctx; @@ -169,7 +168,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, int snum, enum ntvfs_type ty NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->protocol = protocol; ctx->type = type; - ctx->config.snum = snum; + ctx->config = talloc_steal(ctx, scfg); ctx->event_ctx = ev; ctx->msg_ctx = msg; ctx->server_id = server_id; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e7ef9bafd8..975649eeb5 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -38,35 +38,46 @@ */ static void pvfs_setup_options(struct pvfs_state *pvfs) { - int snum = pvfs->ntvfs->ctx->config.snum; + struct share_config *scfg = pvfs->ntvfs->ctx->config; const char *eadb; - if (lp_map_hidden(snum)) pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; - if (lp_map_archive(snum)) pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; - if (lp_map_system(snum)) pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; - if (lp_readonly(snum)) pvfs->flags |= PVFS_FLAG_READONLY; - if (lp_strict_sync(snum)) pvfs->flags |= PVFS_FLAG_STRICT_SYNC; - if (lp_strict_locking(snum)) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; - if (lp_ci_filesystem(snum)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; - - if (lp_parm_bool(snum, "posix", "fakeoplocks", False)) { + if (share_bool_option(scfg, SHARE_MAP_HIDDEN, SHARE_MAP_HIDDEN_DEFAULT)) + pvfs->flags |= PVFS_FLAG_MAP_HIDDEN; + if (share_bool_option(scfg, SHARE_MAP_ARCHIVE, SHARE_MAP_ARCHIVE_DEFAULT)) + pvfs->flags |= PVFS_FLAG_MAP_ARCHIVE; + if (share_bool_option(scfg, SHARE_MAP_SYSTEM, SHARE_MAP_SYSTEM_DEFAULT)) + pvfs->flags |= PVFS_FLAG_MAP_SYSTEM; + if (share_bool_option(scfg, SHARE_READONLY, SHARE_READONLY_DEFAULT)) + pvfs->flags |= PVFS_FLAG_READONLY; + if (share_bool_option(scfg, SHARE_STRICT_SYNC, SHARE_STRICT_SYNC_DEFAULT)) + pvfs->flags |= PVFS_FLAG_STRICT_SYNC; + if (share_bool_option(scfg, SHARE_STRICT_LOCKING, SHARE_STRICT_LOCKING_DEFAULT)) + pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; + if (share_bool_option(scfg, SHARE_CI_FILESYSTEM, SHARE_CI_FILESYSTEM_DEFAULT)) + pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; + if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT)) { pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; } /* this must be a power of 2 */ - pvfs->alloc_size_rounding = lp_parm_int(snum, - "posix", "allocationrounding", 512); + pvfs->alloc_size_rounding = share_int_option(scfg, + PVFS_ALLOCATION_ROUNDING, + PVFS_ALLOCATION_ROUNDING_DEFAULT); - pvfs->search.inactivity_time = lp_parm_int(snum, - "posix", "searchinactivity", 300); + pvfs->search.inactivity_time = share_int_option(scfg, + PVFS_SEARCH_INACTIVITY, + PVFS_SEARCH_INACTIVITY_DEFAULT); #if HAVE_XATTR_SUPPORT - if (lp_parm_bool(snum, "posix", "xattr", True)) pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; + if (share_bool_option(scfg, PVFS_XATTR, PVFS_XATTR_DEFAULT)) + pvfs->flags |= PVFS_FLAG_XATTR_ENABLE; #endif - pvfs->sharing_violation_delay = lp_parm_int(snum, "posix", "sharedelay", 1000000); + pvfs->sharing_violation_delay = share_int_option(scfg, + PVFS_SHARE_DELAY, + PVFS_SHARE_DELAY_DEFAULT); - pvfs->share_name = talloc_strdup(pvfs, lp_servicename(snum)); + pvfs->share_name = talloc_strdup(pvfs, scfg->name); pvfs->fs_attribs = FS_ATTR_CASE_SENSITIVE_SEARCH | @@ -75,7 +86,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) FS_ATTR_SPARSE_FILES; /* allow xattrs to be stored in a external tdb */ - eadb = lp_parm_string(snum, "posix", "eadb"); + eadb = share_string_option(scfg, PVFS_EADB, NULL); if (eadb != NULL) { pvfs->ea_db = tdb_wrap_open(pvfs, eadb, 50000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); @@ -144,7 +155,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(pvfs); /* for simplicity of path construction, remove any trailing slash now */ - base_directory = talloc_strdup(pvfs, lp_pathname(ntvfs->ctx->config.snum)); + base_directory = talloc_strdup(pvfs, share_string_option(ntvfs->ctx->config, SHARE_PATH, "")); NT_STATUS_HAVE_NO_MEMORY(base_directory); if (strcmp(base_directory, "/") != 0) { trim_string(base_directory, NULL, "/"); @@ -186,7 +197,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, event_context_find(pvfs), - pvfs->ntvfs->ctx->config.snum); + pvfs->ntvfs->ctx->config); pvfs->sidmap = sidmap_open(pvfs); if (pvfs->sidmap == NULL) { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index eb738920f4..8d3e86fff1 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -222,6 +222,19 @@ struct pvfs_dir; /* types of notification for pvfs wait events */ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; +#define PVFS_EADB "posix:eadb" +#define PVFS_XATTR "posix:xattr" +#define PVFS_FAKE_OPLOCKS "posix:fakeoplocks" +#define PVFS_SHARE_DELAY "posix:sharedelay" +#define PVFS_ALLOCATION_ROUNDING "posix:allocationrounding" +#define PVFS_SEARCH_INACTIVITY "posix:searchinactivity" + +#define PVFS_XATTR_DEFAULT True +#define PVFS_FAKE_OPLOCKS_DEFAULT False +#define PVFS_SHARE_DELAY_DEFAULT 1000000 +#define PVFS_ALLOCATION_ROUNDING_DEFAULT 512 +#define PVFS_SEARCH_INACTIVITY_DEFAULT 300 + #include "ntvfs/posix/vfs_posix_proto.h" #endif /* _VFS_POSIX_H_ */ diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 31cfcc9303..dfe76b846e 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -75,7 +75,6 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, } if (io->ioctl.in.request == IOCTL_QUERY_JOB_INFO) { - int snum = ntvfs->ctx->config.snum; /* a request for the print job id of an open print job */ io->ioctl.out.blob = data_blob_talloc(req, NULL, 32); @@ -85,7 +84,7 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); push_string(p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); - push_string(p+18, lp_servicename(snum), 13, STR_TERMINATE|STR_ASCII); + push_string(p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index beffe2b546..ccb8b1b97c 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -39,7 +39,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (lp_readonly(ntvfs->ctx->config.snum)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) /* connect to a share - used when a tree_connect operation comes @@ -52,13 +52,13 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, { struct stat st; struct svfs_private *private; - int snum = ntvfs->ctx->config.snum; + struct share_config *scfg = ntvfs->ctx->config; private = talloc(ntvfs, struct svfs_private); NT_STATUS_HAVE_NO_MEMORY(private); private->ntvfs = ntvfs; private->next_search_handle = 0; - private->connectpath = talloc_strdup(private, lp_pathname(snum)); + private->connectpath = talloc_strdup(private, share_string_option(scfg, SHARE_PATH, "")); private->open_files = NULL; private->search = NULL; @@ -319,7 +319,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(ntvfs, req, io); } - readonly = lp_readonly(ntvfs->ctx->config.snum); + readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, SHARE_READONLY_DEFAULT); if (readonly) { create_flags = 0; rdwr_flags = O_RDONLY; @@ -775,7 +775,7 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.out.quota_soft = 0; fs->generic.out.quota_hard = 0; fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req, lp_servicename(ntvfs->ctx->config.snum)); + fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name); fs->generic.out.fs_type = ntvfs->ctx->fs_type; return NT_STATUS_OK; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index c4fa4647d1..3f4f08203e 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -34,10 +34,12 @@ static struct sys_notify_backend *backends; static uint32_t num_backends; +#define NOTIFY_BACKEND "notify-backend" + /* initialise a system change notify backend */ -_PUBLIC_ struct sys_notify_context *sys_notify_context_create(int snum, +_PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_config *scfg, TALLOC_CTX *mem_ctx, struct event_context *ev) { @@ -60,7 +62,7 @@ _PUBLIC_ struct sys_notify_context *sys_notify_context_create(int snum, ctx->ev = ev; - bname = lp_parm_string(snum, "notify", "backend"); + bname = share_string_option(scfg, NOTIFY_BACKEND, NULL); if (!bname) { if (num_backends) { bname = backends[0].name; diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h index 6f8e91efec..6db10fe02c 100644 --- a/source4/ntvfs/sysdep/sys_notify.h +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -19,6 +19,7 @@ */ #include "librpc/gen_ndr/notify.h" +#include "param/share.h" struct sys_notify_context; @@ -43,7 +44,7 @@ struct sys_notify_backend { }; NTSTATUS sys_notify_register(struct sys_notify_backend *backend); -struct sys_notify_context *sys_notify_context_create(int snum, +struct sys_notify_context *sys_notify_context_create(struct share_config *scfg, TALLOC_CTX *mem_ctx, struct event_context *ev); NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, -- cgit From 7b52d77eb5b43787bb95298575bcd0f5f1ed7602 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Aug 2006 10:11:37 +0000 Subject: r17359: http://www.cs.wisc.edu/~cao/cs739/draft-leach-cifs-v1-spec-01.txt says that with the 0xffff fid all files only for the given pid should be flushed Does samba3 handle this correct? metze (This used to be commit 7cf6eae23bf5b944ce6e419105d6cf195b368319) --- source4/ntvfs/posix/pvfs_flush.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 2e64dc983d..0f5a07071b 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -62,8 +62,13 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } - /* they are asking to flush all open files */ + /* + * they are asking to flush all open files + * for the given SMBPID + */ for (f=pvfs->files.list;f;f=f->next) { + if (f->smbpid != req->smbpid) continue; + pvfs_flush_file(pvfs, f); } -- cgit From 529c5dae51c1e782e095bf96b7ab2ca95ccbb856 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 1 Aug 2006 10:58:01 +0000 Subject: r17362: session_info and smbpid are available from the ntvfs_handle so we don't need them on the pvfs_file struct. also we don't need to check is the handle has the correct session as this is job of the frontend server metze (This used to be commit c83501335f245ac73b9d53c12efee3d46b8c5b05) --- source4/ntvfs/posix/pvfs_flush.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 21 +++++---------------- source4/ntvfs/posix/vfs_posix.h | 8 -------- 3 files changed, 6 insertions(+), 25 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 0f5a07071b..a9f36d1ae1 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -67,7 +67,7 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, * for the given SMBPID */ for (f=pvfs->files.list;f;f=f->next) { - if (f->smbpid != req->smbpid) continue; + if (f->ntvfs->smbpid != req->smbpid) continue; pvfs_flush_file(pvfs, f); } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index b0d0348240..d8f30476ac 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -43,11 +43,6 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, f = talloc_get_type(p, struct pvfs_file); if (!f) return NULL; - if (req->session_info != f->session_info) { - DEBUG(2,("pvfs_find_fd: attempt to use wrong session for handle %p\n",h)); - return NULL; - } - return f; } @@ -256,8 +251,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } f->ntvfs = h; - f->session_info = req->session_info; - f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; f->lock_count = 0; @@ -690,8 +683,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } f->ntvfs = h; - f->session_info = req->session_info; - f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; f->lock_count = 0; @@ -861,8 +852,8 @@ static NTSTATUS pvfs_open_deny_dos(struct ntvfs_module_context *ntvfs, */ for (f2=pvfs->files.list;f2;f2=f2->next) { if (f2 != f && - f2->session_info == req->session_info && - f2->smbpid == req->smbpid && + f2->ntvfs->session_info == req->session_info && + f2->ntvfs->smbpid == req->smbpid && (f2->handle->create_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) && @@ -1120,8 +1111,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } f->ntvfs = h; - f->session_info = req->session_info; - f->smbpid = req->smbpid; f->pvfs = pvfs; f->pending_list = NULL; f->lock_count = 0; @@ -1344,7 +1333,7 @@ NTSTATUS pvfs_logoff(struct ntvfs_module_context *ntvfs, for (f=pvfs->files.list;f;f=next) { next = f->next; - if (f->session_info == req->session_info) { + if (f->ntvfs->session_info == req->session_info) { talloc_free(f); } } @@ -1364,8 +1353,8 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, for (f=pvfs->files.list;f;f=next) { next = f->next; - if (f->session_info == req->session_info && - f->smbpid == req->smbpid) { + if (f->ntvfs->session_info == req->session_info && + f->ntvfs->smbpid == req->smbpid) { talloc_free(f); } } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 8d3e86fff1..a788ddd19c 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -161,14 +161,6 @@ struct pvfs_file { uint32_t share_access; uint32_t access_mask; - /* we need to remember the session it was opened on, - as it is illegal to operate on someone elses fnum */ - struct auth_session_info *session_info; - - /* we need to remember the client pid that - opened the file so SMBexit works */ - uint16_t smbpid; - /* a list of pending locks - used for locking cancel operations */ struct pvfs_pending_lock *pending_list; -- cgit From 8c291e67c5c30bd75a8639f04dfcb4168e939930 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Aug 2006 11:55:13 +0000 Subject: r17520: If the blkid library fails, I don't see any reason to return more of an error than if we don't have it. We might not be on a volume that can store/return such a GUID. (Try to fix one of the build farm failures). Andrew Bartlett (This used to be commit 73d6651f3c06d0d3bbfd9fe1a9d0f76fe19ba4af) --- source4/ntvfs/posix/pvfs_fsinfo.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index 1a7ad16776..c1df33be18 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -39,19 +39,22 @@ static NTSTATUS pvfs_blkid_fs_uuid(struct pvfs_state *pvfs, struct stat *st, str devname = blkid_devno_to_devname(st->st_dev); if (!devname) { - return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + ZERO_STRUCTP(uuid); + return NT_STATUS_OK; } uuid_value = blkid_get_tag_value(NULL, "UUID", devname); free(devname); if (!uuid_value) { - return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + ZERO_STRUCTP(uuid); + return NT_STATUS_OK; } status = GUID_from_string(uuid_value, uuid); free(uuid_value); if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_DEVICE_CONFIGURATION_ERROR; + ZERO_STRUCTP(uuid); + return NT_STATUS_OK; } return NT_STATUS_OK; #else -- cgit From b950a91fb2a62c5429bbeb60679dfbd695fd6732 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 21 Aug 2006 06:06:02 +0000 Subject: r17656: some systems (like older solaris) don't return ENOTEMPTY on rmdir() with non-empty directory (This used to be commit 1775381afad8a97777a45b6e98802dda8b389ecb) --- source4/ntvfs/posix/pvfs_mkdir.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 338fc7df0b..2f5ba0a744 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -179,6 +179,10 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs, } if (rmdir(name->full_name) == -1) { + /* some olders systems don't return ENOTEMPTY to rmdir() */ + if (errno == EEXIST) { + return NT_STATUS_DIRECTORY_NOT_EMPTY; + } return pvfs_map_errno(pvfs, errno); } -- cgit From 312ded39cc08596fd3818ab81f25d2e9e09d7a3c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Aug 2006 13:06:31 +0000 Subject: r17752: using -1 in a uint16_t value causes compiler warnings, use UINT16_MAX as invalid search handle metze (This used to be commit a4e19d6cc4cce611241c502de485dbd2496be0d3) --- source4/ntvfs/posix/pvfs_search.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 58cc1e04f3..0d6ee117b5 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -31,6 +31,8 @@ /* place a reasonable limit on old-style searches as clients tend to not send search close requests */ #define MAX_OLD_SEARCHES 2000 +#define MAX_SEARCH_HANDLES (UINT16_MAX - 1) +#define INVALID_SEARCH_HANDLE UINT16_MAX /* destroy an open search @@ -58,7 +60,7 @@ static void pvfs_search_timer(struct event_context *ev, struct timed_event *te, static void pvfs_search_setup_timer(struct pvfs_search_state *search) { struct event_context *ev = search->pvfs->ntvfs->ctx->event_ctx; - if (search->handle == -1) return; + if (search->handle == INVALID_SEARCH_HANDLE) return; talloc_free(search->te); search->te = event_add_timed(ev, search, timeval_current_ofs(search->pvfs->search.inactivity_time, 0), @@ -488,7 +490,7 @@ static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs, return status; } - id = idr_get_new(pvfs->search.idtree, search, UINT16_MAX); + id = idr_get_new(pvfs->search.idtree, search, MAX_SEARCH_HANDLES); if (id == -1) { return NT_STATUS_INSUFFICIENT_RESOURCES; } @@ -669,7 +671,7 @@ static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); search->pvfs = pvfs; - search->handle = -1; + search->handle = INVALID_SEARCH_HANDLE; search->dir = dir; search->current_index = 0; search->search_attrib = 0; @@ -804,7 +806,7 @@ NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs, { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; - uint16_t handle = 0; + uint16_t handle = INVALID_SEARCH_HANDLE; switch (io->generic.level) { case RAW_FINDCLOSE_GENERIC: -- cgit From ec626a732cd5e3900c4db38b0b1ba9b19f9ccf5a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 23 Aug 2006 13:14:03 +0000 Subject: r17753: fix compiler warnings and make the code simpler metze (This used to be commit eda302ffa5458a34f78d733cd0a46e79a74e81d7) --- source4/ntvfs/posix/pvfs_shortname.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 8e26db3ed5..00647f1299 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -313,8 +313,8 @@ static BOOL is_8_3(struct pvfs_mangle_context *ctx, try to find a 8.3 name in the cache, and if found then return the original long name. */ -static const char *check_cache(struct pvfs_mangle_context *ctx, - const char *name) +static char *check_cache(struct pvfs_mangle_context *ctx, + TALLOC_CTX *mem_ctx, const char *name) { uint32_t hash, multiplier; unsigned int i; @@ -351,10 +351,10 @@ static const char *check_cache(struct pvfs_mangle_context *ctx, } if (extension[0]) { - return talloc_asprintf(ctx, "%s.%s", prefix, extension); + return talloc_asprintf(mem_ctx, "%s.%s", prefix, extension); } - return talloc_strdup(ctx, prefix); + return talloc_strdup(mem_ctx, prefix); } @@ -672,12 +672,7 @@ const char *pvfs_short_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, char *pvfs_mangled_lookup(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, const char *name) { - const char *ret; - ret = check_cache(pvfs->mangle_ctx, name); - if (ret) { - return talloc_steal(mem_ctx, ret); - } - return NULL; + return check_cache(pvfs->mangle_ctx, mem_ctx, name); } -- cgit From 5987aace3b62b68680246aaf2ba041fd2c090ceb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 24 Aug 2006 08:45:32 +0000 Subject: r17776: these macros are also defined in libcli/raw/trans2.h metze (This used to be commit 58e7fa037571a3a9fab46945e6158687fff54a17) --- source4/ntvfs/posix/pvfs_fileinfo.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index d5f9156ec2..8226b66d1f 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -23,18 +23,6 @@ #include "includes.h" #include "vfs_posix.h" - -/* UNIX filetype mappings. */ -#define UNIX_TYPE_FILE 0 -#define UNIX_TYPE_DIR 1 -#define UNIX_TYPE_SYMLINK 2 -#define UNIX_TYPE_CHARDEV 3 -#define UNIX_TYPE_BLKDEV 4 -#define UNIX_TYPE_FIFO 5 -#define UNIX_TYPE_SOCKET 6 -#define UNIX_TYPE_UNKNOWN 0xFFFFFFFF - - /**************************************************************************** Change a unix mode to a dos mode. ****************************************************************************/ -- cgit From 0329d755a7611ba3897fc1ee9bdce410cc33d7f8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 30 Aug 2006 11:29:34 +0000 Subject: r17930: Merge noinclude branch: * Move dlinklist.h, smb.h to subsystem-specific directories * Clean up ads.h and move what is left of it to dsdb/ (only place where it's used) (This used to be commit f7afa1cb77f3cfa7020b57de12e6003db7cfcc42) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- source4/ntvfs/cifs_posix_cli/vfs_simple.c | 2 +- source4/ntvfs/common/notify.c | 2 +- source4/ntvfs/common/opendb.c | 1 - source4/ntvfs/ipc/ipc_rap.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/ntvfs_base.c | 2 +- source4/ntvfs/ntvfs_util.c | 2 +- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_notify.c | 2 +- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/posix/pvfs_search.c | 2 +- source4/ntvfs/posix/pvfs_wait.c | 2 +- source4/ntvfs/simple/vfs_simple.c | 2 +- source4/ntvfs/sysdep/inotify.c | 4 ++-- source4/ntvfs/sysdep/sys_notify.c | 2 +- 16 files changed, 16 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index edb5f7b791..bfdb5b92fc 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -30,7 +30,7 @@ #include "libcli/smb_composite/smb_composite.h" #include "auth/auth.h" #include "ntvfs/ntvfs.h" -#include "include/dlinklist.h" +#include "lib/util/dlinklist.h" struct cvfs_file { struct cvfs_file *prev, *next; diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c index eb62336d13..2fd5572c0c 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_simple.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_simple.c @@ -35,7 +35,7 @@ #include "system/filesys.h" #include "cvfs.h" #include "system/time.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "ntvfs/ntvfs.h" #include "ntvfs/cifs_posix_cli/proto.h" diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index dbf404d9e6..17c6e81c6f 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -32,7 +32,7 @@ #include "db_wrap.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_notify.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "ntvfs/sysdep/sys_notify.h" struct notify_context { diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index d83ecdc6f2..c63a677847 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -45,7 +45,6 @@ #include "db_wrap.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" -#include "smb.h" #include "ntvfs/ntvfs.h" struct odb_context { diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 3f415c9293..48a7822446 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "smb.h" +#include "libcli/raw/interfaces.h" #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" #include "librpc/ndr/libndr.h" diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index cc8b4af285..bb80963287 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -26,7 +26,7 @@ #include "includes.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "ntvfs/ntvfs.h" #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index e6c4089e47..7e794b582f 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -24,7 +24,7 @@ */ #include "includes.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "build.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 5c73b53c1c..fc457f21c4 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -22,7 +22,7 @@ */ #include "includes.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 8dcee5f983..2a6a19133a 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -23,7 +23,7 @@ #include "includes.h" #include "vfs_posix.h" #include "system/time.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "messaging/messaging.h" diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 460bf11f40..cc91c678b1 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -24,7 +24,7 @@ #include "vfs_posix.h" #include "lib/messaging/irpc.h" #include "messaging/messaging.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "lib/events/events.h" /* pending notifies buffer, hung off struct pvfs_file for open directories diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index d8f30476ac..a0ef77b0ff 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -24,7 +24,7 @@ #include "vfs_posix.h" #include "system/dir.h" #include "system/time.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "messaging/messaging.h" #include "librpc/gen_ndr/xattr.h" diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 0d6ee117b5..bfe0780958 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -26,7 +26,7 @@ #include "librpc/gen_ndr/security.h" #include "smbd/service_stream.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" /* place a reasonable limit on old-style searches as clients tend to not send search close requests */ diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index d912125289..41c5f4742e 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -22,7 +22,7 @@ #include "includes.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "vfs_posix.h" #include "smbd/service_stream.h" #include "lib/messaging/irpc.h" diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index ccb8b1b97c..7477f359fb 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -31,7 +31,7 @@ #include "system/filesys.h" #include "svfs.h" #include "system/time.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "ntvfs/ntvfs.h" #include "ntvfs/simple/proto.h" diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 5348006543..62e9a387a1 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -26,8 +26,8 @@ #include "system/filesys.h" #include "ntvfs/sysdep/sys_notify.h" #include "lib/events/events.h" -#include "smb.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" +#include "libcli/raw/smb.h" #include #include diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 3f4f08203e..765b4a39a5 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -27,7 +27,7 @@ #include "system/filesys.h" #include "ntvfs/sysdep/sys_notify.h" #include "lib/events/events.h" -#include "dlinklist.h" +#include "lib/util/dlinklist.h" #include "build.h" /* list of registered backends */ -- cgit From bbc78c9c148b62d271d731666e0d48d9195e35f0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 6 Sep 2006 05:59:10 +0000 Subject: r18137: more LIBREPLACE deps (This used to be commit 2d813d1e6deb99b06e43462885be848a5399b9a8) --- source4/ntvfs/config.mk | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 8bf506b253..2fbd1847ba 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -25,6 +25,7 @@ PRIVATE_PROTO_HEADER = simple/proto.h OBJ_FILES = \ simple/vfs_simple.o \ simple/svfs_util.o +PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE ntvfs_simple ################################################ @@ -38,6 +39,7 @@ PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h OBJ_FILES = \ cifs_posix_cli/vfs_simple.o \ cifs_posix_cli/svfs_util.o +PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE ntvfs_cifs_posix_cli ################################################ @@ -73,6 +75,7 @@ SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_nbench_init OBJ_FILES = \ nbench/vfs_nbench.o +PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE ntvfs_nbench ################################################ @@ -90,7 +93,7 @@ OBJ_FILES = \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o -PUBLIC_DEPENDENCIES = +PUBLIC_DEPENDENCIES = LIBREPLACE # # End SUBSYSTEM NTVFS ################################################ -- cgit From a46e12d0e07e1630f8ef15aff0f97cb2f1f4c273 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 7 Sep 2006 10:02:32 +0000 Subject: r18213: don't list LIBREPLACE depdendecies explicit and always at it as first private dependencies metze (This used to be commit 135d096776b53ae09ffc2b4f767dfbd18139570f) --- source4/ntvfs/config.mk | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 2fbd1847ba..ce1e37dc54 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -25,7 +25,6 @@ PRIVATE_PROTO_HEADER = simple/proto.h OBJ_FILES = \ simple/vfs_simple.o \ simple/svfs_util.o -PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE ntvfs_simple ################################################ @@ -39,7 +38,6 @@ PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h OBJ_FILES = \ cifs_posix_cli/vfs_simple.o \ cifs_posix_cli/svfs_util.o -PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE ntvfs_cifs_posix_cli ################################################ @@ -75,7 +73,6 @@ SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_nbench_init OBJ_FILES = \ nbench/vfs_nbench.o -PUBLIC_DEPENDENCIES = LIBREPLACE # End MODULE ntvfs_nbench ################################################ @@ -93,7 +90,6 @@ OBJ_FILES = \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o -PUBLIC_DEPENDENCIES = LIBREPLACE # # End SUBSYSTEM NTVFS ################################################ -- cgit From 30ee8beb9316a99e8a49993306252591106cb349 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 9 Sep 2006 10:05:58 +0000 Subject: r18301: I discovered how to load the warnings from a build farm build into emacs compile mode (hint, paste to a file, and compile as "cat filename"). This allowed me to fix nearly all the warnings for a IA_64 SuSE build very quickly. (This used to be commit eba6c84efff735bb0ca941ac4b755ce2b0591667) --- source4/ntvfs/nbench/vfs_nbench.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 34cf8d9565..a56338d931 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -67,7 +67,7 @@ static char *nbench_ntvfs_handle_string(struct ntvfs_request *req, struct ntvfs_ break; default: DEBUG(0,("%s: invalid wire handle size: %u\n", - __FUNCTION__, key.length)); + __FUNCTION__, (unsigned)key.length)); break; } -- cgit From b0f6a94d9aab979b277c7dbd82b03aa0ce3d1a2f Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 9 Sep 2006 23:50:44 +0000 Subject: r18314: Handle the case where a dir has the sticky bit set and the OS gives back EPERM when trying to access user xattrs. Just pretend no attributes are set. Simo. (This used to be commit 53463ca7969e76f9fb2bc7c5a023d23732e422f5) --- source4/ntvfs/posix/xattr_system.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 9dca13e5c2..ab2337c200 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -58,6 +58,30 @@ again: blob->length = estimated_size; goto again; } + if (ret == -1 && errno == EPERM) { + struct stat statbuf; + + if (fd != -1) { + ret = fstat(fd, &statbuf); + } else { + ret = stat(fname, &statbuf); + } + if (ret == 0) { + /* check if this is a directory and the sticky bit is set */ + if (S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & S_ISVTX)) { + /* pretend we could not find the xattr */ + + data_blob_free(blob); + return NT_STATUS_NOT_FOUND; + + } else { + /* if not this was probably a legittimate error + * reset ret and errno to the correct values */ + errno = EPERM; + ret = -1; + } + } + } if (ret == -1) { data_blob_free(blob); -- cgit From 89efea81d9d67ebed159321e8ea496eee54c2deb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Sep 2006 07:24:41 +0000 Subject: r18319: fixed the directory search resume code on IRIX The problem was twofold: 1) irix returns 64 bit numbers in telldir(). The protocol uses a 32 bit resume key. We now cope with this properly using the code in pvfs_list_seek_ofs(). 2) irix returns 0xFFFFFFFF from telldir() for the last entry in the directory. When added to DIR_OFFSET_BASE this became DIR_OFFSET_DOTDOT which meant an infinite loop! (This used to be commit 8cce9740ed0da9f08d6821beb4acaa9d28d149c2) --- source4/ntvfs/posix/pvfs_dirlist.c | 83 ++++++++++++++++++++++++++++++++++---- source4/ntvfs/posix/pvfs_rename.c | 2 +- source4/ntvfs/posix/pvfs_search.c | 39 +++++++++++------- source4/ntvfs/posix/pvfs_unlink.c | 2 +- source4/ntvfs/posix/vfs_posix.h | 2 +- 5 files changed, 102 insertions(+), 26 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index c351f6ba41..e8dd149836 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -45,10 +45,14 @@ struct pvfs_dir { uint32_t name_cache_index; }; +/* these three numbers are chosen to minimise the chances of a bad + interaction with the OS value for 'end of directory'. On IRIX + telldir() returns 0xFFFFFFFF at the end of a directory, and that + caused an infinite loop with the original values of 0,1,2 +*/ #define DIR_OFFSET_DOT 0 #define DIR_OFFSET_DOTDOT 1 -#define DIR_OFFSET_BASE 2 - +#define DIR_OFFSET_BASE 0x80000002 /* a special directory listing case where the pattern has no wildcard. We can just do a single stat() @@ -140,7 +144,7 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, dir->pvfs = pvfs; dir->no_wildcard = False; dir->end_of_search = False; - dir->offset = 0; + dir->offset = DIR_OFFSET_DOT; dir->name_cache = talloc_zero_array(dir, struct name_cache_entry, NAME_CACHE_SIZE); @@ -173,7 +177,7 @@ static void dcache_add(struct pvfs_dir *dir, const char *name) /* return the next entry */ -const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) +const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) { struct dirent *de; enum protocol_types protocol = dir->pvfs->ntvfs->ctx->protocol; @@ -190,7 +194,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) not return them first in a directory, but windows client may assume that these entries always appear first */ if (*ofs == DIR_OFFSET_DOT) { - (*ofs)++; + (*ofs) = DIR_OFFSET_DOTDOT; dir->offset = *ofs; if (ms_fnmatch(dir->pattern, ".", protocol) == 0) { dcache_add(dir, "."); @@ -199,7 +203,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, uint_t *ofs) } if (*ofs == DIR_OFFSET_DOTDOT) { - (*ofs)++; + (*ofs) = DIR_OFFSET_BASE; dir->offset = *ofs; if (ms_fnmatch(dir->pattern, "..", protocol) == 0) { dcache_add(dir, ".."); @@ -254,7 +258,7 @@ const char *pvfs_list_unix_path(struct pvfs_dir *dir) /* return True if end of search has been reached */ -BOOL pvfs_list_eos(struct pvfs_dir *dir, uint_t ofs) +BOOL pvfs_list_eos(struct pvfs_dir *dir, off_t ofs) { return dir->end_of_search; } @@ -262,11 +266,13 @@ BOOL pvfs_list_eos(struct pvfs_dir *dir, uint_t ofs) /* seek to the given name */ -NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) +NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, off_t *ofs) { struct dirent *de; int i; + dir->end_of_search = False; + if (ISDOT(name)) { dir->offset = DIR_OFFSET_DOTDOT; *ofs = dir->offset; @@ -309,6 +315,67 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, uint_t *ofs) return NT_STATUS_OBJECT_NAME_NOT_FOUND; } +/* + seek to the given offset +*/ +NTSTATUS pvfs_list_seek_ofs(struct pvfs_dir *dir, uint32_t resume_key, off_t *ofs) +{ + struct dirent *de; + int i; + + dir->end_of_search = False; + + if (resume_key == DIR_OFFSET_DOT) { + *ofs = DIR_OFFSET_DOTDOT; + return NT_STATUS_OK; + } + + if (resume_key == DIR_OFFSET_DOTDOT) { + *ofs = DIR_OFFSET_BASE; + return NT_STATUS_OK; + } + + if (resume_key == DIR_OFFSET_BASE) { + rewinddir(dir->dir); + if ((de=readdir(dir->dir)) == NULL) { + dir->end_of_search = True; + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + *ofs = telldir(dir->dir) + DIR_OFFSET_BASE; + dir->offset = *ofs; + return NT_STATUS_OK; + } + + for (i=dir->name_cache_index;i>=0;i--) { + struct name_cache_entry *e = &dir->name_cache[i]; + if (resume_key == (uint32_t)e->offset) { + *ofs = e->offset; + return NT_STATUS_OK; + } + } + for (i=NAME_CACHE_SIZE-1;i>dir->name_cache_index;i--) { + struct name_cache_entry *e = &dir->name_cache[i]; + if (resume_key == (uint32_t)e->offset) { + *ofs = e->offset; + return NT_STATUS_OK; + } + } + + rewinddir(dir->dir); + + while ((de = readdir(dir->dir))) { + dir->offset = telldir(dir->dir) + DIR_OFFSET_BASE; + if (resume_key == (uint32_t)dir->offset) { + *ofs = dir->offset; + return NT_STATUS_OK; + } + } + + dir->end_of_search = True; + + return NT_STATUS_OBJECT_NAME_NOT_FOUND; +} + /* see if a directory is empty diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 6a397ef981..8956a0174e 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -257,7 +257,7 @@ static NTSTATUS pvfs_rename_wildcard(struct pvfs_state *pvfs, { struct pvfs_dir *dir; NTSTATUS status; - uint_t ofs = 0; + off_t ofs = 0; const char *fname, *fname2, *dir_path; uint16_t attrib = ren->rename.in.attrib; int total_renamed = 0; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index bfe0780958..6224e15304 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -75,12 +75,15 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, const char *unix_path, const char *fname, struct pvfs_search_state *search, - uint32_t dir_index, + off_t dir_offset, union smb_search_data *file) { struct pvfs_filename *name; NTSTATUS status; const char *shortname; + uint32_t dir_index = (uint32_t)dir_offset; /* truncated - see the code + in pvfs_list_seek_ofs() for + how we cope with this */ status = pvfs_resolve_partial(pvfs, file, unix_path, fname, &name); if (!NT_STATUS_IS_OK(status)) { @@ -249,7 +252,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, while ((*reply_count) < max_count) { union smb_search_data *file; const char *name; - uint_t ofs = search->current_index; + off_t ofs = search->current_index; name = pvfs_list_next(dir, &search->current_index); if (name == NULL) break; @@ -419,10 +422,15 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - search->current_index = io->search_next.in.id.server_cookie; - search->last_used = time(NULL); dir = search->dir; + status = pvfs_list_seek_ofs(dir, io->search_next.in.id.server_cookie, + &search->current_index); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + search->last_used = time(NULL); + status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level, &reply_count, search_private, callback); if (!NT_STATUS_IS_OK(status)) { @@ -557,23 +565,24 @@ static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs, /* we didn't find the search handle */ return NT_STATUS_INVALID_HANDLE; } - + dir = search->dir; + + status = NT_STATUS_OK; /* work out what type of continuation is being used */ if (io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { status = pvfs_list_seek(dir, io->t2fnext.in.last_name, &search->current_index); - if (!NT_STATUS_IS_OK(status)) { - if (io->t2fnext.in.resume_key) { - search->current_index = io->t2fnext.in.resume_key; - } else { - return status; - } + if (!NT_STATUS_IS_OK(status) && io->t2fnext.in.resume_key) { + status = pvfs_list_seek_ofs(dir, io->t2fnext.in.resume_key, + &search->current_index); } - } else if (io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) { - /* plain continue - nothing to do */ - } else { - search->current_index = io->t2fnext.in.resume_key; + } else if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE)) { + status = pvfs_list_seek_ofs(dir, io->t2fnext.in.resume_key, + &search->current_index); + } + if (!NT_STATUS_IS_OK(status)) { + return status; } search->num_ea_names = io->t2fnext.in.num_names; diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index c40634035d..c02f704bd5 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -130,7 +130,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, uint32_t total_deleted=0; struct pvfs_filename *name; const char *fname; - uint_t ofs; + off_t ofs; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, unl->unlink.in.pattern, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index a788ddd19c..82a3d34172 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -183,7 +183,7 @@ struct pvfs_search_state { struct pvfs_search_state *prev, *next; struct pvfs_state *pvfs; uint16_t handle; - uint_t current_index; + off_t current_index; uint16_t search_attrib; uint16_t must_attrib; struct pvfs_dir *dir; -- cgit From 06bc06cf08e0d36a7ca4a01beed5909920cd69d6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Sep 2006 13:48:42 +0000 Subject: r18341: ooh this gets subtle - this needed for xfs on linux (This used to be commit 9d688eb9cbaed484ccb75d601c2331760bd59fab) --- source4/ntvfs/posix/pvfs_dirlist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index e8dd149836..c29f70209f 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -52,7 +52,7 @@ struct pvfs_dir { */ #define DIR_OFFSET_DOT 0 #define DIR_OFFSET_DOTDOT 1 -#define DIR_OFFSET_BASE 0x80000002 +#define DIR_OFFSET_BASE 0x80000022 /* a special directory listing case where the pattern has no wildcard. We can just do a single stat() -- cgit From 3dc237eb28e9254eabf9a1eab08f858ca4830fbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Sep 2006 13:51:57 +0000 Subject: r18342: a bit more explanation of these strange values (This used to be commit e191f84f24e017d90c49d779a04a5306d96848a5) --- source4/ntvfs/posix/pvfs_dirlist.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index c29f70209f..7efc091c42 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -49,6 +49,10 @@ struct pvfs_dir { interaction with the OS value for 'end of directory'. On IRIX telldir() returns 0xFFFFFFFF at the end of a directory, and that caused an infinite loop with the original values of 0,1,2 + + On XFS on linux telldir returns 0x7FFFFFFF at the end of a + directory. Thus the change from 0x80000002, as otherwise + 0x7FFFFFFF+0x80000002==1==DIR_OFFSET_DOTDOT */ #define DIR_OFFSET_DOT 0 #define DIR_OFFSET_DOTDOT 1 -- cgit From c4aaa094e7818e205641a7204a271474c58e453a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Sep 2006 07:56:23 +0000 Subject: r18370: allow system inotify to be disabled (This used to be commit 31bbf865a069f902dc979f469aec896d3d34422c) --- source4/ntvfs/sysdep/inotify.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 62e9a387a1..a5104a01d0 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -253,6 +253,10 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) { struct inotify_private *in; + if (!lp_parm_bool(-1, "notify", "inotify", True)) { + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + in = talloc(ctx, struct inotify_private); NT_STATUS_HAVE_NO_MEMORY(in); in->fd = inotify_init(); -- cgit From db0fdcf6ce8b3d02a5f720652f22a2b7167c5e26 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 15 Sep 2006 19:24:38 +0000 Subject: r18564: update for cifs unix/posix extensions stub version to build and beginnings of smbtorture test for it (This used to be commit 57f56957176ca04f3abb579b557aade71f8d361d) --- source4/ntvfs/cifs_posix_cli/svfs_util.c | 2 +- source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c | 1026 +++++++++++++++++++++++++ source4/ntvfs/cifs_posix_cli/vfs_simple.c | 1025 ------------------------ source4/ntvfs/config.mk | 10 +- 4 files changed, 1032 insertions(+), 1031 deletions(-) create mode 100644 source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c delete mode 100644 source4/ntvfs/cifs_posix_cli/vfs_simple.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs_posix_cli/svfs_util.c b/source4/ntvfs/cifs_posix_cli/svfs_util.c index b85c43b071..4321a6eb29 100644 --- a/source4/ntvfs/cifs_posix_cli/svfs_util.c +++ b/source4/ntvfs/cifs_posix_cli/svfs_util.c @@ -26,10 +26,10 @@ #include "includes.h" #include "system/filesys.h" #include "cvfs.h" -#include "system/time.h" #include "system/dir.h" #include "ntvfs/ntvfs.h" + /* convert a windows path to a unix path - don't do any manging or case sensitive handling */ diff --git a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c new file mode 100644 index 0000000000..bd1195d896 --- /dev/null +++ b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c @@ -0,0 +1,1026 @@ +/* + Unix SMB/CIFS implementation. + + NTVFS filesystem backend for Linux CIFS client and clients which support + CIFS Unix extensions + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Steve French 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* this module needs to be converted to use ntvfs_handle's! */ +#define fnum _XXX_use_ntvfs_handle_not_fnum_XXX_ + +/* + this implements a very simple NTVFS filesystem backend. + + this backend largely ignores the POSIX -> CIFS mappings, just doing absolutely + minimal work to give a working backend. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "cvfs.h" +#include "lib/util/dlinklist.h" +#include "ntvfs/ntvfs.h" +#include "ntvfs/cifs_posix_cli/proto.h" + +#ifndef O_DIRECTORY +#define O_DIRECTORY 0 +#endif + +#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) + +/* + connect to a share - used when a tree_connect operation comes + in. For a disk based backend we needs to ensure that the base + directory exists (tho it doesn't need to be accessible by the user, + that comes later) +*/ +static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const char *sharename) +{ + struct stat st; + struct svfs_private *private; + + private = talloc(ntvfs, struct svfs_private); + + private->next_search_handle = 0; + private->connectpath = talloc_strdup(private, share_string_option(ntvfs->ctx->config, SHARE_PATH, "")); + private->open_files = NULL; + private->search = NULL; + + DEBUG(0,("cifs backend: connect to %s",sharename)); + /* the directory must exist */ + if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { + DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", + private->connectpath, sharename)); + return NT_STATUS_BAD_NETWORK_NAME; + } + + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + + ntvfs->private_data = private; + + DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs) +{ + return NT_STATUS_OK; +} + +/* + find open file handle given fd +*/ +static struct svfs_file *find_fd(struct svfs_private *private, int fd) +{ + struct svfs_file *f; + for (f=private->open_files;f;f=f->next) { + if (f->fd == fd) { + return f; + } + } + return NULL; +} + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_unlink *unl) +{ + char *unix_path; + + CHECK_READ_ONLY(req); + + unix_path = cvfs_unix_path(ntvfs, req, unl->unlink.in.pattern); + + /* ignoring wildcards ... */ + if (unlink(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + + +/* + ioctl interface - we don't do any +*/ +static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_ioctl *io) +{ + return NT_STATUS_INVALID_PARAMETER; +} + +/* + check if a directory exists +*/ +static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_chkpath *cp) +{ + char *unix_path; + struct stat st; + + unix_path = cvfs_unix_path(ntvfs, req, cp->chkpath.in.path); + + if (stat(unix_path, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + if (!S_ISDIR(st.st_mode)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + + return NT_STATUS_OK; +} + +/* + build a file_id from a stat struct +*/ +static uint64_t svfs_file_id(struct stat *st) +{ + uint64_t ret = st->st_ino; + ret <<= 32; + ret |= st->st_dev; + return ret; +} + +/* + approximately map a struct stat to a generic fileinfo struct +*/ +static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info, + struct stat *st, const char *unix_path) +{ + struct svfs_dir *dir = NULL; + char *pattern = NULL; + int i; + const char *s, *short_name; + + s = strrchr(unix_path, '/'); + if (s) { + short_name = s+1; + } else { + short_name = ""; + } + + asprintf(&pattern, "%s:*", unix_path); + + if (pattern) { + dir = cvfs_list_unix(req, req, pattern); + } + + unix_to_nt_time(&info->generic.out.create_time, st->st_ctime); + unix_to_nt_time(&info->generic.out.access_time, st->st_atime); + unix_to_nt_time(&info->generic.out.write_time, st->st_mtime); + unix_to_nt_time(&info->generic.out.change_time, st->st_mtime); + info->generic.out.alloc_size = st->st_size; + info->generic.out.size = st->st_size; + info->generic.out.attrib = cvfs_unix_to_dos_attrib(st->st_mode); + info->generic.out.alloc_size = st->st_blksize * st->st_blocks; + info->generic.out.nlink = st->st_nlink; + info->generic.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; + info->generic.out.file_id = svfs_file_id(st); + /* REWRITE: TODO stuff in here */ + info->generic.out.delete_pending = 0; + info->generic.out.ea_size = 0; + info->generic.out.num_eas = 0; + info->generic.out.fname.s = talloc_strdup(req, short_name); + info->generic.out.alt_fname.s = talloc_strdup(req, short_name); + info->generic.out.compressed_size = 0; + info->generic.out.format = 0; + info->generic.out.unit_shift = 0; + info->generic.out.chunk_shift = 0; + info->generic.out.cluster_shift = 0; + + info->generic.out.access_flags = 0; + info->generic.out.position = 0; + info->generic.out.mode = 0; + info->generic.out.alignment_requirement = 0; + info->generic.out.reparse_tag = 0; + info->generic.out.num_streams = 0; + /* setup a single data stream */ + info->generic.out.num_streams = 1 + (dir?dir->count:0); + info->generic.out.streams = talloc_array(req, + struct stream_struct, + info->generic.out.num_streams); + if (!info->generic.out.streams) { + return NT_STATUS_NO_MEMORY; + } + info->generic.out.streams[0].size = st->st_size; + info->generic.out.streams[0].alloc_size = st->st_size; + info->generic.out.streams[0].stream_name.s = talloc_strdup(req,"::$DATA"); + + for (i=0;dir && icount;i++) { + s = strchr(dir->files[i].name, ':'); + info->generic.out.streams[1+i].size = dir->files[i].st.st_size; + info->generic.out.streams[1+i].alloc_size = dir->files[i].st.st_size; + info->generic.out.streams[1+i].stream_name.s = s?s:dir->files[i].name; + } + + return NT_STATUS_OK; +} + +/* + return info on a pathname +*/ +static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + char *unix_path; + struct stat st; + + DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.file.path, info->generic.level)); + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qpathinfo(ntvfs, req, info); + } + + unix_path = cvfs_unix_path(ntvfs, req, info->generic.in.file.path); + DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); + if (stat(unix_path, &st) == -1) { + DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); + return svfs_map_fileinfo(ntvfs, req, info, &st, unix_path); +} + +/* + query info on a open file +*/ +static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; + struct stat st; + + if (info->generic.level != RAW_FILEINFO_GENERIC) { + return ntvfs_map_qfileinfo(ntvfs, req, info); + } + + f = find_fd(private, info->generic.in.file.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + if (fstat(info->generic.in.file.fnum, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + return svfs_map_fileinfo(ntvfs, req,info, &st, f->name); +} + + +/* + open a file +*/ +static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io) +{ + struct svfs_private *private = ntvfs->private_data; + char *unix_path; + struct stat st; + int fd, flags; + struct svfs_file *f; + int create_flags, rdwr_flags; + BOOL readonly; + + if (io->generic.level != RAW_OPEN_GENERIC) { + return ntvfs_map_open(ntvfs, req, io); + } + + readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True); + if (readonly) { + create_flags = 0; + rdwr_flags = O_RDONLY; + } else { + create_flags = O_CREAT; + rdwr_flags = O_RDWR; + } + + unix_path = cvfs_unix_path(ntvfs, req, io->ntcreatex.in.fname); + + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_SUPERSEDE: + case NTCREATEX_DISP_OVERWRITE_IF: + flags = create_flags | O_TRUNC; + break; + case NTCREATEX_DISP_OPEN: + case NTCREATEX_DISP_OVERWRITE: + flags = 0; + break; + case NTCREATEX_DISP_CREATE: + flags = create_flags | O_EXCL; + break; + case NTCREATEX_DISP_OPEN_IF: + flags = create_flags; + break; + default: + flags = 0; + break; + } + + flags |= rdwr_flags; + + if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { + flags = O_RDONLY | O_DIRECTORY; + if (readonly) { + goto do_open; + } + switch (io->generic.in.open_disposition) { + case NTCREATEX_DISP_CREATE: + if (mkdir(unix_path, 0755) == -1) { + DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + break; + case NTCREATEX_DISP_OPEN_IF: + if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { + DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + return map_nt_error_from_unix(errno); + } + break; + } + } + +do_open: + fd = open(unix_path, flags, 0644); + if (fd == -1) { + return map_nt_error_from_unix(errno); + } + + if (fstat(fd, &st) == -1) { + DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); + close(fd); + return map_nt_error_from_unix(errno); + } + + f = talloc(ntvfs, struct svfs_file); + NT_STATUS_HAVE_NO_MEMORY(f); + f->fd = fd; + f->name = talloc_strdup(f, unix_path); + NT_STATUS_HAVE_NO_MEMORY(f->name); + + DLIST_ADD(private->open_files, f); + + ZERO_STRUCT(io->generic.out); + + unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); + unix_to_nt_time(&io->generic.out.access_time, st.st_atime); + unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); + unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); + io->generic.out.file.fnum = fd; + io->generic.out.alloc_size = st.st_size; + io->generic.out.size = st.st_size; + io->generic.out.attrib = cvfs_unix_to_dos_attrib(st.st_mode); + io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; + + return NT_STATUS_OK; +} + +/* + create a directory +*/ +static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_mkdir *md) +{ + char *unix_path; + + CHECK_READ_ONLY(req); + + if (md->generic.level != RAW_MKDIR_MKDIR) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path = cvfs_unix_path(ntvfs, req, md->mkdir.in.path); + + if (mkdir(unix_path, 0777) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + remove a directory +*/ +static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_rmdir *rd) +{ + char *unix_path; + + CHECK_READ_ONLY(req); + + unix_path = cvfs_unix_path(ntvfs, req, rd->in.path); + + if (rmdir(unix_path) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + rename a set of files +*/ +static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_rename *ren) +{ + char *unix_path1, *unix_path2; + + CHECK_READ_ONLY(req); + + if (ren->generic.level != RAW_RENAME_RENAME) { + return NT_STATUS_INVALID_LEVEL; + } + + unix_path1 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern1); + unix_path2 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern2); + + if (rename(unix_path1, unix_path2) == -1) { + return map_nt_error_from_unix(errno); + } + + return NT_STATUS_OK; +} + +/* + copy a set of files +*/ +static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + read from a file +*/ +static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_read *rd) +{ + ssize_t ret; + + if (rd->generic.level != RAW_READ_READX) { + return NT_STATUS_NOT_SUPPORTED; + } + + ret = pread(rd->readx.in.file.fnum, + rd->readx.out.data, + rd->readx.in.maxcnt, + rd->readx.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + rd->readx.out.nread = ret; + rd->readx.out.remaining = 0; /* should fill this in? */ + rd->readx.out.compaction_mode = 0; + + return NT_STATUS_OK; +} + +/* + write to a file +*/ +static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_write *wr) +{ + ssize_t ret; + + if (wr->generic.level != RAW_WRITE_WRITEX) { + return ntvfs_map_write(ntvfs, req, wr); + } + + CHECK_READ_ONLY(req); + + ret = pwrite(wr->writex.in.file.fnum, + wr->writex.in.data, + wr->writex.in.count, + wr->writex.in.offset); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; /* should fill this in? */ + + return NT_STATUS_OK; +} + +/* + seek in a file +*/ +static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_seek *io) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + flush a file +*/ +static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_flush *io) +{ + fsync(io->flush.in.file.fnum); + return NT_STATUS_OK; +} + +/* + close a file +*/ +static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_close *io) +{ + struct svfs_private *private = ntvfs->private_data; + struct svfs_file *f; + + if (io->generic.level != RAW_CLOSE_CLOSE) { + /* we need a mapping function */ + return NT_STATUS_INVALID_LEVEL; + } + + f = find_fd(private, io->close.in.file.fnum); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + if (close(io->close.in.file.fnum) == -1) { + return map_nt_error_from_unix(errno); + } + + DLIST_REMOVE(private->open_files, f); + talloc_free(f->name); + talloc_free(f); + + return NT_STATUS_OK; +} + +/* + exit - closing files +*/ +static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + logoff - closing files +*/ +static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + setup for an async call +*/ +static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* + cancel an async call +*/ +static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) +{ + return NT_STATUS_UNSUCCESSFUL; +} + +/* + lock a byte range +*/ +static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lock *lck) +{ + DEBUG(0,("REWRITE: not doing byte range locking!\n")); + return NT_STATUS_OK; +} + +/* + set info on a pathname +*/ +static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_setfileinfo *st) +{ + CHECK_READ_ONLY(req); + + return NT_STATUS_NOT_SUPPORTED; +} + +/* + set info on a open file +*/ +static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *info) +{ + struct utimbuf unix_times; + int fd; + + CHECK_READ_ONLY(req); + + switch (info->generic.level) { + case RAW_SFILEINFO_END_OF_FILE_INFO: + case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + if (ftruncate(info->end_of_file_info.in.file.fnum, + info->end_of_file_info.in.size) == -1) { + return map_nt_error_from_unix(errno); + } + break; + case RAW_SFILEINFO_SETATTRE: + unix_times.actime = info->setattre.in.access_time; + unix_times.modtime = info->setattre.in.write_time; + fd = info->setattre.in.file.fnum; + + if (unix_times.actime == 0 && unix_times.modtime == 0) { + break; + } + + /* set modify time = to access time if modify time was 0 */ + if (unix_times.actime != 0 && unix_times.modtime == 0) { + unix_times.modtime = unix_times.actime; + } + + /* Set the date on this file */ + if (cvfs_file_utime(fd, &unix_times) != 0) { + return NT_STATUS_ACCESS_DENIED; + } + break; + default: + DEBUG(2,("svfs_setfileinfo: level %d not implemented\n", + info->generic.level)); + return NT_STATUS_NOT_IMPLEMENTED; + } + return NT_STATUS_OK; +} + + +/* + return filesystem space info +*/ +static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fsinfo *fs) +{ + struct svfs_private *private = ntvfs->private_data; + struct stat st; + + if (fs->generic.level != RAW_QFS_GENERIC) { + return ntvfs_map_fsinfo(ntvfs, req, fs); + } + + if (sys_fsusage(private->connectpath, + &fs->generic.out.blocks_free, + &fs->generic.out.blocks_total) == -1) { + return map_nt_error_from_unix(errno); + } + + fs->generic.out.block_size = 512; + + if (stat(private->connectpath, &st) != 0) { + return NT_STATUS_DISK_CORRUPT_ERROR; + } + + fs->generic.out.fs_id = st.st_ino; + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.serial_number = st.st_ino; + fs->generic.out.fs_attr = 0; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.device_type = 0; + fs->generic.out.device_characteristics = 0; + fs->generic.out.quota_soft = 0; + fs->generic.out.quota_hard = 0; + fs->generic.out.quota_flags = 0; + fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name); + fs->generic.out.fs_type = ntvfs->ctx->fs_type; + + return NT_STATUS_OK; +} + +#if 0 +/* + return filesystem attribute info +*/ +static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fsattr *fs) +{ + struct stat st; + struct svfs_private *private = ntvfs->private_data; + + if (fs->generic.level != RAW_FSATTR_GENERIC) { + return ntvfs_map_fsattr(ntvfs, req, fs); + } + + if (stat(private->connectpath, &st) == -1) { + return map_nt_error_from_unix(errno); + } + + unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); + fs->generic.out.fs_attr = + FILE_CASE_PRESERVED_NAMES | + FILE_CASE_SENSITIVE_SEARCH | + FILE_PERSISTENT_ACLS; + fs->generic.out.max_file_component_length = 255; + fs->generic.out.serial_number = 1; + fs->generic.out.fs_type = talloc_strdup(req, "NTFS"); + fs->generic.out.volume_name = talloc_strdup(req, + lp_servicename(req->tcon->service)); + + return NT_STATUS_OK; +} +#endif + +/* + return print queue info +*/ +static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_first *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = ntvfs->private_data; + struct search_state *search; + union smb_search_data file; + uint_t max_count; + + if (io->generic.level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { + return NT_STATUS_NOT_SUPPORTED; + } + + search = talloc_zero(private, struct search_state); + if (!search) { + return NT_STATUS_NO_MEMORY; + } + + max_count = io->t2ffirst.in.max_count; + + dir = cvfs_list(ntvfs, req, io->t2ffirst.in.pattern); + if (!dir) { + return NT_STATUS_FOOBAR; + } + + search->handle = private->next_search_handle; + search->dir = dir; + + if (dir->count < max_count) { + max_count = dir->count; + } + + for (i=0; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); + file.both_directory_info.name.s = dir->files[i].name; + file.both_directory_info.short_name.s = dir->files[i].name; + file.both_directory_info.size = dir->files[i].st.st_size; + file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + + if (!callback(search_private, &file)) { + break; + } + } + + search->current_index = i; + + io->t2ffirst.out.count = i; + io->t2ffirst.out.handle = search->handle; + io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; + + /* work out if we are going to keep the search state */ + if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + talloc_free(search); + } else { + private->next_search_handle++; + DLIST_ADD(private->search, search); + } + + return NT_STATUS_OK; +} + +/* continue a search */ +static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_next *io, + void *search_private, + BOOL (*callback)(void *, union smb_search_data *)) +{ + struct svfs_dir *dir; + int i; + struct svfs_private *private = ntvfs->private_data; + struct search_state *search; + union smb_search_data file; + uint_t max_count; + + if (io->generic.level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { + return NT_STATUS_NOT_SUPPORTED; + } + + for (search=private->search; search; search = search->next) { + if (search->handle == io->t2fnext.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + dir = search->dir; + + /* the client might be asking for something other than just continuing + with the search */ + if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && + (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && + io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { + /* look backwards first */ + for (i=search->current_index; i > 0; i--) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + + /* then look forwards */ + for (i=search->current_index+1; i <= dir->count; i++) { + if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { + search->current_index = i; + goto found; + } + } + } + +found: + max_count = search->current_index + io->t2fnext.in.max_count; + + if (max_count > dir->count) { + max_count = dir->count; + } + + for (i = search->current_index; i < max_count;i++) { + ZERO_STRUCT(file); + unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); + unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); + unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); + unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); + file.both_directory_info.name.s = dir->files[i].name; + file.both_directory_info.short_name.s = dir->files[i].name; + file.both_directory_info.size = dir->files[i].st.st_size; + file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + + if (!callback(search_private, &file)) { + break; + } + } + + io->t2fnext.out.count = i - search->current_index; + io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; + + search->current_index = i; + + /* work out if we are going to keep the search state */ + if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || + ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { + DLIST_REMOVE(private->search, search); + talloc_free(search); + } + + return NT_STATUS_OK; +} + +/* close a search */ +static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_close *io) +{ + struct svfs_private *private = ntvfs->private_data; + struct search_state *search; + + for (search=private->search; search; search = search->next) { + if (search->handle == io->findclose.in.handle) break; + } + + if (!search) { + /* we didn't find the search handle */ + return NT_STATUS_FOOBAR; + } + + DLIST_REMOVE(private->search, search); + talloc_free(search); + + return NT_STATUS_OK; +} + +/* SMBtrans - not used on file shares */ +static NTSTATUS svfs_trans(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_trans2 *trans2) +{ + return NT_STATUS_ACCESS_DENIED; +} + + +/* + initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem + */ +NTSTATUS ntvfs_cifs_posix_init(void) +{ + NTSTATUS ret; + struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); + + ZERO_STRUCT(ops); + + /* fill in all the operations */ + ops.connect = svfs_connect; + ops.disconnect = svfs_disconnect; + ops.unlink = svfs_unlink; + ops.chkpath = svfs_chkpath; + ops.qpathinfo = svfs_qpathinfo; + ops.setpathinfo = svfs_setpathinfo; + ops.open = svfs_open; + ops.mkdir = svfs_mkdir; + ops.rmdir = svfs_rmdir; + ops.rename = svfs_rename; + ops.copy = svfs_copy; + ops.ioctl = svfs_ioctl; + ops.read = svfs_read; + ops.write = svfs_write; + ops.seek = svfs_seek; + ops.flush = svfs_flush; + ops.close = svfs_close; + ops.exit = svfs_exit; + ops.lock = svfs_lock; + ops.setfileinfo = svfs_setfileinfo; + ops.qfileinfo = svfs_qfileinfo; + ops.fsinfo = svfs_fsinfo; + ops.lpq = svfs_lpq; + ops.search_first = svfs_search_first; + ops.search_next = svfs_search_next; + ops.search_close = svfs_search_close; + ops.trans = svfs_trans; + ops.logoff = svfs_logoff; + ops.async_setup = svfs_async_setup; + ops.cancel = svfs_cancel; + + /* register ourselves with the NTVFS subsystem. We register + under name 'cifsposix' + */ + + ops.type = NTVFS_DISK; + ops.name = "cifsposix"; + ret = ntvfs_register(&ops, &vers); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register simple backend with name: %s!\n", + ops.name)); + } + + return ret; +} diff --git a/source4/ntvfs/cifs_posix_cli/vfs_simple.c b/source4/ntvfs/cifs_posix_cli/vfs_simple.c deleted file mode 100644 index 2fd5572c0c..0000000000 --- a/source4/ntvfs/cifs_posix_cli/vfs_simple.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - simple NTVFS filesystem backend - - Copyright (C) Andrew Tridgell 2003 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* this module needs to be converted to use ntvfs_handle's! */ -#define fnum _XXX_use_ntvfs_handle_not_fnum_XXX_ - -/* - this implements a very simple NTVFS filesystem backend. - - this backend largely ignores the POSIX -> CIFS mappings, just doing absolutely - minimal work to give a working backend. -*/ - -#include "includes.h" -#include "system/dir.h" -#include "system/filesys.h" -#include "cvfs.h" -#include "system/time.h" -#include "lib/util/dlinklist.h" -#include "ntvfs/ntvfs.h" -#include "ntvfs/cifs_posix_cli/proto.h" - -#ifndef O_DIRECTORY -#define O_DIRECTORY 0 -#endif - -#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) - -/* - connect to a share - used when a tree_connect operation comes - in. For a disk based backend we needs to ensure that the base - directory exists (tho it doesn't need to be accessible by the user, - that comes later) -*/ -static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, const char *sharename) -{ - struct stat st; - struct svfs_private *private; - - private = talloc(ntvfs, struct svfs_private); - - private->next_search_handle = 0; - private->connectpath = talloc_strdup(private, share_string_option(ntvfs->ctx->config, SHARE_PATH, "")); - private->open_files = NULL; - private->search = NULL; - - /* the directory must exist */ - if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { - DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", - private->connectpath, sharename)); - return NT_STATUS_BAD_NETWORK_NAME; - } - - ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); - NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); - ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); - NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); - - ntvfs->private_data = private; - - DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); - - return NT_STATUS_OK; -} - -/* - disconnect from a share -*/ -static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs) -{ - return NT_STATUS_OK; -} - -/* - find open file handle given fd -*/ -static struct svfs_file *find_fd(struct svfs_private *private, int fd) -{ - struct svfs_file *f; - for (f=private->open_files;f;f=f->next) { - if (f->fd == fd) { - return f; - } - } - return NULL; -} - -/* - delete a file - the dirtype specifies the file types to include in the search. - The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) -*/ -static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - union smb_unlink *unl) -{ - char *unix_path; - - CHECK_READ_ONLY(req); - - unix_path = cvfs_unix_path(ntvfs, req, unl->unlink.in.pattern); - - /* ignoring wildcards ... */ - if (unlink(unix_path) == -1) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - - -/* - ioctl interface - we don't do any -*/ -static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_ioctl *io) -{ - return NT_STATUS_INVALID_PARAMETER; -} - -/* - check if a directory exists -*/ -static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - union smb_chkpath *cp) -{ - char *unix_path; - struct stat st; - - unix_path = cvfs_unix_path(ntvfs, req, cp->chkpath.in.path); - - if (stat(unix_path, &st) == -1) { - return map_nt_error_from_unix(errno); - } - - if (!S_ISDIR(st.st_mode)) { - return NT_STATUS_NOT_A_DIRECTORY; - } - - return NT_STATUS_OK; -} - -/* - build a file_id from a stat struct -*/ -static uint64_t svfs_file_id(struct stat *st) -{ - uint64_t ret = st->st_ino; - ret <<= 32; - ret |= st->st_dev; - return ret; -} - -/* - approximately map a struct stat to a generic fileinfo struct -*/ -static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fileinfo *info, - struct stat *st, const char *unix_path) -{ - struct svfs_dir *dir = NULL; - char *pattern = NULL; - int i; - const char *s, *short_name; - - s = strrchr(unix_path, '/'); - if (s) { - short_name = s+1; - } else { - short_name = ""; - } - - asprintf(&pattern, "%s:*", unix_path); - - if (pattern) { - dir = cvfs_list_unix(req, req, pattern); - } - - unix_to_nt_time(&info->generic.out.create_time, st->st_ctime); - unix_to_nt_time(&info->generic.out.access_time, st->st_atime); - unix_to_nt_time(&info->generic.out.write_time, st->st_mtime); - unix_to_nt_time(&info->generic.out.change_time, st->st_mtime); - info->generic.out.alloc_size = st->st_size; - info->generic.out.size = st->st_size; - info->generic.out.attrib = cvfs_unix_to_dos_attrib(st->st_mode); - info->generic.out.alloc_size = st->st_blksize * st->st_blocks; - info->generic.out.nlink = st->st_nlink; - info->generic.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; - info->generic.out.file_id = svfs_file_id(st); - /* REWRITE: TODO stuff in here */ - info->generic.out.delete_pending = 0; - info->generic.out.ea_size = 0; - info->generic.out.num_eas = 0; - info->generic.out.fname.s = talloc_strdup(req, short_name); - info->generic.out.alt_fname.s = talloc_strdup(req, short_name); - info->generic.out.compressed_size = 0; - info->generic.out.format = 0; - info->generic.out.unit_shift = 0; - info->generic.out.chunk_shift = 0; - info->generic.out.cluster_shift = 0; - - info->generic.out.access_flags = 0; - info->generic.out.position = 0; - info->generic.out.mode = 0; - info->generic.out.alignment_requirement = 0; - info->generic.out.reparse_tag = 0; - info->generic.out.num_streams = 0; - /* setup a single data stream */ - info->generic.out.num_streams = 1 + (dir?dir->count:0); - info->generic.out.streams = talloc_array(req, - struct stream_struct, - info->generic.out.num_streams); - if (!info->generic.out.streams) { - return NT_STATUS_NO_MEMORY; - } - info->generic.out.streams[0].size = st->st_size; - info->generic.out.streams[0].alloc_size = st->st_size; - info->generic.out.streams[0].stream_name.s = talloc_strdup(req,"::$DATA"); - - for (i=0;dir && icount;i++) { - s = strchr(dir->files[i].name, ':'); - info->generic.out.streams[1+i].size = dir->files[i].st.st_size; - info->generic.out.streams[1+i].alloc_size = dir->files[i].st.st_size; - info->generic.out.streams[1+i].stream_name.s = s?s:dir->files[i].name; - } - - return NT_STATUS_OK; -} - -/* - return info on a pathname -*/ -static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fileinfo *info) -{ - char *unix_path; - struct stat st; - - DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.file.path, info->generic.level)); - if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qpathinfo(ntvfs, req, info); - } - - unix_path = cvfs_unix_path(ntvfs, req, info->generic.in.file.path); - DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); - if (stat(unix_path, &st) == -1) { - DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); - } - DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); - return svfs_map_fileinfo(ntvfs, req, info, &st, unix_path); -} - -/* - query info on a open file -*/ -static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fileinfo *info) -{ - struct svfs_private *private = ntvfs->private_data; - struct svfs_file *f; - struct stat st; - - if (info->generic.level != RAW_FILEINFO_GENERIC) { - return ntvfs_map_qfileinfo(ntvfs, req, info); - } - - f = find_fd(private, info->generic.in.file.fnum); - if (!f) { - return NT_STATUS_INVALID_HANDLE; - } - - if (fstat(info->generic.in.file.fnum, &st) == -1) { - return map_nt_error_from_unix(errno); - } - - return svfs_map_fileinfo(ntvfs, req,info, &st, f->name); -} - - -/* - open a file -*/ -static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_open *io) -{ - struct svfs_private *private = ntvfs->private_data; - char *unix_path; - struct stat st; - int fd, flags; - struct svfs_file *f; - int create_flags, rdwr_flags; - BOOL readonly; - - if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(ntvfs, req, io); - } - - readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True); - if (readonly) { - create_flags = 0; - rdwr_flags = O_RDONLY; - } else { - create_flags = O_CREAT; - rdwr_flags = O_RDWR; - } - - unix_path = cvfs_unix_path(ntvfs, req, io->ntcreatex.in.fname); - - switch (io->generic.in.open_disposition) { - case NTCREATEX_DISP_SUPERSEDE: - case NTCREATEX_DISP_OVERWRITE_IF: - flags = create_flags | O_TRUNC; - break; - case NTCREATEX_DISP_OPEN: - case NTCREATEX_DISP_OVERWRITE: - flags = 0; - break; - case NTCREATEX_DISP_CREATE: - flags = create_flags | O_EXCL; - break; - case NTCREATEX_DISP_OPEN_IF: - flags = create_flags; - break; - default: - flags = 0; - break; - } - - flags |= rdwr_flags; - - if (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) { - flags = O_RDONLY | O_DIRECTORY; - if (readonly) { - goto do_open; - } - switch (io->generic.in.open_disposition) { - case NTCREATEX_DISP_CREATE: - if (mkdir(unix_path, 0755) == -1) { - DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); - } - break; - case NTCREATEX_DISP_OPEN_IF: - if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { - DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); - return map_nt_error_from_unix(errno); - } - break; - } - } - -do_open: - fd = open(unix_path, flags, 0644); - if (fd == -1) { - return map_nt_error_from_unix(errno); - } - - if (fstat(fd, &st) == -1) { - DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); - close(fd); - return map_nt_error_from_unix(errno); - } - - f = talloc(ntvfs, struct svfs_file); - NT_STATUS_HAVE_NO_MEMORY(f); - f->fd = fd; - f->name = talloc_strdup(f, unix_path); - NT_STATUS_HAVE_NO_MEMORY(f->name); - - DLIST_ADD(private->open_files, f); - - ZERO_STRUCT(io->generic.out); - - unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); - unix_to_nt_time(&io->generic.out.access_time, st.st_atime); - unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); - unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); - io->generic.out.file.fnum = fd; - io->generic.out.alloc_size = st.st_size; - io->generic.out.size = st.st_size; - io->generic.out.attrib = cvfs_unix_to_dos_attrib(st.st_mode); - io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; - - return NT_STATUS_OK; -} - -/* - create a directory -*/ -static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_mkdir *md) -{ - char *unix_path; - - CHECK_READ_ONLY(req); - - if (md->generic.level != RAW_MKDIR_MKDIR) { - return NT_STATUS_INVALID_LEVEL; - } - - unix_path = cvfs_unix_path(ntvfs, req, md->mkdir.in.path); - - if (mkdir(unix_path, 0777) == -1) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -/* - remove a directory -*/ -static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_rmdir *rd) -{ - char *unix_path; - - CHECK_READ_ONLY(req); - - unix_path = cvfs_unix_path(ntvfs, req, rd->in.path); - - if (rmdir(unix_path) == -1) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -/* - rename a set of files -*/ -static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_rename *ren) -{ - char *unix_path1, *unix_path2; - - CHECK_READ_ONLY(req); - - if (ren->generic.level != RAW_RENAME_RENAME) { - return NT_STATUS_INVALID_LEVEL; - } - - unix_path1 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern1); - unix_path2 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern2); - - if (rename(unix_path1, unix_path2) == -1) { - return map_nt_error_from_unix(errno); - } - - return NT_STATUS_OK; -} - -/* - copy a set of files -*/ -static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_copy *cp) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - read from a file -*/ -static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_read *rd) -{ - ssize_t ret; - - if (rd->generic.level != RAW_READ_READX) { - return NT_STATUS_NOT_SUPPORTED; - } - - ret = pread(rd->readx.in.file.fnum, - rd->readx.out.data, - rd->readx.in.maxcnt, - rd->readx.in.offset); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - rd->readx.out.nread = ret; - rd->readx.out.remaining = 0; /* should fill this in? */ - rd->readx.out.compaction_mode = 0; - - return NT_STATUS_OK; -} - -/* - write to a file -*/ -static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_write *wr) -{ - ssize_t ret; - - if (wr->generic.level != RAW_WRITE_WRITEX) { - return ntvfs_map_write(ntvfs, req, wr); - } - - CHECK_READ_ONLY(req); - - ret = pwrite(wr->writex.in.file.fnum, - wr->writex.in.data, - wr->writex.in.count, - wr->writex.in.offset); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - wr->writex.out.nwritten = ret; - wr->writex.out.remaining = 0; /* should fill this in? */ - - return NT_STATUS_OK; -} - -/* - seek in a file -*/ -static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - union smb_seek *io) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - flush a file -*/ -static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - union smb_flush *io) -{ - fsync(io->flush.in.file.fnum); - return NT_STATUS_OK; -} - -/* - close a file -*/ -static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - union smb_close *io) -{ - struct svfs_private *private = ntvfs->private_data; - struct svfs_file *f; - - if (io->generic.level != RAW_CLOSE_CLOSE) { - /* we need a mapping function */ - return NT_STATUS_INVALID_LEVEL; - } - - f = find_fd(private, io->close.in.file.fnum); - if (!f) { - return NT_STATUS_INVALID_HANDLE; - } - - if (close(io->close.in.file.fnum) == -1) { - return map_nt_error_from_unix(errno); - } - - DLIST_REMOVE(private->open_files, f); - talloc_free(f->name); - talloc_free(f); - - return NT_STATUS_OK; -} - -/* - exit - closing files -*/ -static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - logoff - closing files -*/ -static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - setup for an async call -*/ -static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - void *private) -{ - return NT_STATUS_OK; -} - -/* - cancel an async call -*/ -static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) -{ - return NT_STATUS_UNSUCCESSFUL; -} - -/* - lock a byte range -*/ -static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_lock *lck) -{ - DEBUG(0,("REWRITE: not doing byte range locking!\n")); - return NT_STATUS_OK; -} - -/* - set info on a pathname -*/ -static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_setfileinfo *st) -{ - CHECK_READ_ONLY(req); - - return NT_STATUS_NOT_SUPPORTED; -} - -/* - set info on a open file -*/ -static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - union smb_setfileinfo *info) -{ - struct utimbuf unix_times; - int fd; - - CHECK_READ_ONLY(req); - - switch (info->generic.level) { - case RAW_SFILEINFO_END_OF_FILE_INFO: - case RAW_SFILEINFO_END_OF_FILE_INFORMATION: - if (ftruncate(info->end_of_file_info.in.file.fnum, - info->end_of_file_info.in.size) == -1) { - return map_nt_error_from_unix(errno); - } - break; - case RAW_SFILEINFO_SETATTRE: - unix_times.actime = info->setattre.in.access_time; - unix_times.modtime = info->setattre.in.write_time; - fd = info->setattre.in.file.fnum; - - if (unix_times.actime == 0 && unix_times.modtime == 0) { - break; - } - - /* set modify time = to access time if modify time was 0 */ - if (unix_times.actime != 0 && unix_times.modtime == 0) { - unix_times.modtime = unix_times.actime; - } - - /* Set the date on this file */ - if (cvfs_file_utime(fd, &unix_times) != 0) { - return NT_STATUS_ACCESS_DENIED; - } - break; - default: - DEBUG(2,("svfs_setfileinfo: level %d not implemented\n", - info->generic.level)); - return NT_STATUS_NOT_IMPLEMENTED; - } - return NT_STATUS_OK; -} - - -/* - return filesystem space info -*/ -static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fsinfo *fs) -{ - struct svfs_private *private = ntvfs->private_data; - struct stat st; - - if (fs->generic.level != RAW_QFS_GENERIC) { - return ntvfs_map_fsinfo(ntvfs, req, fs); - } - - if (sys_fsusage(private->connectpath, - &fs->generic.out.blocks_free, - &fs->generic.out.blocks_total) == -1) { - return map_nt_error_from_unix(errno); - } - - fs->generic.out.block_size = 512; - - if (stat(private->connectpath, &st) != 0) { - return NT_STATUS_DISK_CORRUPT_ERROR; - } - - fs->generic.out.fs_id = st.st_ino; - unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); - fs->generic.out.serial_number = st.st_ino; - fs->generic.out.fs_attr = 0; - fs->generic.out.max_file_component_length = 255; - fs->generic.out.device_type = 0; - fs->generic.out.device_characteristics = 0; - fs->generic.out.quota_soft = 0; - fs->generic.out.quota_hard = 0; - fs->generic.out.quota_flags = 0; - fs->generic.out.volume_name = talloc_strdup(req, ntvfs->ctx->config->name); - fs->generic.out.fs_type = ntvfs->ctx->fs_type; - - return NT_STATUS_OK; -} - -#if 0 -/* - return filesystem attribute info -*/ -static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_fsattr *fs) -{ - struct stat st; - struct svfs_private *private = ntvfs->private_data; - - if (fs->generic.level != RAW_FSATTR_GENERIC) { - return ntvfs_map_fsattr(ntvfs, req, fs); - } - - if (stat(private->connectpath, &st) == -1) { - return map_nt_error_from_unix(errno); - } - - unix_to_nt_time(&fs->generic.out.create_time, st.st_ctime); - fs->generic.out.fs_attr = - FILE_CASE_PRESERVED_NAMES | - FILE_CASE_SENSITIVE_SEARCH | - FILE_PERSISTENT_ACLS; - fs->generic.out.max_file_component_length = 255; - fs->generic.out.serial_number = 1; - fs->generic.out.fs_type = talloc_strdup(req, "NTFS"); - fs->generic.out.volume_name = talloc_strdup(req, - lp_servicename(req->tcon->service)); - - return NT_STATUS_OK; -} -#endif - -/* - return print queue info -*/ -static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_lpq *lpq) -{ - return NT_STATUS_NOT_SUPPORTED; -} - -/* - list files in a directory matching a wildcard pattern -*/ -static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_search_first *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - struct svfs_dir *dir; - int i; - struct svfs_private *private = ntvfs->private_data; - struct search_state *search; - union smb_search_data file; - uint_t max_count; - - if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { - return NT_STATUS_NOT_SUPPORTED; - } - - search = talloc_zero(private, struct search_state); - if (!search) { - return NT_STATUS_NO_MEMORY; - } - - max_count = io->t2ffirst.in.max_count; - - dir = cvfs_list(ntvfs, req, io->t2ffirst.in.pattern); - if (!dir) { - return NT_STATUS_FOOBAR; - } - - search->handle = private->next_search_handle; - search->dir = dir; - - if (dir->count < max_count) { - max_count = dir->count; - } - - for (i=0; i < max_count;i++) { - ZERO_STRUCT(file); - unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); - unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); - unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); - unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); - file.both_directory_info.name.s = dir->files[i].name; - file.both_directory_info.short_name.s = dir->files[i].name; - file.both_directory_info.size = dir->files[i].st.st_size; - file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); - - if (!callback(search_private, &file)) { - break; - } - } - - search->current_index = i; - - io->t2ffirst.out.count = i; - io->t2ffirst.out.handle = search->handle; - io->t2ffirst.out.end_of_search = (i == dir->count) ? 1 : 0; - - /* work out if we are going to keep the search state */ - if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) || - ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - talloc_free(search); - } else { - private->next_search_handle++; - DLIST_ADD(private->search, search); - } - - return NT_STATUS_OK; -} - -/* continue a search */ -static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_search_next *io, - void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) -{ - struct svfs_dir *dir; - int i; - struct svfs_private *private = ntvfs->private_data; - struct search_state *search; - union smb_search_data file; - uint_t max_count; - - if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) { - return NT_STATUS_NOT_SUPPORTED; - } - - for (search=private->search; search; search = search->next) { - if (search->handle == io->t2fnext.in.handle) break; - } - - if (!search) { - /* we didn't find the search handle */ - return NT_STATUS_FOOBAR; - } - - dir = search->dir; - - /* the client might be asking for something other than just continuing - with the search */ - if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE) && - (io->t2fnext.in.flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) && - io->t2fnext.in.last_name && *io->t2fnext.in.last_name) { - /* look backwards first */ - for (i=search->current_index; i > 0; i--) { - if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { - search->current_index = i; - goto found; - } - } - - /* then look forwards */ - for (i=search->current_index+1; i <= dir->count; i++) { - if (strcmp(io->t2fnext.in.last_name, dir->files[i-1].name) == 0) { - search->current_index = i; - goto found; - } - } - } - -found: - max_count = search->current_index + io->t2fnext.in.max_count; - - if (max_count > dir->count) { - max_count = dir->count; - } - - for (i = search->current_index; i < max_count;i++) { - ZERO_STRUCT(file); - unix_to_nt_time(&file.both_directory_info.create_time, dir->files[i].st.st_ctime); - unix_to_nt_time(&file.both_directory_info.access_time, dir->files[i].st.st_atime); - unix_to_nt_time(&file.both_directory_info.write_time, dir->files[i].st.st_mtime); - unix_to_nt_time(&file.both_directory_info.change_time, dir->files[i].st.st_mtime); - file.both_directory_info.name.s = dir->files[i].name; - file.both_directory_info.short_name.s = dir->files[i].name; - file.both_directory_info.size = dir->files[i].st.st_size; - file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); - - if (!callback(search_private, &file)) { - break; - } - } - - io->t2fnext.out.count = i - search->current_index; - io->t2fnext.out.end_of_search = (i == dir->count) ? 1 : 0; - - search->current_index = i; - - /* work out if we are going to keep the search state */ - if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) || - ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && (i == dir->count))) { - DLIST_REMOVE(private->search, search); - talloc_free(search); - } - - return NT_STATUS_OK; -} - -/* close a search */ -static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, union smb_search_close *io) -{ - struct svfs_private *private = ntvfs->private_data; - struct search_state *search; - - for (search=private->search; search; search = search->next) { - if (search->handle == io->findclose.in.handle) break; - } - - if (!search) { - /* we didn't find the search handle */ - return NT_STATUS_FOOBAR; - } - - DLIST_REMOVE(private->search, search); - talloc_free(search); - - return NT_STATUS_OK; -} - -/* SMBtrans - not used on file shares */ -static NTSTATUS svfs_trans(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, struct smb_trans2 *trans2) -{ - return NT_STATUS_ACCESS_DENIED; -} - - -/* - initialialise the POSIX disk backend, registering ourselves with the ntvfs subsystem - */ -NTSTATUS ntvfs_cifs_posix_init(void) -{ - NTSTATUS ret; - struct ntvfs_ops ops; - NTVFS_CURRENT_CRITICAL_SIZES(vers); - - ZERO_STRUCT(ops); - - /* fill in all the operations */ - ops.connect = svfs_connect; - ops.disconnect = svfs_disconnect; - ops.unlink = svfs_unlink; - ops.chkpath = svfs_chkpath; - ops.qpathinfo = svfs_qpathinfo; - ops.setpathinfo = svfs_setpathinfo; - ops.open = svfs_open; - ops.mkdir = svfs_mkdir; - ops.rmdir = svfs_rmdir; - ops.rename = svfs_rename; - ops.copy = svfs_copy; - ops.ioctl = svfs_ioctl; - ops.read = svfs_read; - ops.write = svfs_write; - ops.seek = svfs_seek; - ops.flush = svfs_flush; - ops.close = svfs_close; - ops.exit = svfs_exit; - ops.lock = svfs_lock; - ops.setfileinfo = svfs_setfileinfo; - ops.qfileinfo = svfs_qfileinfo; - ops.fsinfo = svfs_fsinfo; - ops.lpq = svfs_lpq; - ops.search_first = svfs_search_first; - ops.search_next = svfs_search_next; - ops.search_close = svfs_search_close; - ops.trans = svfs_trans; - ops.logoff = svfs_logoff; - ops.async_setup = svfs_async_setup; - ops.cancel = svfs_cancel; - - /* register ourselves with the NTVFS subsystem. We register - under names 'simple' - */ - - ops.type = NTVFS_DISK; - ops.name = "cifs-posix-cli"; - ret = ntvfs_register(&ops, &vers); - - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register simple backend with name: %s!\n", - ops.name)); - } - - return ret; -} diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index ce1e37dc54..a985348fdb 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -29,16 +29,16 @@ OBJ_FILES = \ ################################################ ################################################ -# Start MODULE ntvfs_cifs_posix_cli -[MODULE::ntvfs_cifs_posix] -ENABLE = NO +# Start MODULE ntvfs_cifsposix +[MODULE::ntvfs_cifsposix] +#ENABLE = NO INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h OBJ_FILES = \ - cifs_posix_cli/vfs_simple.o \ + cifs_posix_cli/vfs_cifs_posix.o \ cifs_posix_cli/svfs_util.o -# End MODULE ntvfs_cifs_posix_cli +# End MODULE ntvfs_cifsposix ################################################ ################################################ -- cgit From ee1d645881b085ab011c6cb2816a8bc926b905c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Sep 2006 20:57:29 +0000 Subject: r18568: this warning is not needed now that it is the job of the unixuid ntvfs module to handle euid (This used to be commit 6784058923ef532da882830296f9bb5f58cddb43) --- source4/ntvfs/simple/vfs_simple.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 7477f359fb..5bfc0f2e5c 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -76,8 +76,6 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; - DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); - return NT_STATUS_OK; } -- cgit From 1ce5df6c724f8d943b9c32c23f9e8e551630ac4a Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 15 Sep 2006 21:39:38 +0000 Subject: r18570: Fix up function names in cifs unix/posix extensions backend. Enable tiny quick test for torture for them (This used to be commit 64062d16a2cc215af320eb30827887eb2531e3b0) --- source4/ntvfs/cifs_posix_cli/README | 6 +- source4/ntvfs/cifs_posix_cli/cifsposix.h | 38 +++ source4/ntvfs/cifs_posix_cli/cvfs.h | 35 --- source4/ntvfs/cifs_posix_cli/svfs_util.c | 35 +-- source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c | 346 +++++++++++++++----------- 5 files changed, 262 insertions(+), 198 deletions(-) create mode 100644 source4/ntvfs/cifs_posix_cli/cifsposix.h delete mode 100644 source4/ntvfs/cifs_posix_cli/cvfs.h (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs_posix_cli/README b/source4/ntvfs/cifs_posix_cli/README index f1de5d9f80..2bc9283418 100644 --- a/source4/ntvfs/cifs_posix_cli/README +++ b/source4/ntvfs/cifs_posix_cli/README @@ -1,4 +1,6 @@ -This module (ntvfs 'simple') provides a very, very simple posix backend. +This module (ntvfs 'cifsposix') provides a simple posix backend which +provides better semantics for clients which implement the cifs unix +extensions or the newer cifs posix extensions WARNING: All file access is done as user 'root'!!! Only use this module for testing, with only test data!!! @@ -7,4 +9,4 @@ For activating this module use: [testshare] path = /tmp/testshare - nfvfs handler = simple + nfvfs handler = cifsposix diff --git a/source4/ntvfs/cifs_posix_cli/cifsposix.h b/source4/ntvfs/cifs_posix_cli/cifsposix.h new file mode 100644 index 0000000000..bf9e588b74 --- /dev/null +++ b/source4/ntvfs/cifs_posix_cli/cifsposix.h @@ -0,0 +1,38 @@ + +struct cifspsx_private { + struct ntvfs_module_context *ntvfs; + + /* the base directory */ + char *connectpath; + + /* a linked list of open searches */ + struct search_state *search; + + /* next available search handle */ + uint16_t next_search_handle; + + struct cifspsx_file *open_files; +}; + +struct cifspsx_dir { + unsigned int count; + char *unix_dir; + struct cifspsx_dirfile { + char *name; + struct stat st; + } *files; +}; + +struct cifspsx_file { + struct cifspsx_file *next, *prev; + int fd; + struct ntvfs_handle *handle; + char *name; +}; + +struct search_state { + struct search_state *next, *prev; + uint16_t handle; + unsigned int current_index; + struct cifspsx_dir *dir; +}; diff --git a/source4/ntvfs/cifs_posix_cli/cvfs.h b/source4/ntvfs/cifs_posix_cli/cvfs.h deleted file mode 100644 index 74e7b6c452..0000000000 --- a/source4/ntvfs/cifs_posix_cli/cvfs.h +++ /dev/null @@ -1,35 +0,0 @@ - -struct svfs_private { - /* the base directory */ - char *connectpath; - - /* a linked list of open searches */ - struct search_state *search; - - /* next available search handle */ - uint16_t next_search_handle; - - struct svfs_file *open_files; -}; - -struct svfs_dir { - unsigned int count; - char *unix_dir; - struct svfs_dirfile { - char *name; - struct stat st; - } *files; -}; - -struct svfs_file { - struct svfs_file *next, *prev; - int fd; - char *name; -}; - -struct search_state { - struct search_state *next, *prev; - uint16_t handle; - unsigned int current_index; - struct svfs_dir *dir; -}; diff --git a/source4/ntvfs/cifs_posix_cli/svfs_util.c b/source4/ntvfs/cifs_posix_cli/svfs_util.c index 4321a6eb29..5622d775ac 100644 --- a/source4/ntvfs/cifs_posix_cli/svfs_util.c +++ b/source4/ntvfs/cifs_posix_cli/svfs_util.c @@ -1,9 +1,12 @@ /* Unix SMB/CIFS implementation. - simple NTVFS filesystem backend + simpler Samba VFS filesystem backend for clients which support the + CIFS Unix Extensions or newer CIFS POSIX protocol extensions + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Steve French 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,23 +23,23 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* - utility functions for simple backend + utility functions for cifs posix backend */ #include "includes.h" #include "system/filesys.h" -#include "cvfs.h" +#include "cifsposix.h" +#include "system/time.h" #include "system/dir.h" #include "ntvfs/ntvfs.h" - /* convert a windows path to a unix path - don't do any manging or case sensitive handling */ -char *cvfs_unix_path(struct ntvfs_module_context *ntvfs, +char *cifspsx_unix_path(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *name) { - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; char *ret; if (*name != '\\') { @@ -57,16 +60,16 @@ char *cvfs_unix_path(struct ntvfs_module_context *ntvfs, returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *cvfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, const char *unix_path) +struct cifspsx_dir *cifspsx_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, const char *unix_path) { char *p, *mask; - struct svfs_dir *dir; + struct cifspsx_dir *dir; DIR *odir; struct dirent *dent; uint_t allocated = 0; char *low_mask; - dir = talloc(mem_ctx, struct svfs_dir); + dir = talloc(mem_ctx, struct cifspsx_dir); if (!dir) { return NULL; } dir->count = 0; @@ -110,7 +113,7 @@ struct svfs_dir *cvfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, if (dir->count >= allocated) { allocated = (allocated + 100) * 1.2; - dir->files = talloc_realloc(dir, dir->files, struct svfs_dirfile, allocated); + dir->files = talloc_realloc(dir, dir->files, struct cifspsx_dirfile, allocated); if (!dir->files) { closedir(odir); return NULL; @@ -140,22 +143,22 @@ struct svfs_dir *cvfs_list_unix(TALLOC_CTX *mem_ctx, struct ntvfs_request *req, returned names are separate unix and DOS names. The returned names are relative to the directory */ -struct svfs_dir *cvfs_list(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *pattern) +struct cifspsx_dir *cifspsx_list(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *pattern) { - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; char *unix_path; - unix_path = cvfs_unix_path(ntvfs, req, pattern); + unix_path = cifspsx_unix_path(ntvfs, req, pattern); if (!unix_path) { return NULL; } - return cvfs_list_unix(private, req, unix_path); + return cifspsx_list_unix(private, req, unix_path); } /******************************************************************* set the time on a file via file descriptor *******************************************************************/ -int cvfs_file_utime(int fd, struct utimbuf *times) +int cifspsx_file_utime(int fd, struct utimbuf *times) { char *fd_path = NULL; int ret; @@ -175,7 +178,7 @@ int cvfs_file_utime(int fd, struct utimbuf *times) /* map a unix file attrib to a DOS attribute */ -uint16_t cvfs_unix_to_dos_attrib(mode_t mode) +uint16_t cifspsx_unix_to_dos_attrib(mode_t mode) { uint16_t ret = 0; if (S_ISDIR(mode)) ret |= FILE_ATTRIBUTE_DIRECTORY; diff --git a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c index bd1195d896..d0813b9556 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c @@ -1,8 +1,8 @@ /* Unix SMB/CIFS implementation. - NTVFS filesystem backend for Linux CIFS client and clients which support - CIFS Unix extensions + simpler Samba VFS filesystem backend for clients which support the + CIFS Unix Extensions or newer CIFS POSIX protocol extensions Copyright (C) Andrew Tridgell 2003 Copyright (C) Steve French 2006 @@ -21,20 +21,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* this module needs to be converted to use ntvfs_handle's! */ -#define fnum _XXX_use_ntvfs_handle_not_fnum_XXX_ - /* this implements a very simple NTVFS filesystem backend. - this backend largely ignores the POSIX -> CIFS mappings, just doing absolutely minimal work to give a working backend. */ #include "includes.h" +#include "system/dir.h" #include "system/filesys.h" -#include "cvfs.h" +#include "cifsposix.h" +#include "system/time.h" #include "lib/util/dlinklist.h" #include "ntvfs/ntvfs.h" #include "ntvfs/cifs_posix_cli/proto.h" @@ -51,20 +48,21 @@ directory exists (tho it doesn't need to be accessible by the user, that comes later) */ -static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *sharename) { struct stat st; - struct svfs_private *private; - - private = talloc(ntvfs, struct svfs_private); + struct cifspsx_private *private; + struct share_config *scfg = ntvfs->ctx->config; + private = talloc(ntvfs, struct cifspsx_private); + NT_STATUS_HAVE_NO_MEMORY(private); + private->ntvfs = ntvfs; private->next_search_handle = 0; - private->connectpath = talloc_strdup(private, share_string_option(ntvfs->ctx->config, SHARE_PATH, "")); + private->connectpath = talloc_strdup(private, share_string_option(scfg, SHARE_PATH, "")); private->open_files = NULL; private->search = NULL; - DEBUG(0,("cifs backend: connect to %s",sharename)); /* the directory must exist */ if (stat(private->connectpath, &st) != 0 || !S_ISDIR(st.st_mode)) { DEBUG(0,("'%s' is not a directory, when connecting to [%s]\n", @@ -79,7 +77,7 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, ntvfs->private_data = private; - DEBUG(0,("WARNING: ntvfs simple: connect to share [%s] with ROOT privileges!!!\n",sharename)); + DEBUG(0,("WARNING: ntvfs cifs posix: connect to share [%s] with ROOT privileges!!!\n",sharename)); return NT_STATUS_OK; } @@ -87,7 +85,7 @@ static NTSTATUS svfs_connect(struct ntvfs_module_context *ntvfs, /* disconnect from a share */ -static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs) +static NTSTATUS cifspsx_disconnect(struct ntvfs_module_context *ntvfs) { return NT_STATUS_OK; } @@ -95,22 +93,25 @@ static NTSTATUS svfs_disconnect(struct ntvfs_module_context *ntvfs) /* find open file handle given fd */ -static struct svfs_file *find_fd(struct svfs_private *private, int fd) +static struct cifspsx_file *find_fd(struct cifspsx_private *private, struct ntvfs_handle *handle) { - struct svfs_file *f; - for (f=private->open_files;f;f=f->next) { - if (f->fd == fd) { - return f; - } - } - return NULL; + struct cifspsx_file *f; + void *p; + + p = ntvfs_handle_get_backend_data(handle, private->ntvfs); + if (!p) return NULL; + + f = talloc_get_type(p, struct cifspsx_file); + if (!f) return NULL; + + return f; } /* delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) */ -static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_unlink(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_unlink *unl) { @@ -118,7 +119,7 @@ static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, CHECK_READ_ONLY(req); - unix_path = cvfs_unix_path(ntvfs, req, unl->unlink.in.pattern); + unix_path = cifspsx_unix_path(ntvfs, req, unl->unlink.in.pattern); /* ignoring wildcards ... */ if (unlink(unix_path) == -1) { @@ -132,7 +133,7 @@ static NTSTATUS svfs_unlink(struct ntvfs_module_context *ntvfs, /* ioctl interface - we don't do any */ -static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_ioctl(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_ioctl *io) { return NT_STATUS_INVALID_PARAMETER; @@ -141,14 +142,14 @@ static NTSTATUS svfs_ioctl(struct ntvfs_module_context *ntvfs, /* check if a directory exists */ -static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_chkpath(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_chkpath *cp) { char *unix_path; struct stat st; - unix_path = cvfs_unix_path(ntvfs, req, cp->chkpath.in.path); + unix_path = cifspsx_unix_path(ntvfs, req, cp->chkpath.in.path); if (stat(unix_path, &st) == -1) { return map_nt_error_from_unix(errno); @@ -164,7 +165,7 @@ static NTSTATUS svfs_chkpath(struct ntvfs_module_context *ntvfs, /* build a file_id from a stat struct */ -static uint64_t svfs_file_id(struct stat *st) +static uint64_t cifspsx_file_id(struct stat *st) { uint64_t ret = st->st_ino; ret <<= 32; @@ -175,11 +176,11 @@ static uint64_t svfs_file_id(struct stat *st) /* approximately map a struct stat to a generic fileinfo struct */ -static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_map_fileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info, struct stat *st, const char *unix_path) { - struct svfs_dir *dir = NULL; + struct cifspsx_dir *dir = NULL; char *pattern = NULL; int i; const char *s, *short_name; @@ -194,7 +195,7 @@ static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, asprintf(&pattern, "%s:*", unix_path); if (pattern) { - dir = cvfs_list_unix(req, req, pattern); + dir = cifspsx_list_unix(req, req, pattern); } unix_to_nt_time(&info->generic.out.create_time, st->st_ctime); @@ -203,11 +204,11 @@ static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, unix_to_nt_time(&info->generic.out.change_time, st->st_mtime); info->generic.out.alloc_size = st->st_size; info->generic.out.size = st->st_size; - info->generic.out.attrib = cvfs_unix_to_dos_attrib(st->st_mode); + info->generic.out.attrib = cifspsx_unix_to_dos_attrib(st->st_mode); info->generic.out.alloc_size = st->st_blksize * st->st_blocks; info->generic.out.nlink = st->st_nlink; info->generic.out.directory = S_ISDIR(st->st_mode) ? 1 : 0; - info->generic.out.file_id = svfs_file_id(st); + info->generic.out.file_id = cifspsx_file_id(st); /* REWRITE: TODO stuff in here */ info->generic.out.delete_pending = 0; info->generic.out.ea_size = 0; @@ -251,73 +252,75 @@ static NTSTATUS svfs_map_fileinfo(struct ntvfs_module_context *ntvfs, /* return info on a pathname */ -static NTSTATUS svfs_qpathinfo(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_qpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { char *unix_path; struct stat st; - DEBUG(19,("svfs_qpathinfo: file %s level 0x%x\n", info->generic.in.file.path, info->generic.level)); + DEBUG(19,("cifspsx_qpathinfo: file %s level 0x%x\n", info->generic.in.file.path, info->generic.level)); if (info->generic.level != RAW_FILEINFO_GENERIC) { return ntvfs_map_qpathinfo(ntvfs, req, info); } - unix_path = cvfs_unix_path(ntvfs, req, info->generic.in.file.path); - DEBUG(19,("svfs_qpathinfo: file %s\n", unix_path)); + unix_path = cifspsx_unix_path(ntvfs, req, info->generic.in.file.path); + DEBUG(19,("cifspsx_qpathinfo: file %s\n", unix_path)); if (stat(unix_path, &st) == -1) { - DEBUG(19,("svfs_qpathinfo: file %s errno=%d\n", unix_path, errno)); + DEBUG(19,("cifspsx_qpathinfo: file %s errno=%d\n", unix_path, errno)); return map_nt_error_from_unix(errno); } - DEBUG(19,("svfs_qpathinfo: file %s, stat done\n", unix_path)); - return svfs_map_fileinfo(ntvfs, req, info, &st, unix_path); + DEBUG(19,("cifspsx_qpathinfo: file %s, stat done\n", unix_path)); + return cifspsx_map_fileinfo(ntvfs, req, info, &st, unix_path); } /* query info on a open file */ -static NTSTATUS svfs_qfileinfo(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { - struct svfs_private *private = ntvfs->private_data; - struct svfs_file *f; + struct cifspsx_private *private = ntvfs->private_data; + struct cifspsx_file *f; struct stat st; if (info->generic.level != RAW_FILEINFO_GENERIC) { return ntvfs_map_qfileinfo(ntvfs, req, info); } - f = find_fd(private, info->generic.in.file.fnum); + f = find_fd(private, info->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (fstat(info->generic.in.file.fnum, &st) == -1) { + if (fstat(f->fd, &st) == -1) { return map_nt_error_from_unix(errno); } - return svfs_map_fileinfo(ntvfs, req,info, &st, f->name); + return cifspsx_map_fileinfo(ntvfs, req,info, &st, f->name); } /* open a file */ -static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io) { - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; char *unix_path; struct stat st; int fd, flags; - struct svfs_file *f; + struct cifspsx_file *f; int create_flags, rdwr_flags; BOOL readonly; + NTSTATUS status; + struct ntvfs_handle *handle; if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(ntvfs, req, io); } - readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True); + readonly = share_bool_option(ntvfs->ctx->config, SHARE_READONLY, SHARE_READONLY_DEFAULT); if (readonly) { create_flags = 0; rdwr_flags = O_RDONLY; @@ -326,7 +329,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, rdwr_flags = O_RDWR; } - unix_path = cvfs_unix_path(ntvfs, req, io->ntcreatex.in.fname); + unix_path = cifspsx_unix_path(ntvfs, req, io->ntcreatex.in.fname); switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: @@ -358,13 +361,13 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_CREATE: if (mkdir(unix_path, 0755) == -1) { - DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + DEBUG(9,("cifspsx_open: mkdir %s errno=%d\n", unix_path, errno)); return map_nt_error_from_unix(errno); } break; case NTCREATEX_DISP_OPEN_IF: if (mkdir(unix_path, 0755) == -1 && errno != EEXIST) { - DEBUG(9,("svfs_open: mkdir %s errno=%d\n", unix_path, errno)); + DEBUG(9,("cifspsx_open: mkdir %s errno=%d\n", unix_path, errno)); return map_nt_error_from_unix(errno); } break; @@ -378,12 +381,15 @@ do_open: } if (fstat(fd, &st) == -1) { - DEBUG(9,("svfs_open: fstat errno=%d\n", errno)); + DEBUG(9,("cifspsx_open: fstat errno=%d\n", errno)); close(fd); return map_nt_error_from_unix(errno); } - f = talloc(ntvfs, struct svfs_file); + status = ntvfs_handle_new(ntvfs, req, &handle); + NT_STATUS_NOT_OK_RETURN(status); + + f = talloc(handle, struct cifspsx_file); NT_STATUS_HAVE_NO_MEMORY(f); f->fd = fd; f->name = talloc_strdup(f, unix_path); @@ -391,16 +397,19 @@ do_open: DLIST_ADD(private->open_files, f); + status = ntvfs_handle_set_backend_data(handle, ntvfs, f); + NT_STATUS_NOT_OK_RETURN(status); + ZERO_STRUCT(io->generic.out); unix_to_nt_time(&io->generic.out.create_time, st.st_ctime); unix_to_nt_time(&io->generic.out.access_time, st.st_atime); unix_to_nt_time(&io->generic.out.write_time, st.st_mtime); unix_to_nt_time(&io->generic.out.change_time, st.st_mtime); - io->generic.out.file.fnum = fd; + io->generic.out.file.ntvfs = handle; io->generic.out.alloc_size = st.st_size; io->generic.out.size = st.st_size; - io->generic.out.attrib = cvfs_unix_to_dos_attrib(st.st_mode); + io->generic.out.attrib = cifspsx_unix_to_dos_attrib(st.st_mode); io->generic.out.is_directory = S_ISDIR(st.st_mode) ? 1 : 0; return NT_STATUS_OK; @@ -409,7 +418,7 @@ do_open: /* create a directory */ -static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_mkdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_mkdir *md) { char *unix_path; @@ -420,7 +429,7 @@ static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; } - unix_path = cvfs_unix_path(ntvfs, req, md->mkdir.in.path); + unix_path = cifspsx_unix_path(ntvfs, req, md->mkdir.in.path); if (mkdir(unix_path, 0777) == -1) { return map_nt_error_from_unix(errno); @@ -432,14 +441,14 @@ static NTSTATUS svfs_mkdir(struct ntvfs_module_context *ntvfs, /* remove a directory */ -static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_rmdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_rmdir *rd) { char *unix_path; CHECK_READ_ONLY(req); - unix_path = cvfs_unix_path(ntvfs, req, rd->in.path); + unix_path = cifspsx_unix_path(ntvfs, req, rd->in.path); if (rmdir(unix_path) == -1) { return map_nt_error_from_unix(errno); @@ -451,7 +460,7 @@ static NTSTATUS svfs_rmdir(struct ntvfs_module_context *ntvfs, /* rename a set of files */ -static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_rename(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_rename *ren) { char *unix_path1, *unix_path2; @@ -462,8 +471,8 @@ static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; } - unix_path1 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern1); - unix_path2 = cvfs_unix_path(ntvfs, req, ren->rename.in.pattern2); + unix_path1 = cifspsx_unix_path(ntvfs, req, ren->rename.in.pattern1); + unix_path2 = cifspsx_unix_path(ntvfs, req, ren->rename.in.pattern2); if (rename(unix_path1, unix_path2) == -1) { return map_nt_error_from_unix(errno); @@ -475,7 +484,7 @@ static NTSTATUS svfs_rename(struct ntvfs_module_context *ntvfs, /* copy a set of files */ -static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_copy(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_copy *cp) { return NT_STATUS_NOT_SUPPORTED; @@ -484,16 +493,23 @@ static NTSTATUS svfs_copy(struct ntvfs_module_context *ntvfs, /* read from a file */ -static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_read(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_read *rd) { + struct cifspsx_private *private = ntvfs->private_data; + struct cifspsx_file *f; ssize_t ret; if (rd->generic.level != RAW_READ_READX) { return NT_STATUS_NOT_SUPPORTED; } - ret = pread(rd->readx.in.file.fnum, + f = find_fd(private, rd->readx.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + ret = pread(f->fd, rd->readx.out.data, rd->readx.in.maxcnt, rd->readx.in.offset); @@ -511,9 +527,11 @@ static NTSTATUS svfs_read(struct ntvfs_module_context *ntvfs, /* write to a file */ -static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *wr) { + struct cifspsx_private *private = ntvfs->private_data; + struct cifspsx_file *f; ssize_t ret; if (wr->generic.level != RAW_WRITE_WRITEX) { @@ -522,7 +540,12 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, CHECK_READ_ONLY(req); - ret = pwrite(wr->writex.in.file.fnum, + f = find_fd(private, wr->writex.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + ret = pwrite(f->fd, wr->writex.in.data, wr->writex.in.count, wr->writex.in.offset); @@ -539,7 +562,7 @@ static NTSTATUS svfs_write(struct ntvfs_module_context *ntvfs, /* seek in a file */ -static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_seek(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_seek *io) { @@ -549,35 +572,55 @@ static NTSTATUS svfs_seek(struct ntvfs_module_context *ntvfs, /* flush a file */ -static NTSTATUS svfs_flush(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_flush *io) { - fsync(io->flush.in.file.fnum); - return NT_STATUS_OK; + struct cifspsx_private *private = ntvfs->private_data; + struct cifspsx_file *f; + + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: + case RAW_FLUSH_SMB2: + /* ignore the additional unknown option in SMB2 */ + f = find_fd(private, io->generic.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + fsync(f->fd); + return NT_STATUS_OK; + + case RAW_FLUSH_ALL: + for (f=private->open_files;f;f=f->next) { + fsync(f->fd); + } + return NT_STATUS_OK; + } + + return NT_STATUS_INVALID_LEVEL; } /* close a file */ -static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_close *io) { - struct svfs_private *private = ntvfs->private_data; - struct svfs_file *f; + struct cifspsx_private *private = ntvfs->private_data; + struct cifspsx_file *f; if (io->generic.level != RAW_CLOSE_CLOSE) { /* we need a mapping function */ return NT_STATUS_INVALID_LEVEL; } - f = find_fd(private, io->close.in.file.fnum); + f = find_fd(private, io->close.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (close(io->close.in.file.fnum) == -1) { + if (close(f->fd) == -1) { return map_nt_error_from_unix(errno); } @@ -591,7 +634,7 @@ static NTSTATUS svfs_close(struct ntvfs_module_context *ntvfs, /* exit - closing files */ -static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_exit(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { return NT_STATUS_NOT_SUPPORTED; @@ -600,7 +643,7 @@ static NTSTATUS svfs_exit(struct ntvfs_module_context *ntvfs, /* logoff - closing files */ -static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_logoff(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { return NT_STATUS_NOT_SUPPORTED; @@ -609,7 +652,7 @@ static NTSTATUS svfs_logoff(struct ntvfs_module_context *ntvfs, /* setup for an async call */ -static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_async_setup(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, void *private) { @@ -619,7 +662,7 @@ static NTSTATUS svfs_async_setup(struct ntvfs_module_context *ntvfs, /* cancel an async call */ -static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) +static NTSTATUS cifspsx_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { return NT_STATUS_UNSUCCESSFUL; } @@ -627,7 +670,7 @@ static NTSTATUS svfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_req /* lock a byte range */ -static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_lock(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lock *lck) { DEBUG(0,("REWRITE: not doing byte range locking!\n")); @@ -637,7 +680,7 @@ static NTSTATUS svfs_lock(struct ntvfs_module_context *ntvfs, /* set info on a pathname */ -static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_setpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *st) { CHECK_READ_ONLY(req); @@ -648,19 +691,25 @@ static NTSTATUS svfs_setpathinfo(struct ntvfs_module_context *ntvfs, /* set info on a open file */ -static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_setfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *info) { + struct cifspsx_private *private = ntvfs->private_data; + struct cifspsx_file *f; struct utimbuf unix_times; - int fd; CHECK_READ_ONLY(req); - + + f = find_fd(private, info->generic.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + switch (info->generic.level) { case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: - if (ftruncate(info->end_of_file_info.in.file.fnum, + if (ftruncate(f->fd, info->end_of_file_info.in.size) == -1) { return map_nt_error_from_unix(errno); } @@ -668,8 +717,7 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_SETATTRE: unix_times.actime = info->setattre.in.access_time; unix_times.modtime = info->setattre.in.write_time; - fd = info->setattre.in.file.fnum; - + if (unix_times.actime == 0 && unix_times.modtime == 0) { break; } @@ -680,12 +728,12 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, } /* Set the date on this file */ - if (cvfs_file_utime(fd, &unix_times) != 0) { + if (cifspsx_file_utime(f->fd, &unix_times) != 0) { return NT_STATUS_ACCESS_DENIED; } break; default: - DEBUG(2,("svfs_setfileinfo: level %d not implemented\n", + DEBUG(2,("cifspsx_setfileinfo: level %d not implemented\n", info->generic.level)); return NT_STATUS_NOT_IMPLEMENTED; } @@ -696,10 +744,10 @@ static NTSTATUS svfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* return filesystem space info */ -static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs) { - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; struct stat st; if (fs->generic.level != RAW_QFS_GENERIC) { @@ -738,11 +786,11 @@ static NTSTATUS svfs_fsinfo(struct ntvfs_module_context *ntvfs, /* return filesystem attribute info */ -static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_fsattr(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsattr *fs) { struct stat st; - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; if (fs->generic.level != RAW_FSATTR_GENERIC) { return ntvfs_map_fsattr(ntvfs, req, fs); @@ -770,7 +818,7 @@ static NTSTATUS svfs_fsattr(struct ntvfs_module_context *ntvfs, /* return print queue info */ -static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_lpq(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lpq *lpq) { return NT_STATUS_NOT_SUPPORTED; @@ -779,19 +827,23 @@ static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, /* list files in a directory matching a wildcard pattern */ -static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct svfs_dir *dir; + struct cifspsx_dir *dir; int i; - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; struct search_state *search; union smb_search_data file; uint_t max_count; - if (io->generic.level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { + if (io->generic.level != RAW_SEARCH_TRANS2) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { return NT_STATUS_NOT_SUPPORTED; } @@ -802,7 +854,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, max_count = io->t2ffirst.in.max_count; - dir = cvfs_list(ntvfs, req, io->t2ffirst.in.pattern); + dir = cifspsx_list(ntvfs, req, io->t2ffirst.in.pattern); if (!dir) { return NT_STATUS_FOOBAR; } @@ -823,7 +875,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, file.both_directory_info.name.s = dir->files[i].name; file.both_directory_info.short_name.s = dir->files[i].name; file.both_directory_info.size = dir->files[i].st.st_size; - file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + file.both_directory_info.attrib = cifspsx_unix_to_dos_attrib(dir->files[i].st.st_mode); if (!callback(search_private, &file)) { break; @@ -849,19 +901,23 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, } /* continue a search */ -static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, BOOL (*callback)(void *, union smb_search_data *)) { - struct svfs_dir *dir; + struct cifspsx_dir *dir; int i; - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; struct search_state *search; union smb_search_data file; uint_t max_count; - if (io->generic.level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { + if (io->generic.level != RAW_SEARCH_TRANS2) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) { return NT_STATUS_NOT_SUPPORTED; } @@ -914,7 +970,7 @@ found: file.both_directory_info.name.s = dir->files[i].name; file.both_directory_info.short_name.s = dir->files[i].name; file.both_directory_info.size = dir->files[i].st.st_size; - file.both_directory_info.attrib = cvfs_unix_to_dos_attrib(dir->files[i].st.st_mode); + file.both_directory_info.attrib = cifspsx_unix_to_dos_attrib(dir->files[i].st.st_mode); if (!callback(search_private, &file)) { break; @@ -937,10 +993,10 @@ found: } /* close a search */ -static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_search_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io) { - struct svfs_private *private = ntvfs->private_data; + struct cifspsx_private *private = ntvfs->private_data; struct search_state *search; for (search=private->search; search; search = search->next) { @@ -959,7 +1015,7 @@ static NTSTATUS svfs_search_close(struct ntvfs_module_context *ntvfs, } /* SMBtrans - not used on file shares */ -static NTSTATUS svfs_trans(struct ntvfs_module_context *ntvfs, +static NTSTATUS cifspsx_trans(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_trans2 *trans2) { return NT_STATUS_ACCESS_DENIED; @@ -978,39 +1034,39 @@ NTSTATUS ntvfs_cifs_posix_init(void) ZERO_STRUCT(ops); /* fill in all the operations */ - ops.connect = svfs_connect; - ops.disconnect = svfs_disconnect; - ops.unlink = svfs_unlink; - ops.chkpath = svfs_chkpath; - ops.qpathinfo = svfs_qpathinfo; - ops.setpathinfo = svfs_setpathinfo; - ops.open = svfs_open; - ops.mkdir = svfs_mkdir; - ops.rmdir = svfs_rmdir; - ops.rename = svfs_rename; - ops.copy = svfs_copy; - ops.ioctl = svfs_ioctl; - ops.read = svfs_read; - ops.write = svfs_write; - ops.seek = svfs_seek; - ops.flush = svfs_flush; - ops.close = svfs_close; - ops.exit = svfs_exit; - ops.lock = svfs_lock; - ops.setfileinfo = svfs_setfileinfo; - ops.qfileinfo = svfs_qfileinfo; - ops.fsinfo = svfs_fsinfo; - ops.lpq = svfs_lpq; - ops.search_first = svfs_search_first; - ops.search_next = svfs_search_next; - ops.search_close = svfs_search_close; - ops.trans = svfs_trans; - ops.logoff = svfs_logoff; - ops.async_setup = svfs_async_setup; - ops.cancel = svfs_cancel; + ops.connect = cifspsx_connect; + ops.disconnect = cifspsx_disconnect; + ops.unlink = cifspsx_unlink; + ops.chkpath = cifspsx_chkpath; + ops.qpathinfo = cifspsx_qpathinfo; + ops.setpathinfo = cifspsx_setpathinfo; + ops.open = cifspsx_open; + ops.mkdir = cifspsx_mkdir; + ops.rmdir = cifspsx_rmdir; + ops.rename = cifspsx_rename; + ops.copy = cifspsx_copy; + ops.ioctl = cifspsx_ioctl; + ops.read = cifspsx_read; + ops.write = cifspsx_write; + ops.seek = cifspsx_seek; + ops.flush = cifspsx_flush; + ops.close = cifspsx_close; + ops.exit = cifspsx_exit; + ops.lock = cifspsx_lock; + ops.setfileinfo = cifspsx_setfileinfo; + ops.qfileinfo = cifspsx_qfileinfo; + ops.fsinfo = cifspsx_fsinfo; + ops.lpq = cifspsx_lpq; + ops.search_first = cifspsx_search_first; + ops.search_next = cifspsx_search_next; + ops.search_close = cifspsx_search_close; + ops.trans = cifspsx_trans; + ops.logoff = cifspsx_logoff; + ops.async_setup = cifspsx_async_setup; + ops.cancel = cifspsx_cancel; /* register ourselves with the NTVFS subsystem. We register - under name 'cifsposix' + under names 'cifsposix' */ ops.type = NTVFS_DISK; @@ -1018,7 +1074,7 @@ NTSTATUS ntvfs_cifs_posix_init(void) ret = ntvfs_register(&ops, &vers); if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0,("Failed to register simple backend with name: %s!\n", + DEBUG(0,("Failed to register cifs posix backend with name: %s!\n", ops.name)); } -- cgit From 9c53e146020c16e2a26e24fb327d69ed8da14c8e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Sep 2006 15:31:53 +0000 Subject: r18580: map the PVFS_FLAG_READONLY bit in the posix backend onto NT_STATUS_ACCESS_DENIED in the access mask checks (This used to be commit ceffc34f3e9f47a8a44dad52054688f9855eeb37) --- source4/ntvfs/posix/pvfs_acl.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 3d276431dc..1dd40c0e06 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -349,6 +349,13 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, uid_t uid = geteuid(); uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL; + if ((pvfs->flags & PVFS_FLAG_READONLY) && + ((*access_mask) & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | + SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE | + SEC_DIR_DELETE_CHILD))) { + return NT_STATUS_ACCESS_DENIED; + } + /* owner and root get extra permissions */ if (uid == 0) { max_bits |= SEC_STD_ALL | SEC_FLAG_SYSTEM_SECURITY; @@ -390,6 +397,13 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, NTSTATUS status; struct security_descriptor *sd; + if ((pvfs->flags & PVFS_FLAG_READONLY) && + ((*access_mask) & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | + SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE | + SEC_DIR_DELETE_CHILD))) { + return NT_STATUS_ACCESS_DENIED; + } + acl = talloc(req, struct xattr_NTACL); if (acl == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From c5e67b855560b85040c6caa17e0cab641b0e273e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 16 Sep 2006 15:37:45 +0000 Subject: r18581: also check for SEC_STD_DELETE, and split out the check into a separate static function (This used to be commit 024ca6a91cdf2c0f8999c220b4459a72c45bfd32) --- source4/ntvfs/posix/pvfs_acl.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 1dd40c0e06..62ef196977 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -335,6 +335,25 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, } +/* + check the read only bit against any of the write access bits +*/ +static BOOL pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask) +{ + if ((pvfs->flags & PVFS_FLAG_READONLY) && + (access_mask & (SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_WRITE_EA | + SEC_FILE_WRITE_ATTRIBUTE | + SEC_STD_DELETE | + SEC_STD_WRITE_DAC | + SEC_STD_WRITE_OWNER | + SEC_DIR_DELETE_CHILD))) { + return True; + } + return False; +} + /* default access check function based on unix permissions doing this saves on building a full security descriptor @@ -349,10 +368,7 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, uid_t uid = geteuid(); uint32_t max_bits = SEC_RIGHTS_FILE_READ | SEC_FILE_ALL; - if ((pvfs->flags & PVFS_FLAG_READONLY) && - ((*access_mask) & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | - SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE | - SEC_DIR_DELETE_CHILD))) { + if (pvfs_read_only(pvfs, *access_mask)) { return NT_STATUS_ACCESS_DENIED; } @@ -397,10 +413,7 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, NTSTATUS status; struct security_descriptor *sd; - if ((pvfs->flags & PVFS_FLAG_READONLY) && - ((*access_mask) & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA | - SEC_FILE_WRITE_EA | SEC_FILE_WRITE_ATTRIBUTE | - SEC_DIR_DELETE_CHILD))) { + if (pvfs_read_only(pvfs, *access_mask)) { return NT_STATUS_ACCESS_DENIED; } -- cgit From 921f73c7e58eac1900eb7ec9f7276cd3afaf0480 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 23 Sep 2006 02:19:15 +0000 Subject: r18835: expand IO limits on SMB2. Samba4 now tops out at 16.7MB IOs. (This used to be commit 1e34e4d5a1fd3d74080424140e4ab276b6042d12) --- source4/ntvfs/ntvfs_generic.c | 6 ------ source4/ntvfs/posix/pvfs_read.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index aff05b70a8..aa6edcdf42 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1266,12 +1266,6 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, break; case RAW_READ_SMB2: - if (rd->smb2.in.length > UINT16_MAX) { - DEBUG(0,("%s: mapping SMB2 => generic length to large %u!\n", - __FUNCTION__, rd->smb2.in.length)); - status = NT_STATUS_FOOBAR; - goto done; - } rd2->readx.in.file.ntvfs= rd->smb2.in.file.ntvfs; rd2->readx.in.offset = rd->smb2.in.offset; rd2->readx.in.mincnt = rd->smb2.in.length; diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 13e8264000..c36d8ca2a3 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -59,7 +59,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, } maxcnt = rd->readx.in.maxcnt; - if (maxcnt > UINT16_MAX) { + if (maxcnt > UINT16_MAX && req->ctx->protocol < PROTOCOL_SMB2) { maxcnt = 0; } -- cgit From 2338e978322510d5b6def6edac40a868e4945d2e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 9 Oct 2006 11:13:49 +0000 Subject: r19199: split out the xattr NTACL code into a separate part of the posix backend, allowing other ACL backends to be added. The xattr backend is still the default backend (This used to be commit 90f044e63b12d32228310c7529382198bd7e6dfe) --- source4/ntvfs/posix/config.mk | 11 ++++ source4/ntvfs/posix/pvfs_acl.c | 108 ++++++++++++++++++++++------------- source4/ntvfs/posix/pvfs_acl_xattr.c | 105 ++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_xattr.c | 18 +++--- source4/ntvfs/posix/vfs_posix.c | 3 + source4/ntvfs/posix/vfs_posix.h | 11 ++++ 6 files changed, 207 insertions(+), 49 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_acl_xattr.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 2835fc4575..57ee5b4090 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,3 +1,13 @@ +################################################ +# Start MODULE pvfs_acl_xattr +[MODULE::pvfs_acl_xattr] +INIT_FUNCTION = pvfs_acl_xattr_init +SUBSYSTEM = ntvfs +OBJ_FILES = \ + pvfs_acl_xattr.o +# End MODULE pvfs_acl_xattr +################################################ + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -32,6 +42,7 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o +PRIVATE_DEPENDENCIES = pvfs_acl_xattr PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 62ef196977..1a3fc184de 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -27,6 +27,60 @@ #include "libcli/security/security.h" +/* the list of currently registered ACL backends */ +static struct pvfs_acl_backend { + const struct pvfs_acl_ops *ops; +} *backends = NULL; +static int num_backends; + +/* + register a pvfs acl backend. + + The 'name' can be later used by other backends to find the operations + structure for this backend. +*/ +_PUBLIC_ NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops) +{ + struct pvfs_acl_ops *new_ops; + + if (pvfs_acl_backend_byname(ops->name) != NULL) { + DEBUG(0,("pvfs acl backend '%s' already registered\n", ops->name)); + return NT_STATUS_OBJECT_NAME_COLLISION; + } + + backends = talloc_realloc(talloc_autofree_context(), backends, struct pvfs_acl_backend, num_backends+1); + NT_STATUS_HAVE_NO_MEMORY(backends); + + new_ops = talloc_memdup(backends, ops, sizeof(*ops)); + new_ops->name = talloc_strdup(new_ops, ops->name); + + backends[num_backends].ops = new_ops; + + num_backends++; + + DEBUG(3,("NTVFS backend '%s' registered\n", ops->name)); + + return NT_STATUS_OK; +} + + +/* + return the operations structure for a named backend +*/ +_PUBLIC_ const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name) +{ + int i; + + for (i=0;iname, name) == 0) { + return backends[i].ops; + } + } + + return NULL; +} + + /* map a single access_mask from generic to specific bits for files/dirs */ @@ -67,17 +121,18 @@ static void pvfs_translate_generic_bits(struct security_acl *acl) static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, struct ntvfs_request *req, struct pvfs_filename *name, int fd, - struct xattr_NTACL *acl) + struct security_descriptor **psd) { struct security_descriptor *sd; NTSTATUS status; struct security_ace ace; mode_t mode; - sd = security_descriptor_initialise(req); - if (sd == NULL) { + *psd = security_descriptor_initialise(req); + if (*psd == NULL) { return NT_STATUS_NO_MEMORY; } + sd = *psd; status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); if (!NT_STATUS_IS_OK(status)) { @@ -154,9 +209,6 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, ace.access_mask = SEC_RIGHTS_FILE_ALL; security_descriptor_dacl_add(sd, &ace); - acl->version = 1; - acl->info.sd = sd; - return NT_STATUS_OK; } @@ -190,36 +242,24 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, uint32_t access_mask, union smb_setfileinfo *info) { - struct xattr_NTACL *acl; uint32_t secinfo_flags = info->set_secdesc.in.secinfo_flags; struct security_descriptor *new_sd, *sd, orig_sd; - NTSTATUS status; + NTSTATUS status = NT_STATUS_NOT_FOUND; uid_t old_uid = -1; gid_t old_gid = -1; uid_t new_uid = -1; gid_t new_gid = -1; - acl = talloc(req, struct xattr_NTACL); - if (acl == NULL) { - return NT_STATUS_NO_MEMORY; + if (pvfs->acl_ops != NULL) { + status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd); } - - status = pvfs_acl_load(pvfs, name, fd, acl); if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { - status = pvfs_default_acl(pvfs, req, name, fd, acl); + status = pvfs_default_acl(pvfs, req, name, fd, &sd); } if (!NT_STATUS_IS_OK(status)) { return status; } - switch (acl->version) { - case 1: - sd = acl->info.sd; - break; - default: - return NT_STATUS_INVALID_ACL; - } - new_sd = info->set_secdesc.in.sd; orig_sd = *sd; @@ -286,8 +326,8 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, /* we avoid saving if the sd is the same. This means when clients copy files and end up copying the default sd that we don't needlessly use xattrs */ - if (!security_descriptor_equal(sd, &orig_sd)) { - status = pvfs_acl_save(pvfs, name, fd, acl); + if (!security_descriptor_equal(sd, &orig_sd) && pvfs->acl_ops) { + status = pvfs->acl_ops->acl_save(pvfs, name, fd, sd); } return status; @@ -302,31 +342,19 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, union smb_fileinfo *info) { - struct xattr_NTACL *acl; - NTSTATUS status; + NTSTATUS status = NT_STATUS_NOT_FOUND; struct security_descriptor *sd; - acl = talloc(req, struct xattr_NTACL); - if (acl == NULL) { - return NT_STATUS_NO_MEMORY; + if (pvfs->acl_ops) { + status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd); } - - status = pvfs_acl_load(pvfs, name, fd, acl); if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { - status = pvfs_default_acl(pvfs, req, name, fd, acl); + status = pvfs_default_acl(pvfs, req, name, fd, &sd); } if (!NT_STATUS_IS_OK(status)) { return status; } - switch (acl->version) { - case 1: - sd = acl->info.sd; - break; - default: - return NT_STATUS_INVALID_ACL; - } - normalise_sd_flags(sd, info->query_secdesc.in.secinfo_flags); info->query_secdesc.out.sd = sd; diff --git a/source4/ntvfs/posix/pvfs_acl_xattr.c b/source4/ntvfs/posix/pvfs_acl_xattr.c new file mode 100644 index 0000000000..705f525507 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_acl_xattr.c @@ -0,0 +1,105 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - NT ACLs in xattrs + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "vfs_posix.h" +#include "lib/util/unix_privs.h" +#include "librpc/gen_ndr/ndr_xattr.h" + +/* + load the current ACL from extended attributes +*/ +static NTSTATUS pvfs_acl_load_xattr(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + TALLOC_CTX *mem_ctx, + struct security_descriptor **sd) +{ + NTSTATUS status; + struct xattr_NTACL *acl; + + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_NOT_FOUND; + } + + acl = talloc_zero(mem_ctx, struct xattr_NTACL); + NT_STATUS_HAVE_NO_MEMORY(acl); + + status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, fd, + XATTR_NTACL_NAME, + acl, + (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL); + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(acl); + return status; + } + + if (acl->version != 1) { + talloc_free(acl); + return NT_STATUS_INVALID_ACL; + } + + *sd = talloc_steal(mem_ctx, acl->info.sd); + + return NT_STATUS_OK; +} + +/* + save the acl for a file into filesystem xattr +*/ +static NTSTATUS pvfs_acl_save_xattr(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct security_descriptor *sd) +{ + NTSTATUS status; + void *privs; + struct xattr_NTACL acl; + + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { + return NT_STATUS_OK; + } + + acl.version = 1; + acl.info.sd = sd; + + /* this xattr is in the "system" namespace, so we need + admin privileges to set it */ + privs = root_privileges(); + status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, + XATTR_NTACL_NAME, + &acl, + (ndr_push_flags_fn_t)ndr_push_xattr_NTACL); + talloc_free(privs); + return status; +} + + +/* + initialise pvfs acl xattr backend +*/ +NTSTATUS pvfs_acl_xattr_init(void) +{ + struct pvfs_acl_ops ops = { + .name = "xattr", + .acl_load = pvfs_acl_load_xattr, + .acl_save = pvfs_acl_save_xattr + }; + return pvfs_acl_register(&ops); +} diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index e5b4fdaa90..ab2f3fef6c 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -101,10 +101,10 @@ NTSTATUS pvfs_xattr_unlink_hook(struct pvfs_state *pvfs, const char *fname) /* load a NDR structure from a xattr */ -static NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, - TALLOC_CTX *mem_ctx, - const char *fname, int fd, const char *attr_name, - void *p, ndr_pull_flags_fn_t pull_fn) +NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, + TALLOC_CTX *mem_ctx, + const char *fname, int fd, const char *attr_name, + void *p, void *pull_fn) { NTSTATUS status; DATA_BLOB blob; @@ -116,7 +116,7 @@ static NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, } /* pull the blob */ - status = ndr_pull_struct_blob(&blob, mem_ctx, p, pull_fn); + status = ndr_pull_struct_blob(&blob, mem_ctx, p, (ndr_pull_flags_fn_t)pull_fn); data_blob_free(&blob); @@ -126,15 +126,15 @@ static NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, /* save a NDR structure into a xattr */ -static NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, - const char *fname, int fd, const char *attr_name, - void *p, ndr_push_flags_fn_t push_fn) +NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, + const char *fname, int fd, const char *attr_name, + void *p, void *push_fn) { TALLOC_CTX *mem_ctx = talloc_new(NULL); DATA_BLOB blob; NTSTATUS status; - status = ndr_push_struct_blob(&blob, mem_ctx, p, push_fn); + status = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn); if (!NT_STATUS_IS_OK(status)) { talloc_free(mem_ctx); return status; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 975649eeb5..ad47908b6e 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -113,6 +113,9 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (pvfs->flags & PVFS_FLAG_XATTR_ENABLE) { pvfs_xattr_probe(pvfs); } + + /* enable an ACL backend */ + pvfs->acl_ops = pvfs_acl_backend_byname(share_string_option(scfg, PVFS_ACL, "xattr")); } static int pvfs_state_destructor(struct pvfs_state *pvfs) diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 82a3d34172..4a81088d1c 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -83,6 +83,9 @@ struct pvfs_state { const struct dom_sid *creator_owner; const struct dom_sid *creator_group; } sid_cache; + + /* the acl backend */ + const struct pvfs_acl_ops *acl_ops; }; /* this is the basic information needed about a file from the filesystem */ @@ -220,6 +223,7 @@ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; #define PVFS_SHARE_DELAY "posix:sharedelay" #define PVFS_ALLOCATION_ROUNDING "posix:allocationrounding" #define PVFS_SEARCH_INACTIVITY "posix:searchinactivity" +#define PVFS_ACL "posix:acl" #define PVFS_XATTR_DEFAULT True #define PVFS_FAKE_OPLOCKS_DEFAULT False @@ -227,6 +231,13 @@ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; #define PVFS_ALLOCATION_ROUNDING_DEFAULT 512 #define PVFS_SEARCH_INACTIVITY_DEFAULT 300 +struct pvfs_acl_ops { + const char *name; + NTSTATUS (*acl_load)(struct pvfs_state *, struct pvfs_filename *, int , TALLOC_CTX *, + struct security_descriptor **); + NTSTATUS (*acl_save)(struct pvfs_state *, struct pvfs_filename *, int , struct security_descriptor *); +}; + #include "ntvfs/posix/vfs_posix_proto.h" #endif /* _VFS_POSIX_H_ */ -- cgit From af870da6194b47c6cd09445c1e03832d00e951bb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 20 Oct 2006 23:32:23 +0000 Subject: r19428: moved tdbutil.c from lib/tdb/common/ to lib/util/util_tdb.c tdbutil.c is Samba specific, so should not be part of the generic tdb library (This used to be commit 979dd24f5e44605fc1603b690913b8c31be7478f) --- source4/ntvfs/common/notify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 17c6e81c6f..19a60a51a9 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -27,7 +27,7 @@ #include "includes.h" #include "system/filesys.h" #include "lib/tdb/include/tdb.h" -#include "lib/tdb/include/tdbutil.h" +#include "lib/util/util_tdb.h" #include "messaging/messaging.h" #include "db_wrap.h" #include "lib/messaging/irpc.h" -- cgit From 515c92a759ad30059f65d3e65dc9f642dc03852a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Oct 2006 09:46:12 +0000 Subject: r19441: work in progress support for NFS4 ACLs in Samba4 on Linux. Still work to do, particularly with getting the detailed bit mappings right, and on sid mapping. Does not pass RAW-ACLS yet (This used to be commit b92553481b534d0ef5277dbfe8c0d64a03f819eb) --- source4/ntvfs/posix/config.mk | 12 ++- source4/ntvfs/posix/pvfs_acl_nfs4.c | 163 ++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 source4/ntvfs/posix/pvfs_acl_nfs4.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 57ee5b4090..ed182d9a98 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -8,6 +8,16 @@ OBJ_FILES = \ # End MODULE pvfs_acl_xattr ################################################ +################################################ +# Start MODULE pvfs_acl_nfs4 +[MODULE::pvfs_acl_nfs4] +INIT_FUNCTION = pvfs_acl_nfs4_init +SUBSYSTEM = ntvfs +OBJ_FILES = \ + pvfs_acl_nfs4.o +# End MODULE pvfs_acl_nfs4 +################################################ + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -42,7 +52,7 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o -PRIVATE_DEPENDENCIES = pvfs_acl_xattr +PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_acl_nfs4.c b/source4/ntvfs/posix/pvfs_acl_nfs4.c new file mode 100644 index 0000000000..b0a329c639 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_acl_nfs4.c @@ -0,0 +1,163 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - NT ACLs mapped to NFS4 ACLs, as per + http://www.suse.de/~agruen/nfs4acl/ + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "vfs_posix.h" +#include "lib/util/unix_privs.h" +#include "librpc/gen_ndr/ndr_nfs4acl.h" +#include "libcli/security/security.h" + +#define ACE4_IDENTIFIER_GROUP 0x40 + +/* + load the current ACL from system.nfs4acl +*/ +static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + TALLOC_CTX *mem_ctx, + struct security_descriptor **psd) +{ + NTSTATUS status; + struct nfs4acl *acl; + struct security_descriptor *sd; + int i; + + acl = talloc_zero(mem_ctx, struct nfs4acl); + NT_STATUS_HAVE_NO_MEMORY(acl); + + status = pvfs_xattr_ndr_load(pvfs, mem_ctx, name->full_name, fd, + NFS4ACL_XATTR_NAME, + acl, ndr_pull_nfs4acl); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(acl); + return status; + } + + *psd = security_descriptor_initialise(mem_ctx); + NT_STATUS_HAVE_NO_MEMORY(*psd); + + sd = *psd; + + sd->type |= acl->a_flags; + status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); + NT_STATUS_NOT_OK_RETURN(status); + status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); + NT_STATUS_NOT_OK_RETURN(status); + + for (i=0;ia_count;i++) { + struct nfs4ace *a = &acl->ace[i]; + struct security_ace ace; + struct dom_sid *sid; + ace.type = a->e_type; + ace.flags = a->e_flags; + ace.access_mask = a->e_mask; + if (a->e_flags & ACE4_IDENTIFIER_GROUP) { + status = sidmap_gid_to_sid(pvfs->sidmap, sd, a->e_id, &sid); + } else { + status = sidmap_uid_to_sid(pvfs->sidmap, sd, a->e_id, &sid); + } + NT_STATUS_NOT_OK_RETURN(status); + ace.trustee = *sid; + security_descriptor_dacl_add(sd, &ace); + } + + return NT_STATUS_OK; +} + +/* + save the acl for a file into system.nfs4acl +*/ +static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd, + struct security_descriptor *sd) +{ + NTSTATUS status; + void *privs; + struct nfs4acl acl; + int i; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(pvfs); + NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); + + acl.a_version = 0; + acl.a_flags = sd->type; + acl.a_count = sd->dacl?sd->dacl->num_aces:0; + acl.a_owner_mask = 0; + acl.a_group_mask = 0; + acl.a_other_mask = 0; + + acl.ace = talloc_array(tmp_ctx, struct nfs4ace, acl.a_count); + if (!acl.ace) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + for (i=0;idacl->aces[i]; + a->e_type = ace->type; + a->e_flags = ace->flags; + a->e_mask = ace->access_mask; + if (sidmap_sid_is_group(pvfs->sidmap, &ace->trustee)) { + gid_t gid; + a->e_flags |= ACE4_IDENTIFIER_GROUP; + status = sidmap_sid_to_unixgid(pvfs->sidmap, &ace->trustee, &gid); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + a->e_id = gid; + } else { + uid_t uid; + status = sidmap_sid_to_unixuid(pvfs->sidmap, &ace->trustee, &uid); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + a->e_id = uid; + } + a->e_who = ""; + } + + privs = root_privileges(); + status = pvfs_xattr_ndr_save(pvfs, name->full_name, fd, + NFS4ACL_XATTR_NAME, + &acl, ndr_push_nfs4acl); + talloc_free(privs); + + talloc_free(tmp_ctx); + return status; +} + + +/* + initialise pvfs acl NFS4 backend +*/ +NTSTATUS pvfs_acl_nfs4_init(void) +{ + struct pvfs_acl_ops ops = { + .name = "nfs4acl", + .acl_load = pvfs_acl_load_nfs4, + .acl_save = pvfs_acl_save_nfs4 + }; + return pvfs_acl_register(&ops); +} -- cgit From 4fa24df98ded939c68bdc95e9f09334caeeb84af Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 29 Oct 2006 17:40:19 +0000 Subject: r19507: Merge my DSO fixes branch. Building Samba's libraries as shared libraries works again now, by specifying --enable-dso to configure. (This used to be commit 7a01235067a4800b07b8919a6a475954bfb0b04c) --- source4/ntvfs/posix/config.mk | 5 +++-- source4/ntvfs/posix/pvfs_xattr.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index ed182d9a98..5fd6e58d2e 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -2,9 +2,10 @@ # Start MODULE pvfs_acl_xattr [MODULE::pvfs_acl_xattr] INIT_FUNCTION = pvfs_acl_xattr_init -SUBSYSTEM = ntvfs +SUBSYSTEM = ntvfs_posix OBJ_FILES = \ pvfs_acl_xattr.o +PRIVATE_DEPENDENCIES = NDR_XATTR # End MODULE pvfs_acl_xattr ################################################ @@ -52,7 +53,7 @@ OBJ_FILES = \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o -PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 +#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index ab2f3fef6c..fcc2d351c9 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -101,7 +101,7 @@ NTSTATUS pvfs_xattr_unlink_hook(struct pvfs_state *pvfs, const char *fname) /* load a NDR structure from a xattr */ -NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, +_PUBLIC_ NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, const char *fname, int fd, const char *attr_name, void *p, void *pull_fn) @@ -126,7 +126,7 @@ NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, /* save a NDR structure into a xattr */ -NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, +_PUBLIC_ NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, const char *fname, int fd, const char *attr_name, void *p, void *push_fn) { -- cgit From d6c003083c75a485044bc2d42045f1887ad64e8d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 29 Oct 2006 22:48:43 +0000 Subject: r19508: fixed SMB2-SETINFO the pvfs_acl_xattr backend was not being initialised (This used to be commit 44c897764e6e2b9cfc4398fd3df52dc3eda6b341) --- source4/ntvfs/posix/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 5fd6e58d2e..2d7a4dc928 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -2,7 +2,7 @@ # Start MODULE pvfs_acl_xattr [MODULE::pvfs_acl_xattr] INIT_FUNCTION = pvfs_acl_xattr_init -SUBSYSTEM = ntvfs_posix +SUBSYSTEM = ntvfs OBJ_FILES = \ pvfs_acl_xattr.o PRIVATE_DEPENDENCIES = NDR_XATTR -- cgit From 13dbee3ffea6065a826f010e50c9b4eb2c6ad109 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 7 Nov 2006 00:48:36 +0000 Subject: r19598: Ahead of a merge to current lorikeet-heimdal: Break up auth/auth.h not to include the world. Add credentials_krb5.h with the kerberos dependent prototypes. Andrew Bartlett (This used to be commit 2b569c42e0fbb596ea82484d0e1cb22e193037b9) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index bfdb5b92fc..185e9a3438 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -29,6 +29,7 @@ #include "libcli/raw/libcliraw.h" #include "libcli/smb_composite/smb_composite.h" #include "auth/auth.h" +#include "auth/credentials/credentials.h" #include "ntvfs/ntvfs.h" #include "lib/util/dlinklist.h" -- cgit From 273d5f866653db0190c334c086bbfbd88d0ac3cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 11 Nov 2006 23:14:58 +0000 Subject: r19671: Fix remaining unresolved symbols in shared library build. Fix starting tests in shared library build. (This used to be commit 3b65a0d6e491a57ed216dc0cd9c31d46e0cb6a35) --- source4/ntvfs/posix/config.mk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 2d7a4dc928..7845b21662 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -5,7 +5,7 @@ INIT_FUNCTION = pvfs_acl_xattr_init SUBSYSTEM = ntvfs OBJ_FILES = \ pvfs_acl_xattr.o -PRIVATE_DEPENDENCIES = NDR_XATTR +PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ @@ -16,6 +16,7 @@ INIT_FUNCTION = pvfs_acl_nfs4_init SUBSYSTEM = ntvfs OBJ_FILES = \ pvfs_acl_nfs4.o +PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ @@ -23,6 +24,7 @@ OBJ_FILES = \ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] SUBSYSTEM = ntvfs +OUTPUT_TYPE = INTEGRATED INIT_FUNCTION = ntvfs_posix_init PRIVATE_PROTO_HEADER = vfs_posix_proto.h OBJ_FILES = \ -- cgit From c81f2930a2df7cbd72a28e167ac522d2638661ea Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 12 Nov 2006 02:49:05 +0000 Subject: r19676: Fix some more dependencies. (This used to be commit 8768bec81f57131a0c9754e8121b345c0be4a5d0) --- source4/ntvfs/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index a985348fdb..8dd71ed56f 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -90,6 +90,7 @@ OBJ_FILES = \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o +PRIVATE_DEPENDENCIES = auth # # End SUBSYSTEM NTVFS ################################################ -- cgit From e0e96ae80d21c6b94e05fbf3af457001a005ce09 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Jan 2007 04:04:26 +0000 Subject: r20624: added AIO read to pvfs backend (This used to be commit d6e20d6d8c5c207e7f04b0d0523224437b209917) --- source4/ntvfs/posix/config.m4 | 6 +++ source4/ntvfs/posix/config.mk | 9 +++- source4/ntvfs/posix/pvfs_aio.c | 96 +++++++++++++++++++++++++++++++++++++++++ source4/ntvfs/posix/pvfs_read.c | 12 +++++- source4/ntvfs/posix/vfs_posix.c | 5 ++- source4/ntvfs/posix/vfs_posix.h | 5 +++ 6 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 source4/ntvfs/posix/pvfs_aio.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.m4 b/source4/ntvfs/posix/config.m4 index c2cdf0ecaf..fe1997b437 100644 --- a/source4/ntvfs/posix/config.m4 +++ b/source4/ntvfs/posix/config.m4 @@ -29,3 +29,9 @@ if test x"$ac_cv_func_ext_blkid_get_cache" = x"yes"; then AC_DEFINE(HAVE_LIBBLKID,1,[Whether we have blkid support (e2fsprogs)]) SMB_ENABLE(BLKID,YES) fi + +AC_CHECK_HEADERS(libaio.h) +SMB_ENABLE(pvfs_aio,NO) +if test x"$ac_cv_header_libaio_h" = x"yes"; then + SMB_ENABLE(pvfs_aio,YES) +fi diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 7845b21662..91dc7bd9e5 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -20,6 +20,13 @@ PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ +################################################ +[MODULE::pvfs_aio] +SUBSYSTEM = ntvfs +OBJ_FILES = pvfs_aio.o +PRIVATE_DEPENDENCIES = LIBAIO_LINUX +################################################ + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -56,6 +63,6 @@ OBJ_FILES = \ xattr_system.o \ xattr_tdb.o #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 -PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING +PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/posix/pvfs_aio.c b/source4/ntvfs/posix/pvfs_aio.c new file mode 100644 index 0000000000..262b856aa9 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_aio.c @@ -0,0 +1,96 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - Linux AIO calls + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "vfs_posix.h" +#include "lib/events/events.h" +#include "system/aio.h" + +struct pvfs_aio_read_state { + struct ntvfs_request *req; + union smb_read *rd; + struct pvfs_file *f; + struct aio_event *ae; +}; + +/* + called when an aio read has finished +*/ +static void pvfs_aio_handler(struct event_context *ev, struct aio_event *ae, + int ret, void *private) +{ + struct pvfs_aio_read_state *state = talloc_get_type(private, + struct pvfs_aio_read_state); + struct pvfs_file *f = state->f; + union smb_read *rd = state->rd; + + if (ret < 0) { + /* errno is -ret on error */ + state->req->async_states->status = pvfs_map_errno(f->pvfs, -ret); + state->req->async_states->send_fn(state->req); + return; + } + + f->handle->position = f->handle->seek_offset = rd->readx.in.offset + ret; + + rd->readx.out.nread = ret; + rd->readx.out.remaining = 0xFFFF; + rd->readx.out.compaction_mode = 0; + + talloc_steal(ev, state->ae); + + state->req->async_states->status = NT_STATUS_OK; + state->req->async_states->send_fn(state->req); +} + + +/* + read from a file +*/ +NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd, + struct pvfs_file *f, uint32_t maxcnt) +{ + struct iocb iocb; + struct pvfs_aio_read_state *state; + + state = talloc(req, struct pvfs_aio_read_state); + NT_STATUS_HAVE_NO_MEMORY(state); + + io_prep_pread(&iocb, f->handle->fd, rd->readx.out.data, + maxcnt, rd->readx.in.offset); + state->ae = event_add_aio(req->ctx->event_ctx, req->ctx->event_ctx, &iocb, + pvfs_aio_handler, state); + if (state->ae == NULL) { + DEBUG(0,("Failed event_add_aio\n")); + talloc_free(state); + return NT_STATUS_NOT_IMPLEMENTED; + } + + state->req = req; + state->rd = rd; + state->f = f; + + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + + return NT_STATUS_OK; +} + diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index c36d8ca2a3..91945dbb0f 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" -#include "librpc/gen_ndr/security.h" +#include "lib/events/events.h" /* read from a file @@ -75,6 +75,16 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, ret = pvfs_stream_read(pvfs, f->handle, rd->readx.out.data, maxcnt, rd->readx.in.offset); } else { +#if HAVE_LINUX_AIO + /* possibly try an aio read */ + if ((req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC) && + (pvfs->flags & PVFS_FLAG_LINUX_AIO)) { + status = pvfs_aio_pread(req, rd, f, maxcnt); + if (NT_STATUS_IS_OK(status)) { + return NT_STATUS_OK; + } + } +#endif ret = pread(f->handle->fd, rd->readx.out.data, maxcnt, diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ad47908b6e..c8d85b557c 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -55,9 +55,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->flags |= PVFS_FLAG_STRICT_LOCKING; if (share_bool_option(scfg, SHARE_CI_FILESYSTEM, SHARE_CI_FILESYSTEM_DEFAULT)) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; - if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT)) { + if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT)) pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; - } + if (share_bool_option(scfg, PVFS_AIO, False)) + pvfs->flags |= PVFS_FLAG_LINUX_AIO; /* this must be a power of 2 */ pvfs->alloc_size_rounding = share_int_option(scfg, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 4a81088d1c..4fd4cb82d8 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -210,6 +210,7 @@ struct pvfs_search_state { #define PVFS_FLAG_STRICT_LOCKING (1<<6) #define PVFS_FLAG_XATTR_ENABLE (1<<7) #define PVFS_FLAG_FAKE_OPLOCKS (1<<8) +#define PVFS_FLAG_LINUX_AIO (1<<9) /* forward declare some anonymous structures */ struct pvfs_dir; @@ -224,6 +225,7 @@ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; #define PVFS_ALLOCATION_ROUNDING "posix:allocationrounding" #define PVFS_SEARCH_INACTIVITY "posix:searchinactivity" #define PVFS_ACL "posix:acl" +#define PVFS_AIO "posix:aio" #define PVFS_XATTR_DEFAULT True #define PVFS_FAKE_OPLOCKS_DEFAULT False @@ -240,4 +242,7 @@ struct pvfs_acl_ops { #include "ntvfs/posix/vfs_posix_proto.h" +NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd, + struct pvfs_file *f, uint32_t maxcnt); + #endif /* _VFS_POSIX_H_ */ -- cgit From 1cd4339b9a2786aa26691ca4f02fa93ab0958b88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 Jan 2007 10:52:09 +0000 Subject: r20646: first preparations for cluster enablement. This changes " uint32_t server_id to struct server_id server_id; which allows a server ID to have an node number. The node number will be zero in non-clustered case. This is the most basic hook needed for clustering, and ctdb. (This used to be commit 2365abaa991d57d68c6ebe9be608e01c907102eb) --- source4/ntvfs/common/brlock.c | 14 +++++++------- source4/ntvfs/common/notify.c | 12 ++++++------ source4/ntvfs/common/opendb.c | 4 ++-- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/ntvfs_base.c | 2 +- source4/ntvfs/posix/pvfs_wait.c | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 2816c563b8..d7fb97415f 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -47,7 +47,7 @@ struct brl_context; lock is the same as another lock */ struct lock_context { - uint32_t server; + struct server_id server; uint16_t smbpid; struct brl_context *ctx; }; @@ -74,7 +74,7 @@ struct brl_handle { /* this struct is typicaly attached to tcon */ struct brl_context { struct tdb_wrap *w; - uint32_t server; + struct server_id server; struct messaging_context *messaging_ctx; }; @@ -83,7 +83,7 @@ struct brl_context { talloc_free(). We need the messaging_ctx to allow for pending lock notifications. */ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, uint32_t server, +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx) { char *path; @@ -130,7 +130,7 @@ struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *n */ static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) { - return (ctx1->server == ctx2->server && + return (cluster_id_equal(&ctx1->server, &ctx2->server) && ctx1->smbpid == ctx2->smbpid && ctx1->ctx == ctx2->ctx); } @@ -249,7 +249,7 @@ static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *loc * if the current lock matches the last failed lock on the file handle * and starts at the same offset, then FILE_LOCK_CONFLICT should be returned */ - if (lock->context.server == brlh->last_lock.context.server && + if (cluster_id_equal(&lock->context.server, &brlh->last_lock.context.server) && lock->context.ctx == brlh->last_lock.context.ctx && lock->ntvfs == brlh->last_lock.ntvfs && lock->start == brlh->last_lock.start) { @@ -535,7 +535,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, if (lock->lock_type >= PENDING_READ_LOCK && lock->notify_ptr == notify_ptr && - lock->context.server == brl->server) { + cluster_id_equal(&lock->context.server, &brl->server)) { /* found it - delete it */ if (count == 1) { if (tdb_delete(brl->w->tdb, kbuf) != 0) { @@ -648,7 +648,7 @@ NTSTATUS brl_close(struct brl_context *brl, struct lock_struct *lock = &locks[i]; if (lock->context.ctx == brl && - lock->context.server == brl->server && + cluster_id_equal(&lock->context.server, &brl->server) && lock->ntvfs == brlh->ntvfs) { /* found it - delete it */ if (count > 1 && i < count-1) { diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 19a60a51a9..13fd44abf0 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -37,7 +37,7 @@ struct notify_context { struct tdb_wrap *w; - uint32_t server; + struct server_id server; struct messaging_context *messaging_ctx; struct notify_list *list; struct notify_array *array; @@ -61,7 +61,7 @@ struct notify_list { static NTSTATUS notify_remove_all(struct notify_context *notify); static void notify_handler(struct messaging_context *msg_ctx, void *private, - uint32_t msg_type, uint32_t server_id, DATA_BLOB *data); + uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); /* destroy the notify context @@ -78,7 +78,7 @@ static int notify_destructor(struct notify_context *notify) talloc_free(). We need the messaging_ctx to allow for notifications via internal messages */ -struct notify_context *notify_init(TALLOC_CTX *mem_ctx, uint32_t server, +struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx, struct event_context *ev, struct share_config *scfg) @@ -241,7 +241,7 @@ static NTSTATUS notify_save(struct notify_context *notify) handle incoming notify messages */ static void notify_handler(struct messaging_context *msg_ctx, void *private, - uint32_t msg_type, uint32_t server_id, DATA_BLOB *data) + uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { struct notify_context *notify = talloc_get_type(private, struct notify_context); NTSTATUS status; @@ -460,7 +460,7 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) for (i=0;inum_entries;i++) { if (private == d->entries[i].private && - notify->server == d->entries[i].server) { + cluster_id_equal(¬ify->server, &d->entries[i].server)) { break; } } @@ -508,7 +508,7 @@ static NTSTATUS notify_remove_all(struct notify_context *notify) for (depth=0;deptharray->num_depths;depth++) { struct notify_depth *d = ¬ify->array->depth[depth]; for (i=0;inum_entries;i++) { - if (notify->server == d->entries[i].server) { + if (cluster_id_equal(¬ify->server, &d->entries[i].server)) { if (i < d->num_entries-1) { memmove(&d->entries[i], &d->entries[i+1], sizeof(d->entries[i])*(d->num_entries-(i+1))); diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index c63a677847..e1766d670e 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -408,7 +408,7 @@ _PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) /* find the entry, and delete it */ for (i=0;intvfs_ctx->server_id == file.entries[i].server) { + cluster_id_equal(&odb->ntvfs_ctx->server_id, &file.entries[i].server)) { if (file.entries[i].delete_on_close) { file.delete_on_close = True; } @@ -455,7 +455,7 @@ _PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) /* find the entry, and delete it */ for (i=0;intvfs_ctx->server_id == file.pending[i].server) { + cluster_id_equal(&odb->ntvfs_ctx->server_id, &file.pending[i].server)) { if (i < file.num_pending-1) { memmove(file.pending+i, file.pending+i+1, (file.num_pending - (i+1)) * diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index b48a5dac00..69e638e1a1 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -184,7 +184,7 @@ struct ntvfs_context { struct share_config *config; - uint32_t server_id; + struct server_id server_id; struct event_context *event_ctx; struct messaging_context *msg_ctx; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 7e794b582f..599669360b 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -154,7 +154,7 @@ _PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const i NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, enum ntvfs_type type, enum protocol_types protocol, struct event_context *ev, struct messaging_context *msg, - uint32_t server_id, struct ntvfs_context **_ctx) + struct server_id server_id, struct ntvfs_context **_ctx) { const char **handlers = share_string_list_option(mem_ctx, scfg, SHARE_NTVFS_HANDLER); int i; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 41c5f4742e..6e8324183f 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -57,7 +57,7 @@ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, receive a completion message for a wait */ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uint32_t msg_type, - uint32_t src, DATA_BLOB *data) + struct server_id src, DATA_BLOB *data) { struct pvfs_wait *pwait = private; struct ntvfs_request *req; -- cgit From 98ac70b6a3f7eb48beb86f543f629f77d2aa4549 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 10 Jan 2007 13:25:39 +0000 Subject: r20653: If this is the wrong way to fix the build, I apologize. But these includes are necessary in my environment to get through make. Volker (This used to be commit 47e80da39f27a7e7aa6f85d6333f2d1772292ec9) --- source4/ntvfs/common/brlock.c | 1 + source4/ntvfs/common/notify.c | 1 + source4/ntvfs/common/opendb.c | 1 + 3 files changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index d7fb97415f..c42c2f3a11 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -32,6 +32,7 @@ #include "db_wrap.h" #include "lib/messaging/irpc.h" #include "libcli/libcli.h" +#include "cluster/cluster.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 13fd44abf0..8ba918d8af 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -34,6 +34,7 @@ #include "librpc/gen_ndr/ndr_notify.h" #include "lib/util/dlinklist.h" #include "ntvfs/sysdep/sys_notify.h" +#include "cluster/cluster.h" struct notify_context { struct tdb_wrap *w; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index e1766d670e..df6bb7249b 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -46,6 +46,7 @@ #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" #include "ntvfs/ntvfs.h" +#include "cluster/cluster.h" struct odb_context { struct tdb_wrap *w; -- cgit From 427fa23ca536f0a0388460f05bd2422e13e04414 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Jan 2007 05:47:00 +0000 Subject: r20698: added AIO writing support (This used to be commit dbf54c7b49d427af8112414760369cd21c8b5941) --- source4/ntvfs/posix/pvfs_aio.c | 75 ++++++++++++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_write.c | 10 ++++++ source4/ntvfs/posix/vfs_posix.h | 2 ++ 3 files changed, 85 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_aio.c b/source4/ntvfs/posix/pvfs_aio.c index 262b856aa9..f40382b5ec 100644 --- a/source4/ntvfs/posix/pvfs_aio.c +++ b/source4/ntvfs/posix/pvfs_aio.c @@ -32,10 +32,17 @@ struct pvfs_aio_read_state { struct aio_event *ae; }; +struct pvfs_aio_write_state { + struct ntvfs_request *req; + union smb_write *wr; + struct pvfs_file *f; + struct aio_event *ae; +}; + /* called when an aio read has finished */ -static void pvfs_aio_handler(struct event_context *ev, struct aio_event *ae, +static void pvfs_aio_read_handler(struct event_context *ev, struct aio_event *ae, int ret, void *private) { struct pvfs_aio_read_state *state = talloc_get_type(private, @@ -78,7 +85,7 @@ NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd, io_prep_pread(&iocb, f->handle->fd, rd->readx.out.data, maxcnt, rd->readx.in.offset); state->ae = event_add_aio(req->ctx->event_ctx, req->ctx->event_ctx, &iocb, - pvfs_aio_handler, state); + pvfs_aio_read_handler, state); if (state->ae == NULL) { DEBUG(0,("Failed event_add_aio\n")); talloc_free(state); @@ -94,3 +101,67 @@ NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd, return NT_STATUS_OK; } + + + +/* + called when an aio write has finished +*/ +static void pvfs_aio_write_handler(struct event_context *ev, struct aio_event *ae, + int ret, void *private) +{ + struct pvfs_aio_write_state *state = talloc_get_type(private, + struct pvfs_aio_write_state); + struct pvfs_file *f = state->f; + union smb_write *wr = state->wr; + + if (ret < 0) { + /* errno is -ret on error */ + state->req->async_states->status = pvfs_map_errno(f->pvfs, -ret); + state->req->async_states->send_fn(state->req); + return; + } + + f->handle->seek_offset = wr->writex.in.offset + ret; + + wr->writex.out.nwritten = ret; + wr->writex.out.remaining = 0; + + talloc_steal(ev, state->ae); + + state->req->async_states->status = NT_STATUS_OK; + state->req->async_states->send_fn(state->req); +} + + +/* + write to a file +*/ +NTSTATUS pvfs_aio_pwrite(struct ntvfs_request *req, union smb_write *wr, + struct pvfs_file *f) +{ + struct iocb iocb; + struct pvfs_aio_write_state *state; + + state = talloc(req, struct pvfs_aio_write_state); + NT_STATUS_HAVE_NO_MEMORY(state); + + io_prep_pwrite(&iocb, f->handle->fd, wr->writex.in.data, + wr->writex.in.count, wr->writex.in.offset); + state->ae = event_add_aio(req->ctx->event_ctx, req->ctx->event_ctx, &iocb, + pvfs_aio_write_handler, state); + if (state->ae == NULL) { + DEBUG(0,("Failed event_add_aio\n")); + talloc_free(state); + return NT_STATUS_NOT_IMPLEMENTED; + } + + state->req = req; + state->wr = wr; + state->f = f; + + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + + return NT_STATUS_OK; +} + diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 9f58281919..d433a80cc6 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -66,6 +66,16 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, wr->writex.in.count, wr->writex.in.offset); } else { +#if HAVE_LINUX_AIO + /* possibly try an aio write */ + if ((req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC) && + (pvfs->flags & PVFS_FLAG_LINUX_AIO)) { + status = pvfs_aio_pwrite(req, wr, f); + if (NT_STATUS_IS_OK(status)) { + return NT_STATUS_OK; + } + } +#endif ret = pwrite(f->handle->fd, wr->writex.in.data, wr->writex.in.count, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 4fd4cb82d8..5bb9dcf811 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -244,5 +244,7 @@ struct pvfs_acl_ops { NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd, struct pvfs_file *f, uint32_t maxcnt); +NTSTATUS pvfs_aio_pwrite(struct ntvfs_request *req, union smb_write *wr, + struct pvfs_file *f); #endif /* _VFS_POSIX_H_ */ -- cgit From 20b406ce23a467b1424e3de9f82f54b9385a951d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jan 2007 03:55:17 +0000 Subject: r20890: spelling fix (This used to be commit 507266b951272534f0a0bad5fd5e2450438dcdf1) --- source4/ntvfs/posix/pvfs_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 2a6a19133a..2e0f77616b 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -85,7 +85,7 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, /* called when we receive a pending lock notification. It means that - either our lock timed out or somoene else has unlocked a overlapping + either our lock timed out or someone else has unlocked a overlapping range, so we should try the lock again. Note that on timeout we do retry the lock, giving it a last chance. */ -- cgit From be05a5ca2525f7f3ab732a5b5c7baceb7c7a4ada Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jan 2007 03:58:16 +0000 Subject: r20891: enable multiple brlock backends. The tdb backend is the default. The prototype ctdb backend is in cluster/ctdb/brlock_ctdb.c (This used to be commit 84d0e5316299931dc26f2a7b86962d2fffcc4b71) --- source4/ntvfs/common/brlock.c | 689 ------------------------------------- source4/ntvfs/common/brlock.h | 53 +++ source4/ntvfs/common/brlock_tdb.c | 706 ++++++++++++++++++++++++++++++++++++++ source4/ntvfs/common/config.mk | 1 + 4 files changed, 760 insertions(+), 689 deletions(-) delete mode 100644 source4/ntvfs/common/brlock.c create mode 100644 source4/ntvfs/common/brlock.h create mode 100644 source4/ntvfs/common/brlock_tdb.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c deleted file mode 100644 index c42c2f3a11..0000000000 --- a/source4/ntvfs/common/brlock.c +++ /dev/null @@ -1,689 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - generic byte range locking code - - Copyright (C) Andrew Tridgell 1992-2004 - Copyright (C) Jeremy Allison 1992-2000 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* This module implements a tdb based byte range locking service, - replacing the fcntl() based byte range locking previously - used. This allows us to provide the same semantics as NT */ - -#include "includes.h" -#include "system/filesys.h" -#include "lib/tdb/include/tdb.h" -#include "messaging/messaging.h" -#include "db_wrap.h" -#include "lib/messaging/irpc.h" -#include "libcli/libcli.h" -#include "cluster/cluster.h" - -/* - in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies - a file. For a local posix filesystem this will usually be a combination - of the device and inode numbers of the file, but it can be anything - that uniquely idetifies a file for locking purposes, as long - as it is applied consistently. -*/ - -struct brl_context; -/* - the lock context contains the elements that define whether one - lock is the same as another lock -*/ -struct lock_context { - struct server_id server; - uint16_t smbpid; - struct brl_context *ctx; -}; - -/* The data in brlock records is an unsorted linear array of these - records. It is unnecessary to store the count as tdb provides the - size of the record */ -struct lock_struct { - struct lock_context context; - struct ntvfs_handle *ntvfs; - uint64_t start; - uint64_t size; - enum brl_type lock_type; - void *notify_ptr; -}; - -/* this struct is attached to on oprn file handle */ -struct brl_handle { - DATA_BLOB key; - struct ntvfs_handle *ntvfs; - struct lock_struct last_lock; -}; - -/* this struct is typicaly attached to tcon */ -struct brl_context { - struct tdb_wrap *w; - struct server_id server; - struct messaging_context *messaging_ctx; -}; - -/* - Open up the brlock.tdb database. Close it down using - talloc_free(). We need the messaging_ctx to allow for - pending lock notifications. -*/ -struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, - struct messaging_context *messaging_ctx) -{ - char *path; - struct brl_context *brl; - - brl = talloc(mem_ctx, struct brl_context); - if (brl == NULL) { - return NULL; - } - - path = smbd_tmp_path(brl, "brlock.tdb"); - brl->w = tdb_wrap_open(brl, path, 0, - TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - talloc_free(path); - if (brl->w == NULL) { - talloc_free(brl); - return NULL; - } - - brl->server = server; - brl->messaging_ctx = messaging_ctx; - - return brl; -} - -struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) -{ - struct brl_handle *brlh; - - brlh = talloc(mem_ctx, struct brl_handle); - if (brlh == NULL) { - return NULL; - } - - brlh->key = *file_key; - brlh->ntvfs = ntvfs; - ZERO_STRUCT(brlh->last_lock); - - return brlh; -} - -/* - see if two locking contexts are equal -*/ -static BOOL brl_same_context(struct lock_context *ctx1, struct lock_context *ctx2) -{ - return (cluster_id_equal(&ctx1->server, &ctx2->server) && - ctx1->smbpid == ctx2->smbpid && - ctx1->ctx == ctx2->ctx); -} - -/* - see if lck1 and lck2 overlap -*/ -static BOOL brl_overlap(struct lock_struct *lck1, - struct lock_struct *lck2) -{ - /* this extra check is not redundent - it copes with locks - that go beyond the end of 64 bit file space */ - if (lck1->size != 0 && - lck1->start == lck2->start && - lck1->size == lck2->size) { - return True; - } - - if (lck1->start >= (lck2->start+lck2->size) || - lck2->start >= (lck1->start+lck1->size)) { - return False; - } - return True; -} - -/* - See if lock2 can be added when lock1 is in place. -*/ -static BOOL brl_conflict(struct lock_struct *lck1, - struct lock_struct *lck2) -{ - /* pending locks don't conflict with anything */ - if (lck1->lock_type >= PENDING_READ_LOCK || - lck2->lock_type >= PENDING_READ_LOCK) { - return False; - } - - if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { - return False; - } - - if (brl_same_context(&lck1->context, &lck2->context) && - lck2->lock_type == READ_LOCK && lck1->ntvfs == lck2->ntvfs) { - return False; - } - - return brl_overlap(lck1, lck2); -} - - -/* - Check to see if this lock conflicts, but ignore our own locks on the - same fnum only. -*/ -static BOOL brl_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) -{ - /* pending locks don't conflict with anything */ - if (lck1->lock_type >= PENDING_READ_LOCK || - lck2->lock_type >= PENDING_READ_LOCK) { - return False; - } - - if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) - return False; - - /* - * note that incoming write calls conflict with existing READ - * locks even if the context is the same. JRA. See LOCKTEST7 - * in smbtorture. - */ - if (brl_same_context(&lck1->context, &lck2->context) && - lck1->ntvfs == lck2->ntvfs && - (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { - return False; - } - - return brl_overlap(lck1, lck2); -} - - -/* - amazingly enough, w2k3 "remembers" whether the last lock failure - is the same as this one and changes its error code. I wonder if any - app depends on this? -*/ -static NTSTATUS brl_lock_failed(struct brl_handle *brlh, struct lock_struct *lock) -{ - /* - * this function is only called for non pending lock! - */ - - /* - * if the notify_ptr is non NULL, - * it means that we're at the end of a pending lock - * and the real lock is requested after the timout went by - * In this case we need to remember the last_lock and always - * give FILE_LOCK_CONFLICT - */ - if (lock->notify_ptr) { - brlh->last_lock = *lock; - return NT_STATUS_FILE_LOCK_CONFLICT; - } - - /* - * amazing the little things you learn with a test - * suite. Locks beyond this offset (as a 64 bit - * number!) always generate the conflict error code, - * unless the top bit is set - */ - if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { - brlh->last_lock = *lock; - return NT_STATUS_FILE_LOCK_CONFLICT; - } - - /* - * if the current lock matches the last failed lock on the file handle - * and starts at the same offset, then FILE_LOCK_CONFLICT should be returned - */ - if (cluster_id_equal(&lock->context.server, &brlh->last_lock.context.server) && - lock->context.ctx == brlh->last_lock.context.ctx && - lock->ntvfs == brlh->last_lock.ntvfs && - lock->start == brlh->last_lock.start) { - return NT_STATUS_FILE_LOCK_CONFLICT; - } - - brlh->last_lock = *lock; - return NT_STATUS_LOCK_NOT_GRANTED; -} - -/* - Lock a range of bytes. The lock_type can be a PENDING_*_LOCK, in - which case a real lock is first tried, and if that fails then a - pending lock is created. When the pending lock is triggered (by - someone else closing an overlapping lock range) a messaging - notification is sent, identified by the notify_ptr -*/ -NTSTATUS brl_lock(struct brl_context *brl, - struct brl_handle *brlh, - uint16_t smbpid, - uint64_t start, uint64_t size, - enum brl_type lock_type, - void *notify_ptr) -{ - TDB_DATA kbuf, dbuf; - int count=0, i; - struct lock_struct lock, *locks=NULL; - NTSTATUS status; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - /* if this is a pending lock, then with the chainlock held we - try to get the real lock. If we succeed then we don't need - to make it pending. This prevents a possible race condition - where the pending lock gets created after the lock that is - preventing the real lock gets removed */ - if (lock_type >= PENDING_READ_LOCK) { - enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); - - /* here we need to force that the last_lock isn't overwritten */ - lock = brlh->last_lock; - status = brl_lock(brl, brlh, smbpid, start, size, rw, NULL); - brlh->last_lock = lock; - - if (NT_STATUS_IS_OK(status)) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - - lock.context.smbpid = smbpid; - lock.context.server = brl->server; - lock.context.ctx = brl; - lock.ntvfs = brlh->ntvfs; - lock.context.ctx = brl; - lock.start = start; - lock.size = size; - lock.lock_type = lock_type; - lock.notify_ptr = notify_ptr; - - if (dbuf.dptr) { - /* there are existing locks - make sure they don't conflict */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - for (i=0; iw->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - - /* the caller needs to know if the real lock was granted. If - we have reached here then it must be a pending lock that - was granted, so tell them the lock failed */ - if (lock_type >= PENDING_READ_LOCK) { - return NT_STATUS_LOCK_NOT_GRANTED; - } - - return NT_STATUS_OK; - - fail: - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return status; -} - - -/* - we are removing a lock that might be holding up a pending lock. Scan for pending - locks that cover this range and if we find any then notify the server that it should - retry the lock -*/ -static void brl_notify_unlock(struct brl_context *brl, - struct lock_struct *locks, int count, - struct lock_struct *removed_lock) -{ - int i, last_notice; - - /* the last_notice logic is to prevent stampeding on a lock - range. It prevents us sending hundreds of notifies on the - same range of bytes. It doesn't prevent all possible - stampedes, but it does prevent the most common problem */ - last_notice = -1; - - for (i=0;i= PENDING_READ_LOCK && - brl_overlap(&locks[i], removed_lock)) { - if (last_notice != -1 && brl_overlap(&locks[i], &locks[last_notice])) { - continue; - } - if (locks[i].lock_type == PENDING_WRITE_LOCK) { - last_notice = i; - } - messaging_send_ptr(brl->messaging_ctx, locks[i].context.server, - MSG_BRL_RETRY, locks[i].notify_ptr); - } - } -} - - -/* - send notifications for all pending locks - the file is being closed by this - user -*/ -static void brl_notify_all(struct brl_context *brl, - struct lock_struct *locks, int count) -{ - int i; - for (i=0;ilock_type >= PENDING_READ_LOCK) { - brl_notify_unlock(brl, locks, count, &locks[i]); - } - } -} - - - -/* - Unlock a range of bytes. -*/ -NTSTATUS brl_unlock(struct brl_context *brl, - struct brl_handle *brlh, - uint16_t smbpid, - uint64_t start, uint64_t size) -{ - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct *locks; - struct lock_context context; - NTSTATUS status; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_RANGE_NOT_LOCKED; - } - - context.smbpid = smbpid; - context.server = brl->server; - context.ctx = brl; - - /* there are existing locks - find a match */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; icontext, &context) && - lock->ntvfs == brlh->ntvfs && - lock->start == start && - lock->size == size && - lock->lock_type < PENDING_READ_LOCK) { - /* found it - delete it */ - if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } else { - struct lock_struct removed_lock = *lock; - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - - /* send notifications for any relevant pending locks */ - brl_notify_unlock(brl, locks, count, &removed_lock); - - dbuf.dsize = count * sizeof(*locks); - - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - } - - /* we didn't find it */ - status = NT_STATUS_RANGE_NOT_LOCKED; - - fail: - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return status; -} - - -/* - remove a pending lock. This is called when the caller has either - given up trying to establish a lock or when they have succeeded in - getting it. In either case they no longer need to be notified. -*/ -NTSTATUS brl_remove_pending(struct brl_context *brl, - struct brl_handle *brlh, - void *notify_ptr) -{ - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct *locks; - NTSTATUS status; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_RANGE_NOT_LOCKED; - } - - /* there are existing locks - find a match */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; ilock_type >= PENDING_READ_LOCK && - lock->notify_ptr == notify_ptr && - cluster_id_equal(&lock->context.server, &brl->server)) { - /* found it - delete it */ - if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } else { - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - dbuf.dsize = count * sizeof(*locks); - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - } - - /* we didn't find it */ - status = NT_STATUS_RANGE_NOT_LOCKED; - - fail: - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return status; -} - - -/* - Test if we are allowed to perform IO on a region of an open file -*/ -NTSTATUS brl_locktest(struct brl_context *brl, - struct brl_handle *brlh, - uint16_t smbpid, - uint64_t start, uint64_t size, - enum brl_type lock_type) -{ - TDB_DATA kbuf, dbuf; - int count, i; - struct lock_struct lock, *locks; - - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (dbuf.dptr == NULL) { - return NT_STATUS_OK; - } - - lock.context.smbpid = smbpid; - lock.context.server = brl->server; - lock.context.ctx = brl; - lock.ntvfs = brlh->ntvfs; - lock.start = start; - lock.size = size; - lock.lock_type = lock_type; - - /* there are existing locks - make sure they don't conflict */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; ikey.data; - kbuf.dsize = brlh->key.length; - - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; - } - - /* there are existing locks - remove any for this fnum */ - locks = (struct lock_struct *)dbuf.dptr; - count = dbuf.dsize / sizeof(*locks); - - for (i=0; icontext.ctx == brl && - cluster_id_equal(&lock->context.server, &brl->server) && - lock->ntvfs == brlh->ntvfs) { - /* found it - delete it */ - if (count > 1 && i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - i--; - dcount++; - } - } - - status = NT_STATUS_OK; - - if (count == 0) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } else if (dcount != 0) { - /* tell all pending lock holders for this file that - they have a chance now. This is a bit indiscriminant, - but works OK */ - brl_notify_all(brl, locks, count); - - dbuf.dsize = count * sizeof(*locks); - - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - - return status; -} - diff --git a/source4/ntvfs/common/brlock.h b/source4/ntvfs/common/brlock.h new file mode 100644 index 0000000000..a462254ddf --- /dev/null +++ b/source4/ntvfs/common/brlock.h @@ -0,0 +1,53 @@ +/* + Unix SMB/CIFS implementation. + + generic byte range locking code - common include + + Copyright (C) Andrew Tridgell 2006 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +struct brlock_ops { + struct brl_context *(*brl_init)(TALLOC_CTX *, struct server_id , + struct messaging_context *); + struct brl_handle *(*brl_create_handle)(TALLOC_CTX *, struct ntvfs_handle *, DATA_BLOB *); + NTSTATUS (*brl_lock)(struct brl_context *, + struct brl_handle *, + uint16_t , + uint64_t , uint64_t , + enum brl_type , + void *); + NTSTATUS (*brl_unlock)(struct brl_context *, + struct brl_handle *, + uint16_t , + uint64_t , uint64_t ); + NTSTATUS (*brl_remove_pending)(struct brl_context *, + struct brl_handle *, + void *); + NTSTATUS (*brl_locktest)(struct brl_context *, + struct brl_handle *, + uint16_t , + uint64_t , uint64_t , + enum brl_type ); + NTSTATUS (*brl_close)(struct brl_context *, + struct brl_handle *); +}; + + +void brl_set_ops(const struct brlock_ops *new_ops); +void brl_tdb_init_ops(void); +void brl_ctdb_init_ops(void); + diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c new file mode 100644 index 0000000000..34c0b7e979 --- /dev/null +++ b/source4/ntvfs/common/brlock_tdb.c @@ -0,0 +1,706 @@ +/* + Unix SMB/CIFS implementation. + + generic byte range locking code - tdb backend + + Copyright (C) Andrew Tridgell 1992-2006 + Copyright (C) Jeremy Allison 1992-2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* This module implements a tdb based byte range locking service, + replacing the fcntl() based byte range locking previously + used. This allows us to provide the same semantics as NT */ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/tdb/include/tdb.h" +#include "messaging/messaging.h" +#include "db_wrap.h" +#include "lib/messaging/irpc.h" +#include "libcli/libcli.h" +#include "cluster/cluster.h" +#include "ntvfs/common/brlock.h" + +/* + in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies + a file. For a local posix filesystem this will usually be a combination + of the device and inode numbers of the file, but it can be anything + that uniquely idetifies a file for locking purposes, as long + as it is applied consistently. +*/ + +/* this struct is typicaly attached to tcon */ +struct brl_context { + struct tdb_wrap *w; + struct server_id server; + struct messaging_context *messaging_ctx; +}; + +/* + the lock context contains the elements that define whether one + lock is the same as another lock +*/ +struct lock_context { + struct server_id server; + uint16_t smbpid; + struct brl_context *ctx; +}; + +/* The data in brlock records is an unsorted linear array of these + records. It is unnecessary to store the count as tdb provides the + size of the record */ +struct lock_struct { + struct lock_context context; + struct ntvfs_handle *ntvfs; + uint64_t start; + uint64_t size; + enum brl_type lock_type; + void *notify_ptr; +}; + +/* this struct is attached to on oprn file handle */ +struct brl_handle { + DATA_BLOB key; + struct ntvfs_handle *ntvfs; + struct lock_struct last_lock; +}; + +/* + Open up the brlock.tdb database. Close it down using + talloc_free(). We need the messaging_ctx to allow for + pending lock notifications. +*/ +static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id server, + struct messaging_context *messaging_ctx) +{ + char *path; + struct brl_context *brl; + + brl = talloc(mem_ctx, struct brl_context); + if (brl == NULL) { + return NULL; + } + + path = smbd_tmp_path(brl, "brlock.tdb"); + brl->w = tdb_wrap_open(brl, path, 0, + TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + talloc_free(path); + if (brl->w == NULL) { + talloc_free(brl); + return NULL; + } + + brl->server = server; + brl->messaging_ctx = messaging_ctx; + + return brl; +} + +static struct brl_handle *brl_tdb_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, + DATA_BLOB *file_key) +{ + struct brl_handle *brlh; + + brlh = talloc(mem_ctx, struct brl_handle); + if (brlh == NULL) { + return NULL; + } + + brlh->key = *file_key; + brlh->ntvfs = ntvfs; + ZERO_STRUCT(brlh->last_lock); + + return brlh; +} + +/* + see if two locking contexts are equal +*/ +static BOOL brl_tdb_same_context(struct lock_context *ctx1, struct lock_context *ctx2) +{ + return (cluster_id_equal(&ctx1->server, &ctx2->server) && + ctx1->smbpid == ctx2->smbpid && + ctx1->ctx == ctx2->ctx); +} + +/* + see if lck1 and lck2 overlap +*/ +static BOOL brl_tdb_overlap(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + /* this extra check is not redundent - it copes with locks + that go beyond the end of 64 bit file space */ + if (lck1->size != 0 && + lck1->start == lck2->start && + lck1->size == lck2->size) { + return True; + } + + if (lck1->start >= (lck2->start+lck2->size) || + lck2->start >= (lck1->start+lck1->size)) { + return False; + } + return True; +} + +/* + See if lock2 can be added when lock1 is in place. +*/ +static BOOL brl_tdb_conflict(struct lock_struct *lck1, + struct lock_struct *lck2) +{ + /* pending locks don't conflict with anything */ + if (lck1->lock_type >= PENDING_READ_LOCK || + lck2->lock_type >= PENDING_READ_LOCK) { + return False; + } + + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { + return False; + } + + if (brl_tdb_same_context(&lck1->context, &lck2->context) && + lck2->lock_type == READ_LOCK && lck1->ntvfs == lck2->ntvfs) { + return False; + } + + return brl_tdb_overlap(lck1, lck2); +} + + +/* + Check to see if this lock conflicts, but ignore our own locks on the + same fnum only. +*/ +static BOOL brl_tdb_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) +{ + /* pending locks don't conflict with anything */ + if (lck1->lock_type >= PENDING_READ_LOCK || + lck2->lock_type >= PENDING_READ_LOCK) { + return False; + } + + if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) + return False; + + /* + * note that incoming write calls conflict with existing READ + * locks even if the context is the same. JRA. See LOCKTEST7 + * in smbtorture. + */ + if (brl_tdb_same_context(&lck1->context, &lck2->context) && + lck1->ntvfs == lck2->ntvfs && + (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { + return False; + } + + return brl_tdb_overlap(lck1, lck2); +} + + +/* + amazingly enough, w2k3 "remembers" whether the last lock failure + is the same as this one and changes its error code. I wonder if any + app depends on this? +*/ +static NTSTATUS brl_tdb_lock_failed(struct brl_handle *brlh, struct lock_struct *lock) +{ + /* + * this function is only called for non pending lock! + */ + + /* + * if the notify_ptr is non NULL, + * it means that we're at the end of a pending lock + * and the real lock is requested after the timout went by + * In this case we need to remember the last_lock and always + * give FILE_LOCK_CONFLICT + */ + if (lock->notify_ptr) { + brlh->last_lock = *lock; + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + /* + * amazing the little things you learn with a test + * suite. Locks beyond this offset (as a 64 bit + * number!) always generate the conflict error code, + * unless the top bit is set + */ + if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) { + brlh->last_lock = *lock; + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + /* + * if the current lock matches the last failed lock on the file handle + * and starts at the same offset, then FILE_LOCK_CONFLICT should be returned + */ + if (cluster_id_equal(&lock->context.server, &brlh->last_lock.context.server) && + lock->context.ctx == brlh->last_lock.context.ctx && + lock->ntvfs == brlh->last_lock.ntvfs && + lock->start == brlh->last_lock.start) { + return NT_STATUS_FILE_LOCK_CONFLICT; + } + + brlh->last_lock = *lock; + return NT_STATUS_LOCK_NOT_GRANTED; +} + +/* + Lock a range of bytes. The lock_type can be a PENDING_*_LOCK, in + which case a real lock is first tried, and if that fails then a + pending lock is created. When the pending lock is triggered (by + someone else closing an overlapping lock range) a messaging + notification is sent, identified by the notify_ptr +*/ +static NTSTATUS brl_tdb_lock(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type, + void *notify_ptr) +{ + TDB_DATA kbuf, dbuf; + int count=0, i; + struct lock_struct lock, *locks=NULL; + NTSTATUS status; + + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* if this is a pending lock, then with the chainlock held we + try to get the real lock. If we succeed then we don't need + to make it pending. This prevents a possible race condition + where the pending lock gets created after the lock that is + preventing the real lock gets removed */ + if (lock_type >= PENDING_READ_LOCK) { + enum brl_type rw = (lock_type==PENDING_READ_LOCK? READ_LOCK : WRITE_LOCK); + + /* here we need to force that the last_lock isn't overwritten */ + lock = brlh->last_lock; + status = brl_tdb_lock(brl, brlh, smbpid, start, size, rw, NULL); + brlh->last_lock = lock; + + if (NT_STATUS_IS_OK(status)) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + + lock.context.smbpid = smbpid; + lock.context.server = brl->server; + lock.context.ctx = brl; + lock.ntvfs = brlh->ntvfs; + lock.context.ctx = brl; + lock.start = start; + lock.size = size; + lock.lock_type = lock_type; + lock.notify_ptr = notify_ptr; + + if (dbuf.dptr) { + /* there are existing locks - make sure they don't conflict */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + for (i=0; iw->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + + /* the caller needs to know if the real lock was granted. If + we have reached here then it must be a pending lock that + was granted, so tell them the lock failed */ + if (lock_type >= PENDING_READ_LOCK) { + return NT_STATUS_LOCK_NOT_GRANTED; + } + + return NT_STATUS_OK; + + fail: + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + we are removing a lock that might be holding up a pending lock. Scan for pending + locks that cover this range and if we find any then notify the server that it should + retry the lock +*/ +static void brl_tdb_notify_unlock(struct brl_context *brl, + struct lock_struct *locks, int count, + struct lock_struct *removed_lock) +{ + int i, last_notice; + + /* the last_notice logic is to prevent stampeding on a lock + range. It prevents us sending hundreds of notifies on the + same range of bytes. It doesn't prevent all possible + stampedes, but it does prevent the most common problem */ + last_notice = -1; + + for (i=0;i= PENDING_READ_LOCK && + brl_tdb_overlap(&locks[i], removed_lock)) { + if (last_notice != -1 && brl_tdb_overlap(&locks[i], &locks[last_notice])) { + continue; + } + if (locks[i].lock_type == PENDING_WRITE_LOCK) { + last_notice = i; + } + messaging_send_ptr(brl->messaging_ctx, locks[i].context.server, + MSG_BRL_RETRY, locks[i].notify_ptr); + } + } +} + + +/* + send notifications for all pending locks - the file is being closed by this + user +*/ +static void brl_tdb_notify_all(struct brl_context *brl, + struct lock_struct *locks, int count) +{ + int i; + for (i=0;ilock_type >= PENDING_READ_LOCK) { + brl_tdb_notify_unlock(brl, locks, count, &locks[i]); + } + } +} + + + +/* + Unlock a range of bytes. +*/ +static NTSTATUS brl_tdb_unlock(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size) +{ + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct *locks; + struct lock_context context; + NTSTATUS status; + + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_RANGE_NOT_LOCKED; + } + + context.smbpid = smbpid; + context.server = brl->server; + context.ctx = brl; + + /* there are existing locks - find a match */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; icontext, &context) && + lock->ntvfs == brlh->ntvfs && + lock->start == start && + lock->size == size && + lock->lock_type < PENDING_READ_LOCK) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + struct lock_struct removed_lock = *lock; + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + + /* send notifications for any relevant pending locks */ + brl_tdb_notify_unlock(brl, locks, count, &removed_lock); + + dbuf.dsize = count * sizeof(*locks); + + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + + /* we didn't find it */ + status = NT_STATUS_RANGE_NOT_LOCKED; + + fail: + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + remove a pending lock. This is called when the caller has either + given up trying to establish a lock or when they have succeeded in + getting it. In either case they no longer need to be notified. +*/ +static NTSTATUS brl_tdb_remove_pending(struct brl_context *brl, + struct brl_handle *brlh, + void *notify_ptr) +{ + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct *locks; + NTSTATUS status; + + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_RANGE_NOT_LOCKED; + } + + /* there are existing locks - find a match */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; ilock_type >= PENDING_READ_LOCK && + lock->notify_ptr == notify_ptr && + cluster_id_equal(&lock->context.server, &brl->server)) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + dbuf.dsize = count * sizeof(*locks); + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + } + + /* we didn't find it */ + status = NT_STATUS_RANGE_NOT_LOCKED; + + fail: + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return status; +} + + +/* + Test if we are allowed to perform IO on a region of an open file +*/ +static NTSTATUS brl_tdb_locktest(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type) +{ + TDB_DATA kbuf, dbuf; + int count, i; + struct lock_struct lock, *locks; + + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (dbuf.dptr == NULL) { + return NT_STATUS_OK; + } + + lock.context.smbpid = smbpid; + lock.context.server = brl->server; + lock.context.ctx = brl; + lock.ntvfs = brlh->ntvfs; + lock.start = start; + lock.size = size; + lock.lock_type = lock_type; + + /* there are existing locks - make sure they don't conflict */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; ikey.data; + kbuf.dsize = brlh->key.length; + + if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = tdb_fetch(brl->w->tdb, kbuf); + if (!dbuf.dptr) { + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; + } + + /* there are existing locks - remove any for this fnum */ + locks = (struct lock_struct *)dbuf.dptr; + count = dbuf.dsize / sizeof(*locks); + + for (i=0; icontext.ctx == brl && + cluster_id_equal(&lock->context.server, &brl->server) && + lock->ntvfs == brlh->ntvfs) { + /* found it - delete it */ + if (count > 1 && i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); + } + count--; + i--; + dcount++; + } + } + + status = NT_STATUS_OK; + + if (count == 0) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } else if (dcount != 0) { + /* tell all pending lock holders for this file that + they have a chance now. This is a bit indiscriminant, + but works OK */ + brl_tdb_notify_all(brl, locks, count); + + dbuf.dsize = count * sizeof(*locks); + + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + } + } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + + return status; +} + + +static const struct brlock_ops brlock_tdb_ops = { + .brl_init = brl_tdb_init, + .brl_create_handle = brl_tdb_create_handle, + .brl_lock = brl_tdb_lock, + .brl_unlock = brl_tdb_unlock, + .brl_remove_pending = brl_tdb_remove_pending, + .brl_locktest = brl_tdb_locktest, + .brl_close = brl_tdb_close +}; + + +void brl_tdb_init_ops(void) +{ + brl_set_ops(&brlock_tdb_ops); +} diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index c16cc09dfe..fd1b55a4f7 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -5,6 +5,7 @@ PRIVATE_PROTO_HEADER = proto.h OBJ_FILES = \ init.o \ brlock.o \ + brlock_tdb.o \ opendb.o \ notify.o PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share -- cgit From 72316674bf8a53fb704f14690d900a6c5799deb7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Jan 2007 04:08:33 +0000 Subject: r20894: the new brlock.c is needed (seems a svn rename + new file didn't make it in one commit) (This used to be commit 3315e877ab6504569e2869b52d989fc821982a3b) --- source4/ntvfs/common/brlock.c | 132 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 source4/ntvfs/common/brlock.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c new file mode 100644 index 0000000000..e483a6ba9b --- /dev/null +++ b/source4/ntvfs/common/brlock.c @@ -0,0 +1,132 @@ +/* + Unix SMB/CIFS implementation. + + generic byte range locking code + + Copyright (C) Andrew Tridgell 1992-2004 + Copyright (C) Jeremy Allison 1992-2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* This module implements a tdb based byte range locking service, + replacing the fcntl() based byte range locking previously + used. This allows us to provide the same semantics as NT */ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/tdb/include/tdb.h" +#include "messaging/messaging.h" +#include "db_wrap.h" +#include "lib/messaging/irpc.h" +#include "libcli/libcli.h" +#include "cluster/cluster.h" +#include "ntvfs/common/brlock.h" + +static const struct brlock_ops *ops; + +/* + set the brl backend ops +*/ +void brl_set_ops(const struct brlock_ops *new_ops) +{ + ops = new_ops; +} + +/* + Open up the brlock database. Close it down using talloc_free(). We + need the messaging_ctx to allow for pending lock notifications. +*/ +struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, + struct messaging_context *messaging_ctx) +{ + if (ops == NULL) { + if (lp_parm_bool(-1, "ctdb", "brlock", False)) { + brl_ctdb_init_ops(); + } else { + brl_tdb_init_ops(); + } + } + return ops->brl_init(mem_ctx, server, messaging_ctx); +} + +struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) +{ + return ops->brl_create_handle(mem_ctx, ntvfs, file_key); +} + +/* + Lock a range of bytes. The lock_type can be a PENDING_*_LOCK, in + which case a real lock is first tried, and if that fails then a + pending lock is created. When the pending lock is triggered (by + someone else closing an overlapping lock range) a messaging + notification is sent, identified by the notify_ptr +*/ +NTSTATUS brl_lock(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type, + void *notify_ptr) +{ + return ops->brl_lock(brl, brlh, smbpid, start, size, lock_type, notify_ptr); +} + + +/* + Unlock a range of bytes. +*/ +NTSTATUS brl_unlock(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size) +{ + return ops->brl_unlock(brl, brlh, smbpid, start, size); +} + +/* + remove a pending lock. This is called when the caller has either + given up trying to establish a lock or when they have succeeded in + getting it. In either case they no longer need to be notified. +*/ +NTSTATUS brl_remove_pending(struct brl_context *brl, + struct brl_handle *brlh, + void *notify_ptr) +{ + return ops->brl_remove_pending(brl, brlh, notify_ptr); +} + + +/* + Test if we are allowed to perform IO on a region of an open file +*/ +NTSTATUS brl_locktest(struct brl_context *brl, + struct brl_handle *brlh, + uint16_t smbpid, + uint64_t start, uint64_t size, + enum brl_type lock_type) +{ + return ops->brl_locktest(brl, brlh, smbpid, start, size, lock_type); +} + + +/* + Remove any locks associated with a open file. +*/ +NTSTATUS brl_close(struct brl_context *brl, + struct brl_handle *brlh) +{ + return ops->brl_close(brl, brlh); +} -- cgit From f40182cb123c91d4bc8fd3dbf9c3cca615f72c31 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jan 2007 11:58:03 +0000 Subject: r20897: fix compiler warnings metze (This used to be commit 5ac562e1e0e8de03c8bcd083a1822b31667c5e21) --- source4/ntvfs/common/brlock.c | 2 +- source4/ntvfs/common/notify.c | 1 + source4/ntvfs/common/ntvfs_common.h | 27 +++++++++++++++++++++++++++ source4/ntvfs/common/opendb.c | 1 + source4/ntvfs/posix/vfs_posix.h | 2 +- 5 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 source4/ntvfs/common/ntvfs_common.h (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index e483a6ba9b..8397c3bdd3 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -33,7 +33,7 @@ #include "lib/messaging/irpc.h" #include "libcli/libcli.h" #include "cluster/cluster.h" -#include "ntvfs/common/brlock.h" +#include "ntvfs/common/ntvfs_common.h" static const struct brlock_ops *ops; diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 8ba918d8af..0ee66a5a41 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -33,6 +33,7 @@ #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_notify.h" #include "lib/util/dlinklist.h" +#include "ntvfs/common/ntvfs_common.h" #include "ntvfs/sysdep/sys_notify.h" #include "cluster/cluster.h" diff --git a/source4/ntvfs/common/ntvfs_common.h b/source4/ntvfs/common/ntvfs_common.h new file mode 100644 index 0000000000..08f34c178f --- /dev/null +++ b/source4/ntvfs/common/ntvfs_common.h @@ -0,0 +1,27 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Stefan Metzmacher 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef _NTVFS_COMMON_H_ +#define _NTVFS_COMMON_H_ + +#include "ntvfs/common/brlock.h" +#include "ntvfs/common/proto.h" + +#endif /* _NTVFS_COMMON_H_ */ diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index df6bb7249b..e272ece3e5 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -46,6 +46,7 @@ #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" #include "ntvfs/ntvfs.h" +#include "ntvfs/common/ntvfs_common.h" #include "cluster/cluster.h" struct odb_context { diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 5bb9dcf811..e79eadd03a 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -26,7 +26,7 @@ #include "librpc/gen_ndr/xattr.h" #include "system/filesys.h" #include "ntvfs/ntvfs.h" -#include "ntvfs/common/proto.h" +#include "ntvfs/common/ntvfs_common.h" #include "dsdb/samdb/samdb.h" /* this is the private structure for the posix vfs backend. It is used -- cgit From 22bedb42ab964f3e3a771746c3218397b4bb318d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jan 2007 12:12:53 +0000 Subject: r20898: make it work to include ntvfs/ntvfs.h multiple times metze (This used to be commit 6814f38f000e9d44bdf25ca5bc1d69fd82522614) --- source4/ntvfs/ntvfs.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 69e638e1a1..e805c97bbd 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -19,6 +19,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#ifndef _NTVFS_H_ +#define _NTVFS_H_ + #include "libcli/raw/interfaces.h" #include "param/share.h" @@ -311,3 +314,5 @@ struct messaging_context; #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/notify.h" #include "ntvfs/ntvfs_proto.h" + +#endif /* _NTVFS_H_ */ -- cgit From c30b82c3ea088c2b76709e9413e3479c1e458314 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 19 Jan 2007 12:16:03 +0000 Subject: r20899: fix the build and compiler warnings metze (This used to be commit eec93720aced2b4cdad9f6f5a4f6e23587128357) --- source4/ntvfs/common/ntvfs_common.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/ntvfs_common.h b/source4/ntvfs/common/ntvfs_common.h index 08f34c178f..ab80bb08f0 100644 --- a/source4/ntvfs/common/ntvfs_common.h +++ b/source4/ntvfs/common/ntvfs_common.h @@ -21,6 +21,11 @@ #ifndef _NTVFS_COMMON_H_ #define _NTVFS_COMMON_H_ +#include "ntvfs/ntvfs.h" + +struct notify_event; +struct notify_entry; + #include "ntvfs/common/brlock.h" #include "ntvfs/common/proto.h" -- cgit From 2ad79af331ee77a7772a1e7840d3ce613ca051ae Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 20 Jan 2007 00:49:04 +0000 Subject: r20920: use cluster_tdb_tmp_open() in ntvfs backend code (This used to be commit c9080c54872f107d1e42e77261df50a5d55d294f) --- source4/ntvfs/common/brlock_tdb.c | 6 +----- source4/ntvfs/common/notify.c | 7 +------ source4/ntvfs/common/opendb.c | 7 +------ 3 files changed, 3 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 34c0b7e979..ee83008ce2 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -87,7 +87,6 @@ struct brl_handle { static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx) { - char *path; struct brl_context *brl; brl = talloc(mem_ctx, struct brl_context); @@ -95,10 +94,7 @@ static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id se return NULL; } - path = smbd_tmp_path(brl, "brlock.tdb"); - brl->w = tdb_wrap_open(brl, path, 0, - TDB_DEFAULT, O_RDWR|O_CREAT, 0600); - talloc_free(path); + brl->w = cluster_tdb_tmp_open(brl, "brlock.tdb", TDB_DEFAULT); if (brl->w == NULL) { talloc_free(brl); return NULL; diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 0ee66a5a41..2306cfe742 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -85,7 +85,6 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, struct event_context *ev, struct share_config *scfg) { - char *path; struct notify_context *notify; if (share_bool_option(scfg, NOTIFY_ENABLE, NOTIFY_ENABLE_DEFAULT) != True) { @@ -97,11 +96,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, return NULL; } - path = smbd_tmp_path(notify, "notify.tdb"); - notify->w = tdb_wrap_open(notify, path, 0, - TDB_SEQNUM, - O_RDWR|O_CREAT, 0600); - talloc_free(path); + notify->w = cluster_tdb_tmp_open(notify, "notify.tdb", TDB_SEQNUM); if (notify->w == NULL) { talloc_free(notify); return NULL; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index e272ece3e5..875f90760c 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -72,7 +72,6 @@ struct odb_lock { _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, struct ntvfs_context *ntvfs_ctx) { - char *path; struct odb_context *odb; odb = talloc(mem_ctx, struct odb_context); @@ -80,11 +79,7 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, return NULL; } - path = smbd_tmp_path(odb, "openfiles.tdb"); - odb->w = tdb_wrap_open(odb, path, 0, - TDB_DEFAULT, - O_RDWR|O_CREAT, 0600); - talloc_free(path); + odb->w = cluster_tdb_tmp_open(odb, "openfiles.tdb", TDB_DEFAULT); if (odb->w == NULL) { talloc_free(odb); return NULL; -- cgit From 87df5a631200a5725618fbe2779ade7066ad084c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 Jan 2007 11:46:27 +0000 Subject: r20947: fixed a bug in the unlock logic in the brlock tdb backend I'm very surprised this didn't show up earlier! (This used to be commit 5d9b1acf4f35d11c4730cbc9cadedb33c6ec08e8) --- source4/ntvfs/common/brlock_tdb.c | 72 ++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 28 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index ee83008ce2..6fe8cefd34 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -423,7 +423,7 @@ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, { TDB_DATA kbuf, dbuf; int count, i; - struct lock_struct *locks; + struct lock_struct *locks, *lock; struct lock_context context; NTSTATUS status; @@ -449,42 +449,58 @@ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, count = dbuf.dsize / sizeof(*locks); for (i=0; icontext, &context) && lock->ntvfs == brlh->ntvfs && lock->start == start && lock->size == size && - lock->lock_type < PENDING_READ_LOCK) { - /* found it - delete it */ - if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } else { - struct lock_struct removed_lock = *lock; - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - - /* send notifications for any relevant pending locks */ - brl_tdb_notify_unlock(brl, locks, count, &removed_lock); + lock->lock_type == WRITE_LOCK) { + break; + } + } + if (i < count) goto found; - dbuf.dsize = count * sizeof(*locks); + for (i=0; icontext, &context) && + lock->ntvfs == brlh->ntvfs && + lock->start == start && + lock->size == size && + lock->lock_type < PENDING_READ_LOCK) { + break; + } + } - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } +found: + if (i < count) { + /* found it - delete it */ + if (count == 1) { + if (tdb_delete(brl->w->tdb, kbuf) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } + } else { + struct lock_struct removed_lock = *lock; + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); } + count--; - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; + /* send notifications for any relevant pending locks */ + brl_tdb_notify_unlock(brl, locks, count, &removed_lock); + + dbuf.dsize = count * sizeof(*locks); + + if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto fail; + } } + + free(dbuf.dptr); + tdb_chainunlock(brl->w->tdb, kbuf); + return NT_STATUS_OK; } /* we didn't find it */ -- cgit From 67f494d72ae33da328504c5e86357c8b755c0053 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 23 Jan 2007 15:06:41 +0000 Subject: r20972: "private" -> "private_data" (This used to be commit 8cbcd3d1cbb0661b1767bb7ace0804cf9a573e34) --- source4/ntvfs/common/notify.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 2306cfe742..5954a7ebe2 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -50,7 +50,7 @@ struct notify_context { struct notify_list { struct notify_list *next, *prev; - void *private; + void *private_data; void (*callback)(void *, const struct notify_event *); void *sys_notify_handle; int depth; @@ -62,7 +62,7 @@ struct notify_list { #define NOTIFY_ENABLE_DEFAULT True static NTSTATUS notify_remove_all(struct notify_context *notify); -static void notify_handler(struct messaging_context *msg_ctx, void *private, +static void notify_handler(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); /* @@ -237,10 +237,10 @@ static NTSTATUS notify_save(struct notify_context *notify) /* handle incoming notify messages */ -static void notify_handler(struct messaging_context *msg_ctx, void *private, +static void notify_handler(struct messaging_context *msg_ctx, void *private_data, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { - struct notify_context *notify = talloc_get_type(private, struct notify_context); + struct notify_context *notify = talloc_get_type(private_data, struct notify_context); NTSTATUS status; struct notify_event ev; TALLOC_CTX *tmp_ctx = talloc_new(notify); @@ -254,8 +254,8 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private, } for (listel=notify->list;listel;listel=listel->next) { - if (listel->private == ev.private) { - listel->callback(listel->private, &ev); + if (listel->private_data == ev.private_data) { + listel->callback(listel->private_data, &ev); break; } } @@ -270,15 +270,15 @@ static void sys_notify_callback(struct sys_notify_context *ctx, void *ptr, struct notify_event *ev) { struct notify_list *listel = talloc_get_type(ptr, struct notify_list); - ev->private = listel; - listel->callback(listel->private, ev); + ev->private_data = listel; + listel->callback(listel->private_data, ev); } /* add an entry to the notify array */ static NTSTATUS notify_add_array(struct notify_context *notify, struct notify_entry *e, - void *private, int depth) + void *private_data, int depth) { int i; struct notify_depth *d; @@ -304,7 +304,7 @@ static NTSTATUS notify_add_array(struct notify_context *notify, struct notify_en d->entries = ee; d->entries[d->num_entries] = *e; - d->entries[d->num_entries].private = private; + d->entries[d->num_entries].private_data = private_data; d->entries[d->num_entries].server = notify->server; d->entries[d->num_entries].path_len = strlen(e->path); d->num_entries++; @@ -334,7 +334,7 @@ static NTSTATUS notify_add_array(struct notify_context *notify, struct notify_en */ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, void (*callback)(void *, const struct notify_event *), - void *private) + void *private_data) { struct notify_entry e = *e0; NTSTATUS status; @@ -375,7 +375,7 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, goto done; } - listel->private = private; + listel->private_data = private_data; listel->callback = callback; listel->depth = depth; DLIST_ADD(notify->list, listel); @@ -399,7 +399,7 @@ NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0, then we need to install it in the array used for the intra-samba notify handling */ if (e.filter != 0 || e.subdir_filter != 0) { - status = notify_add_array(notify, &e, private, depth); + status = notify_add_array(notify, &e, private_data, depth); } done: @@ -412,7 +412,7 @@ done: /* remove a notify watch. Called when the directory handle is closed */ -NTSTATUS notify_remove(struct notify_context *notify, void *private) +NTSTATUS notify_remove(struct notify_context *notify, void *private_data) { NTSTATUS status; struct notify_list *listel; @@ -425,7 +425,7 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) } for (listel=notify->list;listel;listel=listel->next) { - if (listel->private == private) { + if (listel->private_data == private_data) { DLIST_REMOVE(notify->list, listel); break; } @@ -456,7 +456,7 @@ NTSTATUS notify_remove(struct notify_context *notify, void *private) d = ¬ify->array->depth[depth]; for (i=0;inum_entries;i++) { - if (private == d->entries[i].private && + if (private_data == d->entries[i].private_data && cluster_id_equal(¬ify->server, &d->entries[i].server)) { break; } @@ -540,7 +540,7 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, ev.action = action; ev.path = path; - ev.private = e->private; + ev.private_data = e->private_data; tmp_ctx = talloc_new(notify); -- cgit From a80732cf0010404ef52f9ba05fd6e318461ae375 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 23 Jan 2007 20:57:50 +0000 Subject: r20983: Two no-mem error returns (This used to be commit 79a0cd3a1bbd3d4ef0c335f398fa8bb8e82c8624) --- source4/ntvfs/common/notify.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 5954a7ebe2..91fa8a1d78 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -213,6 +213,7 @@ static NTSTATUS notify_save(struct notify_context *notify) } tmp_ctx = talloc_new(notify); + NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); status = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, (ndr_push_flags_fn_t)ndr_push_notify_array); @@ -246,6 +247,10 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data TALLOC_CTX *tmp_ctx = talloc_new(notify); struct notify_list *listel; + if (tmp_ctx == NULL) { + return; + } + status = ndr_pull_struct_blob(data, tmp_ctx, &ev, (ndr_pull_flags_fn_t)ndr_pull_notify_event); if (!NT_STATUS_IS_OK(status)) { -- cgit From 1fbb49a3e7ed78582e283060b6624c57f30d13dd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 28 Jan 2007 17:03:10 +0000 Subject: r21041: Change some "private" to "private_data", and change one (void **) function parameter to (void *). void** in function parameters leads to type-punned warnings. Volker (This used to be commit 57979d89c53b4363e4b447205703579df6756653) --- source4/ntvfs/sysdep/inotify.c | 28 ++++++++++++++++------------ source4/ntvfs/sysdep/sys_notify.c | 8 +++++--- source4/ntvfs/sysdep/sys_notify.h | 11 ++++++----- 3 files changed, 27 insertions(+), 20 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index a5104a01d0..8bb0096dcc 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -72,7 +72,7 @@ struct watch_context { struct inotify_private *in; int wd; sys_notify_callback_t callback; - void *private; + void *private_data; uint32_t mask; /* the inotify mask */ uint32_t filter; /* the windows completion filter */ const char *path; @@ -175,7 +175,7 @@ static void inotify_dispatch(struct inotify_private *in, for (w=in->watches;w;w=next) { next = w->next; if (w->wd == e->wd && filter_match(w, e)) { - w->callback(in->ctx, w->private, &ne); + w->callback(in->ctx, w->private_data, &ne); } } @@ -194,7 +194,7 @@ static void inotify_dispatch(struct inotify_private *in, next = w->next; if (w->wd == e->wd && filter_match(w, e) && !(w->filter & FILE_NOTIFY_CHANGE_CREATION)) { - w->callback(in->ctx, w->private, &ne); + w->callback(in->ctx, w->private_data, &ne); } } } @@ -203,9 +203,10 @@ static void inotify_dispatch(struct inotify_private *in, called when the kernel has some events for us */ static void inotify_handler(struct event_context *ev, struct fd_event *fde, - uint16_t flags, void *private) + uint16_t flags, void *private_data) { - struct inotify_private *in = talloc_get_type(private, struct inotify_private); + struct inotify_private *in = talloc_get_type(private_data, + struct inotify_private); int bufsize = 0; struct inotify_event *e0, *e; uint32_t prev_cookie=0; @@ -268,7 +269,7 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) in->ctx = ctx; in->watches = NULL; - ctx->private = in; + ctx->private_data = in; talloc_set_destructor(in, inotify_destructor); /* add a event waiting for the inotify fd to be readable */ @@ -332,24 +333,27 @@ static int watch_destructor(struct watch_context *w) add a watch. The watch is removed when the caller calls talloc_free() on *handle */ -static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entry *e, - sys_notify_callback_t callback, void *private, - void **handle) +static NTSTATUS inotify_watch(struct sys_notify_context *ctx, + struct notify_entry *e, + sys_notify_callback_t callback, + void *private_data, + void *handle_p) { struct inotify_private *in; int wd; uint32_t mask; struct watch_context *w; uint32_t filter = e->filter; + void **handle = (void **)handle_p; /* maybe setup the inotify fd */ - if (ctx->private == NULL) { + if (ctx->private_data == NULL) { NTSTATUS status; status = inotify_setup(ctx); NT_STATUS_NOT_OK_RETURN(status); } - in = talloc_get_type(ctx->private, struct inotify_private); + in = talloc_get_type(ctx->private_data, struct inotify_private); mask = inotify_map(e); if (mask == 0) { @@ -378,7 +382,7 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct notify_entr w->in = in; w->wd = wd; w->callback = callback; - w->private = private; + w->private_data = private_data; w->mask = mask; w->filter = filter; w->path = talloc_strdup(w, e->path); diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 765b4a39a5..1c0467236a 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -95,13 +95,15 @@ _PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_confi bits to remove ones handled by this backend. Any remaining bits will be handled by the generic notify layer */ -_PUBLIC_ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, - sys_notify_callback_t callback, void *private, void **handle) +_PUBLIC_ NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, + struct notify_entry *e, + sys_notify_callback_t callback, + void *private_data, void *handle) { if (!ctx->notify_watch) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } - return ctx->notify_watch(ctx, e, callback, private, handle); + return ctx->notify_watch(ctx, e, callback, private_data, handle); } /* diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h index 6db10fe02c..a660ee7de5 100644 --- a/source4/ntvfs/sysdep/sys_notify.h +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -28,12 +28,13 @@ typedef void (*sys_notify_callback_t)(struct sys_notify_context *, typedef NTSTATUS (*notify_watch_t)(struct sys_notify_context *ctx, struct notify_entry *e, - sys_notify_callback_t callback, void *private, - void **handle); + sys_notify_callback_t callback, + void *private_data, + void *handle_p); struct sys_notify_context { struct event_context *ev; - void *private; /* for use of backend */ + void *private_data; /* for use of backend */ const char *name; notify_watch_t notify_watch; }; @@ -48,6 +49,6 @@ struct sys_notify_context *sys_notify_context_create(struct share_config *scfg, TALLOC_CTX *mem_ctx, struct event_context *ev); NTSTATUS sys_notify_watch(struct sys_notify_context *ctx, struct notify_entry *e, - sys_notify_callback_t callback, void *private, - void **handle); + sys_notify_callback_t callback, void *private_data, + void *handle); NTSTATUS sys_notify_init(void); -- cgit From 4c9efad4b8a06cf5c4a35649366accd21c3befd0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 28 Jan 2007 18:25:46 +0000 Subject: r21042: Fix typo (This used to be commit eb83537a3b4889353cdc9bb471315a77e1f87c90) --- source4/ntvfs/posix/pvfs_rename.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 8956a0174e..73513fdf00 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -72,7 +72,7 @@ NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *nam } /* this is a strange one. w2k3 gives an additional event for CHANGE_ATTRIBUTES - and CHANGE_CREATION on the new file when renming files, but not + and CHANGE_CREATION on the new file when renaming files, but not directories */ if ((name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) == 0) { notify_trigger(pvfs->notify_context, -- cgit From 4da372c9065876e742c380d360c62b784fb01df0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Feb 2007 10:59:35 +0000 Subject: r21104: Rename struct watch_context to struct inotify_watch_context (This used to be commit 3548b1f683a7f5ccc6563de7e099d3a5a86ed39c) --- source4/ntvfs/sysdep/inotify.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 8bb0096dcc..fbbf6e4010 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -64,11 +64,11 @@ static int inotify_rm_watch(int fd, int wd) struct inotify_private { struct sys_notify_context *ctx; int fd; - struct watch_context *watches; + struct inotify_watch_context *watches; }; -struct watch_context { - struct watch_context *next, *prev; +struct inotify_watch_context { + struct inotify_watch_context *next, *prev; struct inotify_private *in; int wd; sys_notify_callback_t callback; @@ -93,7 +93,8 @@ static int inotify_destructor(struct inotify_private *in) see if a particular event from inotify really does match a requested notify event in SMB */ -static BOOL filter_match(struct watch_context *w, struct inotify_event *e) +static BOOL filter_match(struct inotify_watch_context *w, + struct inotify_event *e) { if ((e->mask & w->mask) == 0) { /* this happens because inotify_add_watch() coalesces watches on the same @@ -139,7 +140,7 @@ static void inotify_dispatch(struct inotify_private *in, uint32_t prev_cookie, struct inotify_event *e2) { - struct watch_context *w, *next; + struct inotify_watch_context *w, *next; struct notify_event ne; /* ignore extraneous events, such as unmount and IN_IGNORED events */ @@ -312,7 +313,7 @@ static uint32_t inotify_map(struct notify_entry *e) /* destroy a watch */ -static int watch_destructor(struct watch_context *w) +static int watch_destructor(struct inotify_watch_context *w) { struct inotify_private *in = w->in; int wd = w->wd; @@ -342,7 +343,7 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, struct inotify_private *in; int wd; uint32_t mask; - struct watch_context *w; + struct inotify_watch_context *w; uint32_t filter = e->filter; void **handle = (void **)handle_p; @@ -372,7 +373,7 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, return map_nt_error_from_unix(errno); } - w = talloc(in, struct watch_context); + w = talloc(in, struct inotify_watch_context); if (w == NULL) { inotify_rm_watch(in->fd, wd); e->filter = filter; -- cgit From 667cff3699a37510a69f682407bdda6316ba4402 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Feb 2007 07:06:28 +0000 Subject: r21214: fixed a valgrind error that can be caused by a semi-async call inside a nested ntvfs call. The req structure can go away while processing a ntvfs request (This used to be commit f62b3c505f71f37a86a76d152d643926e19eb148) --- source4/ntvfs/unixuid/vfs_unixuid.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 17fdb42de0..b430d3048b 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -156,7 +156,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, token = req->session_info->security_token; - *sec = save_unix_security(req); + *sec = save_unix_security(ntvfs); if (*sec == NULL) { return NT_STATUS_NO_MEMORY; } @@ -166,6 +166,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, } else { status = nt_token_to_unix_security(ntvfs, req, token, &newsec); if (!NT_STATUS_IS_OK(status)) { + talloc_free(*sec); return status; } if (private->last_sec_ctx) { @@ -178,6 +179,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, status = set_unix_security(newsec); if (!NT_STATUS_IS_OK(status)) { + talloc_free(*sec); return status; } @@ -194,6 +196,7 @@ static NTSTATUS unixuid_setup_security(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); \ status = ntvfs_next_##op args; \ status2 = set_unix_security(sec); \ + talloc_free(sec); \ if (!NT_STATUS_IS_OK(status2)) smb_panic("Unable to reset security context"); \ } while (0) -- cgit From 1cd412aa19b1c0185097bb91a68d9f7146d3c290 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Feb 2007 03:01:47 +0000 Subject: r21234: fixed a subtle bug with talloc reference counting and async ntvfs requests. (This used to be commit 6a2ba01f155266add71319c1dbc3442eb0c2c751) --- source4/ntvfs/posix/pvfs_wait.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 6e8324183f..3d0bb465e3 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -76,9 +76,9 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin structure is not destroyed when the async request reply is sent, which would cause problems with the other ntvfs modules above us */ - talloc_increase_ref_count(req); + talloc_reference(msg, req); ntvfs_async_setup(pwait->req, pwait); - talloc_free(req); + talloc_unlink(msg, req); } -- cgit From bedf53f9e0f7388c6ed8c1533eb89e55a88e65bd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 3 Mar 2007 00:27:46 +0000 Subject: r21669: Fix --enable-dso build (This used to be commit 7cf9d07c88b0c81777bb9363d445ac657982a366) --- source4/ntvfs/common/config.mk | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index fd1b55a4f7..99a46323e2 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -9,5 +9,6 @@ OBJ_FILES = \ opendb.o \ notify.o PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share +PRIVATE_DEPENDENCIES = brlock_ctdb # End LIBRARY ntvfs_common ################################################ -- cgit From 676a04a056d495b9b81ba7c6e6b1cbb9c3d64ac5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Mar 2007 01:47:04 +0000 Subject: r21807: modularise the opendb code, so different backends can be implemented. This will allow for a ctdb opendb backend. (This used to be commit 6b91ca0968209ad17489341c78d9610607cc8320) --- source4/ntvfs/common/config.mk | 1 + source4/ntvfs/common/ntvfs_common.h | 1 + source4/ntvfs/common/opendb.c | 478 ++------------------------- source4/ntvfs/common/opendb.h | 49 +++ source4/ntvfs/common/opendb_tdb.c | 622 ++++++++++++++++++++++++++++++++++++ 5 files changed, 693 insertions(+), 458 deletions(-) create mode 100644 source4/ntvfs/common/opendb.h create mode 100644 source4/ntvfs/common/opendb_tdb.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 99a46323e2..665e8e255b 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,6 +7,7 @@ OBJ_FILES = \ brlock.o \ brlock_tdb.o \ opendb.o \ + opendb_tdb.o \ notify.o PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share PRIVATE_DEPENDENCIES = brlock_ctdb diff --git a/source4/ntvfs/common/ntvfs_common.h b/source4/ntvfs/common/ntvfs_common.h index ab80bb08f0..4cc7ebe752 100644 --- a/source4/ntvfs/common/ntvfs_common.h +++ b/source4/ntvfs/common/ntvfs_common.h @@ -27,6 +27,7 @@ struct notify_event; struct notify_entry; #include "ntvfs/common/brlock.h" +#include "ntvfs/common/opendb.h" #include "ntvfs/common/proto.h" #endif /* _NTVFS_COMMON_H_ */ diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 875f90760c..c17b819c04 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -39,30 +39,19 @@ */ #include "includes.h" -#include "system/filesys.h" -#include "lib/tdb/include/tdb.h" -#include "messaging/messaging.h" -#include "db_wrap.h" -#include "lib/messaging/irpc.h" -#include "librpc/gen_ndr/ndr_opendb.h" #include "ntvfs/ntvfs.h" #include "ntvfs/common/ntvfs_common.h" #include "cluster/cluster.h" -struct odb_context { - struct tdb_wrap *w; - struct ntvfs_context *ntvfs_ctx; - BOOL oplocks; -}; +static const struct opendb_ops *ops; /* - an odb lock handle. You must obtain one of these using odb_lock() before doing - any other operations. + set the odb backend ops */ -struct odb_lock { - struct odb_context *odb; - TDB_DATA key; -}; +void odb_set_ops(const struct opendb_ops *new_ops) +{ + ops = new_ops; +} /* Open up the openfiles.tdb database. Close it down using @@ -72,34 +61,10 @@ struct odb_lock { _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, struct ntvfs_context *ntvfs_ctx) { - struct odb_context *odb; - - odb = talloc(mem_ctx, struct odb_context); - if (odb == NULL) { - return NULL; - } - - odb->w = cluster_tdb_tmp_open(odb, "openfiles.tdb", TDB_DEFAULT); - if (odb->w == NULL) { - talloc_free(odb); - return NULL; + if (ops == NULL) { + odb_tdb_init_ops(); } - - odb->ntvfs_ctx = ntvfs_ctx; - - /* leave oplocks disabled by default until the code is working */ - odb->oplocks = lp_parm_bool(-1, "opendb", "oplocks", False); - - return odb; -} - -/* - destroy a lock on the database -*/ -static int odb_lock_destructor(struct odb_lock *lck) -{ - tdb_chainunlock(lck->odb->w->tdb, lck->key); - return 0; + return ops->odb_init(mem_ctx, ntvfs_ctx); } /* @@ -109,153 +74,9 @@ static int odb_lock_destructor(struct odb_lock *lck) _PUBLIC_ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, struct odb_context *odb, DATA_BLOB *file_key) { - struct odb_lock *lck; - - lck = talloc(mem_ctx, struct odb_lock); - if (lck == NULL) { - return NULL; - } - - lck->odb = talloc_reference(lck, odb); - lck->key.dptr = talloc_memdup(lck, file_key->data, file_key->length); - lck->key.dsize = file_key->length; - if (lck->key.dptr == NULL) { - talloc_free(lck); - return NULL; - } - - if (tdb_chainlock(odb->w->tdb, lck->key) != 0) { - talloc_free(lck); - return NULL; - } - - talloc_set_destructor(lck, odb_lock_destructor); - - return lck; + return ops->odb_lock(mem_ctx, odb, file_key); } -/* - determine if two odb_entry structures conflict - - return NT_STATUS_OK on no conflict -*/ -static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2) -{ - /* if either open involves no read.write or delete access then - it can't conflict */ - if (!(e1->access_mask & (SEC_FILE_WRITE_DATA | - SEC_FILE_APPEND_DATA | - SEC_FILE_READ_DATA | - SEC_FILE_EXECUTE | - SEC_STD_DELETE))) { - return NT_STATUS_OK; - } - if (!(e2->access_mask & (SEC_FILE_WRITE_DATA | - SEC_FILE_APPEND_DATA | - SEC_FILE_READ_DATA | - SEC_FILE_EXECUTE | - SEC_STD_DELETE))) { - return NT_STATUS_OK; - } - - /* data IO access masks. This is skipped if the two open handles - are on different streams (as in that case the masks don't - interact) */ - if (e1->stream_id != e2->stream_id) { - return NT_STATUS_OK; - } - -#define CHECK_MASK(am, right, sa, share) \ - if (((am) & (right)) && !((sa) & (share))) return NT_STATUS_SHARING_VIOLATION - - CHECK_MASK(e1->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, - e2->share_access, NTCREATEX_SHARE_ACCESS_WRITE); - CHECK_MASK(e2->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, - e1->share_access, NTCREATEX_SHARE_ACCESS_WRITE); - - CHECK_MASK(e1->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, - e2->share_access, NTCREATEX_SHARE_ACCESS_READ); - CHECK_MASK(e2->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, - e1->share_access, NTCREATEX_SHARE_ACCESS_READ); - - CHECK_MASK(e1->access_mask, SEC_STD_DELETE, - e2->share_access, NTCREATEX_SHARE_ACCESS_DELETE); - CHECK_MASK(e2->access_mask, SEC_STD_DELETE, - e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE); - - return NT_STATUS_OK; -} - -/* - pull a record, translating from the db format to the opendb_file structure defined - in opendb.idl -*/ -static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) -{ - struct odb_context *odb = lck->odb; - TDB_DATA dbuf; - DATA_BLOB blob; - NTSTATUS status; - - dbuf = tdb_fetch(odb->w->tdb, lck->key); - if (dbuf.dptr == NULL) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - blob.data = dbuf.dptr; - blob.length = dbuf.dsize; - - status = ndr_pull_struct_blob(&blob, lck, file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); - - free(dbuf.dptr); - - return status; -} - -/* - push a record, translating from the opendb_file structure defined in opendb.idl -*/ -static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) -{ - struct odb_context *odb = lck->odb; - TDB_DATA dbuf; - DATA_BLOB blob; - NTSTATUS status; - int ret; - - if (file->num_entries == 0) { - ret = tdb_delete(odb->w->tdb, lck->key); - if (ret != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - return NT_STATUS_OK; - } - - status = ndr_push_struct_blob(&blob, lck, file, (ndr_push_flags_fn_t)ndr_push_opendb_file); - NT_STATUS_NOT_OK_RETURN(status); - - dbuf.dptr = blob.data; - dbuf.dsize = blob.length; - - ret = tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE); - data_blob_free(&blob); - if (ret != 0) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - return NT_STATUS_OK; -} - -/* - send an oplock break to a client -*/ -static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_entry *e) -{ - /* tell the server handling this open file about the need to send the client - a break */ - return messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, e->server, - MSG_NTVFS_OPLOCK_BREAK, e->file_handle); -} /* register an open file in the open files database. This implements the share_access @@ -270,97 +91,9 @@ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, const char *path, uint32_t oplock_level, uint32_t *oplock_granted) { - struct odb_context *odb = lck->odb; - struct opendb_entry e; - int i; - struct opendb_file file; - NTSTATUS status; - - if (odb->oplocks == False) { - oplock_level = OPLOCK_NONE; - } - - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - /* initialise a blank structure */ - ZERO_STRUCT(file); - file.path = path; - } else { - NT_STATUS_NOT_OK_RETURN(status); - } - - /* see if it conflicts */ - e.server = odb->ntvfs_ctx->server_id; - e.file_handle = file_handle; - e.stream_id = stream_id; - e.share_access = share_access; - e.access_mask = access_mask; - e.delete_on_close = delete_on_close; - e.oplock_level = OPLOCK_NONE; - - /* see if anyone has an oplock, which we need to break */ - for (i=0;iodb_open_file(lck, file_handle, stream_id, share_access, + access_mask, delete_on_close, path, oplock_level, + oplock_granted); } @@ -369,23 +102,7 @@ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, */ _PUBLIC_ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) { - struct odb_context *odb = lck->odb; - struct opendb_file file; - NTSTATUS status; - - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); - - file.pending = talloc_realloc(lck, file.pending, struct opendb_pending, - file.num_pending+1); - NT_STATUS_HAVE_NO_MEMORY(file.pending); - - file.pending[file.num_pending].server = odb->ntvfs_ctx->server_id; - file.pending[file.num_pending].notify_ptr = private; - - file.num_pending++; - - return odb_push_record(lck, &file); + return ops->odb_open_file_pending(lck, private); } @@ -394,45 +111,7 @@ _PUBLIC_ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) */ _PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) { - struct odb_context *odb = lck->odb; - struct opendb_file file; - int i; - NTSTATUS status; - - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); - - /* find the entry, and delete it */ - for (i=0;intvfs_ctx->server_id, &file.entries[i].server)) { - if (file.entries[i].delete_on_close) { - file.delete_on_close = True; - } - if (i < file.num_entries-1) { - memmove(file.entries+i, file.entries+i+1, - (file.num_entries - (i+1)) * - sizeof(struct opendb_entry)); - } - break; - } - } - - if (i == file.num_entries) { - return NT_STATUS_UNSUCCESSFUL; - } - - /* send any pending notifications, removing them once sent */ - for (i=0;intvfs_ctx->msg_ctx, file.pending[i].server, - MSG_PVFS_RETRY_OPEN, - file.pending[i].notify_ptr); - } - file.num_pending = 0; - - file.num_entries--; - - return odb_push_record(lck, &file); + return ops->odb_close_file(lck, file_handle); } @@ -441,34 +120,7 @@ _PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) */ _PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) { - struct odb_context *odb = lck->odb; - int i; - NTSTATUS status; - struct opendb_file file; - - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); - - /* find the entry, and delete it */ - for (i=0;intvfs_ctx->server_id, &file.pending[i].server)) { - if (i < file.num_pending-1) { - memmove(file.pending+i, file.pending+i+1, - (file.num_pending - (i+1)) * - sizeof(struct opendb_pending)); - } - break; - } - } - - if (i == file.num_pending) { - return NT_STATUS_UNSUCCESSFUL; - } - - file.num_pending--; - - return odb_push_record(lck, &file); + return ops->odb_remove_pending(lck, private); } @@ -477,18 +129,7 @@ _PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) */ _PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) { - struct opendb_file file; - NTSTATUS status; - - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { - /* not having the record at all is OK */ - return NT_STATUS_OK; - } - NT_STATUS_NOT_OK_RETURN(status); - - file.path = path; - return odb_push_record(lck, &file); + return ops->odb_rename(lck, path); } /* @@ -496,15 +137,7 @@ _PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) */ _PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) { - NTSTATUS status; - struct opendb_file file; - - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); - - file.delete_on_close = del_on_close; - - return odb_push_record(lck, &file); + return ops->odb_set_delete_on_close(lck, del_on_close); } /* @@ -515,39 +148,7 @@ _PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, DATA_BLOB *key, BOOL *del_on_close, int *open_count, char **path) { - NTSTATUS status; - struct opendb_file file; - struct odb_lock *lck; - - lck = odb_lock(odb, odb, key); - NT_STATUS_HAVE_NO_MEMORY(lck); - - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { - talloc_free(lck); - (*del_on_close) = False; - return NT_STATUS_OK; - } - if (!NT_STATUS_IS_OK(status)) { - talloc_free(lck); - return status; - } - - (*del_on_close) = file.delete_on_close; - if (open_count != NULL) { - (*open_count) = file.num_entries; - } - if (path != NULL) { - *path = talloc_strdup(odb, file.path); - NT_STATUS_HAVE_NO_MEMORY(*path); - if (file.num_entries == 1 && file.entries[0].delete_on_close) { - (*del_on_close) = True; - } - } - - talloc_free(lck); - - return NT_STATUS_OK; + return ops->odb_get_delete_on_close(odb, key, del_on_close, open_count, path); } @@ -559,44 +160,5 @@ _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, uint32_t share_access, uint32_t create_options, uint32_t access_mask) { - struct odb_context *odb = lck->odb; - NTSTATUS status; - struct opendb_file file; - struct opendb_entry e; - int i; - - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - return NT_STATUS_OK; - } - NT_STATUS_NOT_OK_RETURN(status); - - if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - file.num_entries != 0) { - return NT_STATUS_SHARING_VIOLATION; - } - - if (file.delete_on_close) { - return NT_STATUS_DELETE_PENDING; - } - - e.server = odb->ntvfs_ctx->server_id; - e.file_handle = NULL; - e.stream_id = 0; - e.share_access = share_access; - e.access_mask = access_mask; - - for (i=0;iodb_can_open(lck, share_access, create_options, access_mask); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h new file mode 100644 index 0000000000..9d6c18c471 --- /dev/null +++ b/source4/ntvfs/common/opendb.h @@ -0,0 +1,49 @@ +/* + Unix SMB/CIFS implementation. + + open database code - common include + + Copyright (C) Andrew Tridgell 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +struct opendb_ops { + struct odb_context *(*odb_init)(TALLOC_CTX *mem_ctx, + struct ntvfs_context *ntvfs_ctx); + struct odb_lock *(*odb_lock)(TALLOC_CTX *mem_ctx, + struct odb_context *odb, DATA_BLOB *file_key); + NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle, + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, BOOL delete_on_close, + const char *path, + uint32_t oplock_level, uint32_t *oplock_granted); + NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); + NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle); + NTSTATUS (*odb_remove_pending)(struct odb_lock *lck, void *private); + NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path); + NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, BOOL del_on_close); + NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, + DATA_BLOB *key, BOOL *del_on_close, + int *open_count, char **path); + NTSTATUS (*odb_can_open)(struct odb_lock *lck, + uint32_t share_access, uint32_t create_options, + uint32_t access_mask); +}; + + +void odb_set_ops(const struct opendb_ops *new_ops); +void odb_tdb_init_ops(void); + diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c new file mode 100644 index 0000000000..c181b033e7 --- /dev/null +++ b/source4/ntvfs/common/opendb_tdb.c @@ -0,0 +1,622 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Andrew Tridgell 2004 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + this is the open files database, tdb backend. It implements shared + storage of what files are open between server instances, and + implements the rules of shared access to files. + + The caller needs to provide a file_key, which specifies what file + they are talking about. This needs to be a unique key across all + filesystems, and is usually implemented in terms of a device/inode + pair. + + Before any operations can be performed the caller needs to establish + a lock on the record associated with file_key. That is done by + calling odb_lock(). The caller releases this lock by calling + talloc_free() on the returned handle. + + All other operations on a record are done by passing the odb_lock() + handle back to this module. The handle contains internal + information about what file_key is being operated on. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/tdb/include/tdb.h" +#include "messaging/messaging.h" +#include "db_wrap.h" +#include "lib/messaging/irpc.h" +#include "librpc/gen_ndr/ndr_opendb.h" +#include "ntvfs/ntvfs.h" +#include "ntvfs/common/ntvfs_common.h" +#include "cluster/cluster.h" + +struct odb_context { + struct tdb_wrap *w; + struct ntvfs_context *ntvfs_ctx; + BOOL oplocks; +}; + +/* + an odb lock handle. You must obtain one of these using odb_lock() before doing + any other operations. +*/ +struct odb_lock { + struct odb_context *odb; + TDB_DATA key; +}; + +/* + Open up the openfiles.tdb database. Close it down using + talloc_free(). We need the messaging_ctx to allow for pending open + notifications. +*/ +static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, + struct ntvfs_context *ntvfs_ctx) +{ + struct odb_context *odb; + + odb = talloc(mem_ctx, struct odb_context); + if (odb == NULL) { + return NULL; + } + + odb->w = cluster_tdb_tmp_open(odb, "openfiles.tdb", TDB_DEFAULT); + if (odb->w == NULL) { + talloc_free(odb); + return NULL; + } + + odb->ntvfs_ctx = ntvfs_ctx; + + /* leave oplocks disabled by default until the code is working */ + odb->oplocks = lp_parm_bool(-1, "opendb", "oplocks", False); + + return odb; +} + +/* + destroy a lock on the database +*/ +static int odb_lock_destructor(struct odb_lock *lck) +{ + tdb_chainunlock(lck->odb->w->tdb, lck->key); + return 0; +} + +/* + get a lock on a entry in the odb. This call returns a lock handle, + which the caller should unlock using talloc_free(). +*/ +static struct odb_lock *odb_tdb_lock(TALLOC_CTX *mem_ctx, + struct odb_context *odb, DATA_BLOB *file_key) +{ + struct odb_lock *lck; + + lck = talloc(mem_ctx, struct odb_lock); + if (lck == NULL) { + return NULL; + } + + lck->odb = talloc_reference(lck, odb); + lck->key.dptr = talloc_memdup(lck, file_key->data, file_key->length); + lck->key.dsize = file_key->length; + if (lck->key.dptr == NULL) { + talloc_free(lck); + return NULL; + } + + if (tdb_chainlock(odb->w->tdb, lck->key) != 0) { + talloc_free(lck); + return NULL; + } + + talloc_set_destructor(lck, odb_lock_destructor); + + return lck; +} + +/* + determine if two odb_entry structures conflict + + return NT_STATUS_OK on no conflict +*/ +static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2) +{ + /* if either open involves no read.write or delete access then + it can't conflict */ + if (!(e1->access_mask & (SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_READ_DATA | + SEC_FILE_EXECUTE | + SEC_STD_DELETE))) { + return NT_STATUS_OK; + } + if (!(e2->access_mask & (SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_READ_DATA | + SEC_FILE_EXECUTE | + SEC_STD_DELETE))) { + return NT_STATUS_OK; + } + + /* data IO access masks. This is skipped if the two open handles + are on different streams (as in that case the masks don't + interact) */ + if (e1->stream_id != e2->stream_id) { + return NT_STATUS_OK; + } + +#define CHECK_MASK(am, right, sa, share) \ + if (((am) & (right)) && !((sa) & (share))) return NT_STATUS_SHARING_VIOLATION + + CHECK_MASK(e1->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, + e2->share_access, NTCREATEX_SHARE_ACCESS_WRITE); + CHECK_MASK(e2->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, + e1->share_access, NTCREATEX_SHARE_ACCESS_WRITE); + + CHECK_MASK(e1->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, + e2->share_access, NTCREATEX_SHARE_ACCESS_READ); + CHECK_MASK(e2->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, + e1->share_access, NTCREATEX_SHARE_ACCESS_READ); + + CHECK_MASK(e1->access_mask, SEC_STD_DELETE, + e2->share_access, NTCREATEX_SHARE_ACCESS_DELETE); + CHECK_MASK(e2->access_mask, SEC_STD_DELETE, + e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE); + + return NT_STATUS_OK; +} + +/* + pull a record, translating from the db format to the opendb_file structure defined + in opendb.idl +*/ +static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) +{ + struct odb_context *odb = lck->odb; + TDB_DATA dbuf; + DATA_BLOB blob; + NTSTATUS status; + + dbuf = tdb_fetch(odb->w->tdb, lck->key); + if (dbuf.dptr == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + blob.data = dbuf.dptr; + blob.length = dbuf.dsize; + + status = ndr_pull_struct_blob(&blob, lck, file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); + + free(dbuf.dptr); + + return status; +} + +/* + push a record, translating from the opendb_file structure defined in opendb.idl +*/ +static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) +{ + struct odb_context *odb = lck->odb; + TDB_DATA dbuf; + DATA_BLOB blob; + NTSTATUS status; + int ret; + + if (file->num_entries == 0) { + ret = tdb_delete(odb->w->tdb, lck->key); + if (ret != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + return NT_STATUS_OK; + } + + status = ndr_push_struct_blob(&blob, lck, file, (ndr_push_flags_fn_t)ndr_push_opendb_file); + NT_STATUS_NOT_OK_RETURN(status); + + dbuf.dptr = blob.data; + dbuf.dsize = blob.length; + + ret = tdb_store(odb->w->tdb, lck->key, dbuf, TDB_REPLACE); + data_blob_free(&blob); + if (ret != 0) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + return NT_STATUS_OK; +} + +/* + send an oplock break to a client +*/ +static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_entry *e) +{ + /* tell the server handling this open file about the need to send the client + a break */ + return messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, e->server, + MSG_NTVFS_OPLOCK_BREAK, e->file_handle); +} + +/* + register an open file in the open files database. This implements the share_access + rules + + Note that the path is only used by the delete on close logic, not + for comparing with other filenames +*/ +static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, BOOL delete_on_close, + const char *path, + uint32_t oplock_level, uint32_t *oplock_granted) +{ + struct odb_context *odb = lck->odb; + struct opendb_entry e; + int i; + struct opendb_file file; + NTSTATUS status; + + if (odb->oplocks == False) { + oplock_level = OPLOCK_NONE; + } + + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + /* initialise a blank structure */ + ZERO_STRUCT(file); + file.path = path; + } else { + NT_STATUS_NOT_OK_RETURN(status); + } + + /* see if it conflicts */ + e.server = odb->ntvfs_ctx->server_id; + e.file_handle = file_handle; + e.stream_id = stream_id; + e.share_access = share_access; + e.access_mask = access_mask; + e.delete_on_close = delete_on_close; + e.oplock_level = OPLOCK_NONE; + + /* see if anyone has an oplock, which we need to break */ + for (i=0;iodb; + struct opendb_file file; + NTSTATUS status; + + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); + + file.pending = talloc_realloc(lck, file.pending, struct opendb_pending, + file.num_pending+1); + NT_STATUS_HAVE_NO_MEMORY(file.pending); + + file.pending[file.num_pending].server = odb->ntvfs_ctx->server_id; + file.pending[file.num_pending].notify_ptr = private; + + file.num_pending++; + + return odb_push_record(lck, &file); +} + + +/* + remove a opendb entry +*/ +static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle) +{ + struct odb_context *odb = lck->odb; + struct opendb_file file; + int i; + NTSTATUS status; + + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); + + /* find the entry, and delete it */ + for (i=0;intvfs_ctx->server_id, &file.entries[i].server)) { + if (file.entries[i].delete_on_close) { + file.delete_on_close = True; + } + if (i < file.num_entries-1) { + memmove(file.entries+i, file.entries+i+1, + (file.num_entries - (i+1)) * + sizeof(struct opendb_entry)); + } + break; + } + } + + if (i == file.num_entries) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* send any pending notifications, removing them once sent */ + for (i=0;intvfs_ctx->msg_ctx, file.pending[i].server, + MSG_PVFS_RETRY_OPEN, + file.pending[i].notify_ptr); + } + file.num_pending = 0; + + file.num_entries--; + + return odb_push_record(lck, &file); +} + + +/* + remove a pending opendb entry +*/ +static NTSTATUS odb_tdb_remove_pending(struct odb_lock *lck, void *private) +{ + struct odb_context *odb = lck->odb; + int i; + NTSTATUS status; + struct opendb_file file; + + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); + + /* find the entry, and delete it */ + for (i=0;intvfs_ctx->server_id, &file.pending[i].server)) { + if (i < file.num_pending-1) { + memmove(file.pending+i, file.pending+i+1, + (file.num_pending - (i+1)) * + sizeof(struct opendb_pending)); + } + break; + } + } + + if (i == file.num_pending) { + return NT_STATUS_UNSUCCESSFUL; + } + + file.num_pending--; + + return odb_push_record(lck, &file); +} + + +/* + rename the path in a open file +*/ +static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path) +{ + struct opendb_file file; + NTSTATUS status; + + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { + /* not having the record at all is OK */ + return NT_STATUS_OK; + } + NT_STATUS_NOT_OK_RETURN(status); + + file.path = path; + return odb_push_record(lck, &file); +} + +/* + update delete on close flag on an open file +*/ +static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) +{ + NTSTATUS status; + struct opendb_file file; + + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); + + file.delete_on_close = del_on_close; + + return odb_push_record(lck, &file); +} + +/* + return the current value of the delete_on_close bit, and how many + people still have the file open +*/ +static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, + DATA_BLOB *key, BOOL *del_on_close, + int *open_count, char **path) +{ + NTSTATUS status; + struct opendb_file file; + struct odb_lock *lck; + + lck = odb_lock(odb, odb, key); + NT_STATUS_HAVE_NO_MEMORY(lck); + + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { + talloc_free(lck); + (*del_on_close) = False; + return NT_STATUS_OK; + } + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } + + (*del_on_close) = file.delete_on_close; + if (open_count != NULL) { + (*open_count) = file.num_entries; + } + if (path != NULL) { + *path = talloc_strdup(odb, file.path); + NT_STATUS_HAVE_NO_MEMORY(*path); + if (file.num_entries == 1 && file.entries[0].delete_on_close) { + (*del_on_close) = True; + } + } + + talloc_free(lck); + + return NT_STATUS_OK; +} + + +/* + determine if a file can be opened with the given share_access, + create_options and access_mask +*/ +static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, + uint32_t share_access, uint32_t create_options, + uint32_t access_mask) +{ + struct odb_context *odb = lck->odb; + NTSTATUS status; + struct opendb_file file; + struct opendb_entry e; + int i; + + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + return NT_STATUS_OK; + } + NT_STATUS_NOT_OK_RETURN(status); + + if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + file.num_entries != 0) { + return NT_STATUS_SHARING_VIOLATION; + } + + if (file.delete_on_close) { + return NT_STATUS_DELETE_PENDING; + } + + e.server = odb->ntvfs_ctx->server_id; + e.file_handle = NULL; + e.stream_id = 0; + e.share_access = share_access; + e.access_mask = access_mask; + + for (i=0;i Date: Mon, 2 Apr 2007 04:47:19 +0000 Subject: r22021: use the pid specified in the individual locks, not the request pid, in locking requests. This fixes a bug noticed by Ronnie Sahlberg (thanks!) (This used to be commit b4ac085816cbec93c9fd4543a7ce48c5f3f9dca6) --- source4/ntvfs/posix/pvfs_lock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 2e0f77616b..4527cd3ed2 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -125,7 +125,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas */ status = brl_lock(pvfs->brl_context, f->brl_handle, - req->smbpid, + locks[pending->pending_lock].pid, locks[pending->pending_lock].offset, locks[pending->pending_lock].count, rw, pending); @@ -174,7 +174,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas status = brl_lock(pvfs->brl_context, f->brl_handle, - req->smbpid, + locks[i].pid, locks[i].offset, locks[i].count, rw, pending); -- cgit From 66156220ebf5dc212e9aa86015b7301d1b665b50 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 5 Apr 2007 03:51:49 +0000 Subject: r22082: merged the ctdb changes from bzr added opendb ctdb backend from ronnie (This used to be commit b0da25cb79f860bfa14ba7a8419c7996d936292b) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/common/opendb.c | 6 +++++- source4/ntvfs/common/opendb.h | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 665e8e255b..5c744f9c90 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -10,6 +10,6 @@ OBJ_FILES = \ opendb_tdb.o \ notify.o PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share -PRIVATE_DEPENDENCIES = brlock_ctdb +PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index c17b819c04..ea27efdf3b 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -62,7 +62,11 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, struct ntvfs_context *ntvfs_ctx) { if (ops == NULL) { - odb_tdb_init_ops(); + if (lp_parm_bool(-1, "ctdb", "opendb", False)) { + odb_ctdb_init_ops(); + } else { + odb_tdb_init_ops(); + } } return ops->odb_init(mem_ctx, ntvfs_ctx); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 9d6c18c471..85bb678d77 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -46,4 +46,4 @@ struct opendb_ops { void odb_set_ops(const struct opendb_ops *new_ops); void odb_tdb_init_ops(void); - +void odb_ctdb_init_ops(void); -- cgit From 3529cf25eb9c2cfb2a960f8e95f9ecdb264063b1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 12 Apr 2007 14:56:29 +0000 Subject: r22200: make ntvfs a subsystem as linking ntvfs.so.1 uses ca. 800 cmdline args to ld and that fails on some hosts in the build-farm, lets see if they will be happier now metze (This used to be commit fda810ff129646535e9fa6d2b2c77559b5d58f92) --- source4/ntvfs/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 8dd71ed56f..66b902a753 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -79,11 +79,11 @@ OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS -[LIBRARY::ntvfs] +[SUBSYSTEM::ntvfs] PUBLIC_HEADERS = ntvfs.h -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = Virtual File System with NTFS semantics +#VERSION = 0.0.1 +#SO_VERSION = 0 +#DESCRIPTION = Virtual File System with NTFS semantics PRIVATE_PROTO_HEADER = ntvfs_proto.h OBJ_FILES = \ ntvfs_base.o \ -- cgit From aabf459ca6c7841308ace365fb5df90331d54d92 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Apr 2007 10:36:51 +0000 Subject: r22258: make ntvfs a library again metze (This used to be commit 26566222ec6ff221d8d8c971f5a1d6d9d4952e30) --- source4/ntvfs/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 66b902a753..8dd71ed56f 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -79,11 +79,11 @@ OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS -[SUBSYSTEM::ntvfs] +[LIBRARY::ntvfs] PUBLIC_HEADERS = ntvfs.h -#VERSION = 0.0.1 -#SO_VERSION = 0 -#DESCRIPTION = Virtual File System with NTFS semantics +VERSION = 0.0.1 +SO_VERSION = 0 +DESCRIPTION = Virtual File System with NTFS semantics PRIVATE_PROTO_HEADER = ntvfs_proto.h OBJ_FILES = \ ntvfs_base.o \ -- cgit From cfb00400df284bb337028d260be0961b994bef5a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Apr 2007 06:57:07 +0000 Subject: r22399: fix major memory leak metze (This used to be commit cc71fa34961e7ab73eebc284194bf03e9b17525a) --- source4/ntvfs/posix/xattr_tdb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index cea50bb4fa..1e0b100ba8 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -229,5 +229,7 @@ NTSTATUS unlink_xattr_tdb(struct pvfs_state *pvfs, const char *fname) delete_xattr_tdb(pvfs, s, fname, -1); } - return delete_xattr_tdb(pvfs, XATTR_LIST_ATTR, fname, -1); + status = delete_xattr_tdb(pvfs, XATTR_LIST_ATTR, fname, -1); + talloc_free(mem_ctx); + return status; } -- cgit From 344cde462e460c5a6effa6651e039d6384681eea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 20 Apr 2007 11:04:13 +0000 Subject: r22406: this dependencies should also be private metze (This used to be commit 7f07895cac3e933b39f81bf67812834352184af0) --- source4/ntvfs/config.mk | 4 ++-- source4/ntvfs/posix/config.mk | 2 +- source4/ntvfs/unixuid/config.mk | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 8dd71ed56f..b1aada7b31 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -11,7 +11,7 @@ INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = ntvfs OBJ_FILES = \ cifs/vfs_cifs.o -PUBLIC_DEPENDENCIES = \ +PRIVATE_DEPENDENCIES = \ LIBCLI_SMB LIBCLI_RAW # End MODULE ntvfs_cifs ################################################ @@ -61,7 +61,7 @@ OBJ_FILES = \ ipc/vfs_ipc.o \ ipc/ipc_rap.o \ ipc/rap_server.o -PUBLIC_DEPENDENCIES = dcerpc_server DCERPC_COMMON +PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 91dc7bd9e5..6588be11ae 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -63,6 +63,6 @@ OBJ_FILES = \ xattr_system.o \ xattr_tdb.o #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 -PUBLIC_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio +PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio # End MODULE ntvfs_posix ################################################ diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index a26f96ffad..d078e9f5c6 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -5,6 +5,6 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs OBJ_FILES = \ vfs_unixuid.o -PUBLIC_DEPENDENCIES = SAMDB +PRIVATE_DEPENDENCIES = SAMDB # End MODULE ntvfs_unixuid ################################################ -- cgit From bf27e58c2f1ce897a222a63bc1771716e90d5672 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 May 2007 00:58:24 +0000 Subject: r22831: take advantage of EVENT_FD_AUTOCLOSE in the inotify code (This used to be commit 419ef7393f9208e274745808980e0342e2e65a37) --- source4/ntvfs/sysdep/inotify.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index fbbf6e4010..cc612d8f9a 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -79,16 +79,6 @@ struct inotify_watch_context { }; -/* - destroy the inotify private context -*/ -static int inotify_destructor(struct inotify_private *in) -{ - close(in->fd); - return 0; -} - - /* see if a particular event from inotify really does match a requested notify event in SMB @@ -271,10 +261,9 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) in->watches = NULL; ctx->private_data = in; - talloc_set_destructor(in, inotify_destructor); /* add a event waiting for the inotify fd to be readable */ - event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ, inotify_handler, in); + event_add_fd(ctx->ev, in, in->fd, EVENT_FD_READ|EVENT_FD_AUTOCLOSE, inotify_handler, in); return NT_STATUS_OK; } -- cgit From a42f78cd503c8fdb8c8de00f21a4bdc830478567 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 11:45:39 +0000 Subject: r22842: fix directory listing of SMB2 and include directories and hidden files metze (This used to be commit e087772ec9ec561b13dbdf6bfead7394a184d7d9) --- source4/ntvfs/posix/pvfs_search.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 6224e15304..609538f678 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -683,7 +683,7 @@ static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs, search->handle = INVALID_SEARCH_HANDLE; search->dir = dir; search->current_index = 0; - search->search_attrib = 0; + search->search_attrib = 0x0000FFFF; search->must_attrib = 0; search->last_used = 0; search->num_ea_names = 0; -- cgit From bd93b41d17361b0ee8aa050c8b7b85622846699d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 13:47:03 +0000 Subject: r22849: map smb2 lock to the generic level metze (This used to be commit fbbb144f8e5271a543c0b47b0105eccd357477ba) --- source4/ntvfs/ntvfs_generic.c | 55 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index aa6edcdf42..05fb0df47b 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -33,6 +33,8 @@ #include "includes.h" #include "ntvfs/ntvfs.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" /* a second stage function converts from the out parameters of the generic call onto the out parameters of the specific call made */ @@ -960,27 +962,60 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_LEVEL; case RAW_LOCK_LOCK: + lck2->generic.level = RAW_LOCK_GENERIC; + lck2->generic.in.file.ntvfs= lck->lock.in.file.ntvfs; + lck2->generic.in.mode = 0; + lck2->generic.in.timeout = 0; lck2->generic.in.ulock_cnt = 0; lck2->generic.in.lock_cnt = 1; + lck2->generic.in.locks = locks; + locks->pid = req->smbpid; + locks->offset = lck->lock.in.offset; + locks->count = lck->lock.in.count; break; case RAW_LOCK_UNLOCK: + lck2->generic.level = RAW_LOCK_GENERIC; + lck2->generic.in.file.ntvfs= lck->unlock.in.file.ntvfs; + lck2->generic.in.mode = 0; + lck2->generic.in.timeout = 0; lck2->generic.in.ulock_cnt = 1; lck2->generic.in.lock_cnt = 0; + lck2->generic.in.locks = locks; + locks->pid = req->smbpid; + locks->offset = lck->unlock.in.offset; + locks->count = lck->unlock.in.count; break; case RAW_LOCK_SMB2: - return NT_STATUS_INVALID_LEVEL; - } + if (lck->smb2.in.unknown1 != 1) { + return NT_STATUS_INVALID_PARAMETER; + } + + lck2->generic.level = RAW_LOCK_GENERIC; + lck2->generic.in.file.ntvfs= lck->smb2.in.file.ntvfs; + if (lck->smb2.in.flags & SMB2_LOCK_FLAG_EXCLUSIV) { + lck2->generic.in.mode = 0; + } else { + lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; + } + lck2->generic.in.timeout = 0; + if (lck->smb2.in.flags & SMB2_LOCK_FLAG_UNLOCK) { + lck2->generic.in.ulock_cnt = 1; + lck2->generic.in.lock_cnt = 0; + } else { + lck2->generic.in.ulock_cnt = 0; + lck2->generic.in.lock_cnt = 1; + } + lck2->generic.in.locks = locks; + locks->pid = 0; + locks->offset = lck->smb2.in.offset; + locks->count = lck->smb2.in.count; - lck2->generic.level = RAW_LOCK_GENERIC; - lck2->generic.in.file.ntvfs= lck->lock.in.file.ntvfs; - lck2->generic.in.mode = 0; - lck2->generic.in.timeout = 0; - lck2->generic.in.locks = locks; - locks->pid = req->smbpid; - locks->offset = lck->lock.in.offset; - locks->count = lck->lock.in.count; + /* initialize output value */ + lck->smb2.out.unknown1 = 0; + break; + } /* * we don't need to call ntvfs_map_async_setup() here, -- cgit From 0543c06d2598ccd476bcb78e7701e50e6a85e51f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 17:51:19 +0000 Subject: r22863: in SMB2 mode we always need to return NT_STATUS_LOCK_NOT_GRANTED metze (This used to be commit 83a61a2892539b2bcfbdaac7ca169c99f2b4503a) --- source4/ntvfs/common/brlock_tdb.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 6fe8cefd34..d5eb7d82fb 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -34,6 +34,7 @@ #include "libcli/libcli.h" #include "cluster/cluster.h" #include "ntvfs/common/brlock.h" +#include "ntvfs/ntvfs.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies @@ -220,6 +221,11 @@ static NTSTATUS brl_tdb_lock_failed(struct brl_handle *brlh, struct lock_struct * this function is only called for non pending lock! */ + /* in SMB2 mode always return NT_STATUS_LOCK_NOT_GRANTED! */ + if (lock->ntvfs->ctx->protocol == PROTOCOL_SMB2) { + return NT_STATUS_LOCK_NOT_GRANTED; + } + /* * if the notify_ptr is non NULL, * it means that we're at the end of a pending lock -- cgit From 5eb7420f119df890e2e4b7acd904dc2da70793a6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 17:56:00 +0000 Subject: r22864: in SMB2 mode we need to cancel an existing lock with a conflicting lock if they're on the same handle and the same range metze (This used to be commit 36384bb4a071dcc366ae1039bd0579f08b84e238) --- source4/ntvfs/posix/pvfs_lock.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 4527cd3ed2..9b5823e69e 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -69,8 +69,13 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, int i, NTSTATUS status) { + /* in SMB2 mode we also try to unlock failing lock */ + if (req->ctx->protocol != PROTOCOL_SMB2) { + i--; + } + /* undo the locks we just did */ - for (i=i-1;i>=0;i--) { + for (;i>=0;i--) { brl_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, @@ -377,8 +382,12 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, DLIST_ADD(f->pending_list, pending); return NT_STATUS_OK; } + /* in SMB2 mode we also try to unlock failing lock */ + if (req->ctx->protocol != PROTOCOL_SMB2) { + i--; + } /* undo the locks we just did */ - for (i=i-1;i>=0;i--) { + for (;i>=0;i--) { brl_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, -- cgit From 37f8c04d900df00dd984dfd6be33b367b145a3ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 14 May 2007 17:58:28 +0000 Subject: r22865: handle pending locks in smb2 metze (This used to be commit 8329fa689521b12e4ce2ac094b3e322fa4ed4bb8) --- source4/ntvfs/ntvfs_generic.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 05fb0df47b..aa3009d86e 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -999,7 +999,11 @@ _PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, } else { lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; } - lck2->generic.in.timeout = 0; + if (lck->smb2.in.flags & SMB2_LOCK_FLAG_NO_PENDING) { + lck2->generic.in.timeout = 0; + } else { + lck2->generic.in.timeout = UINT32_MAX; + } if (lck->smb2.in.flags & SMB2_LOCK_FLAG_UNLOCK) { lck2->generic.in.ulock_cnt = 1; lck2->generic.in.lock_cnt = 0; -- cgit From 3a88c56346929695cc4b2ecc22e20aee51b493d9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 May 2007 01:21:20 +0000 Subject: r22874: Expand the RPC-QFILEINFO-IPC test, and add a server implementation to match. This should help with Vista joins. Andrew Bartlett (This used to be commit 8f85fb37862044d4b618e4184274bc67432af73b) --- source4/ntvfs/ipc/vfs_ipc.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index bb80963287..20b70415aa 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -149,7 +149,14 @@ static NTSTATUS ipc_chkpath(struct ntvfs_module_context *ntvfs, static NTSTATUS ipc_qpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { - return NT_STATUS_ACCESS_DENIED; + switch (info->generic.level) { + case RAW_FILEINFO_GENERIC: + return NT_STATUS_INVALID_DEVICE_REQUEST; + case RAW_FILEINFO_GETATTR: + return NT_STATUS_ACCESS_DENIED; + default: + return ntvfs_map_qpathinfo(ntvfs, req, info); + } } /* @@ -602,6 +609,39 @@ static NTSTATUS ipc_setfileinfo(struct ntvfs_module_context *ntvfs, static NTSTATUS ipc_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { + struct ipc_private *private = ntvfs->private_data; + switch (info->generic.level) { + case RAW_FILEINFO_GENERIC: + { + struct pipe_state *p; + p = pipe_state_find(private, info->generic.in.file.ntvfs); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } + ZERO_STRUCT(info->generic.out); + info->generic.out.attrib = FILE_ATTRIBUTE_NORMAL; + info->generic.out.fname.s = strrchr(p->pipe_name, '\\'); + info->generic.out.alloc_size = 4096; + info->generic.out.nlink = 1; + /* What the heck? Match Win2k3: IPC$ pipes are delete pending */ + info->generic.out.delete_pending = 1; + return NT_STATUS_OK; + } + case RAW_FILEINFO_ALT_NAME_INFO: + case RAW_FILEINFO_ALT_NAME_INFORMATION: + case RAW_FILEINFO_STREAM_INFO: + case RAW_FILEINFO_STREAM_INFORMATION: + case RAW_FILEINFO_COMPRESSION_INFO: + case RAW_FILEINFO_COMPRESSION_INFORMATION: + case RAW_FILEINFO_NETWORK_OPEN_INFORMATION: + case RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION: + return NT_STATUS_INVALID_PARAMETER; + case RAW_FILEINFO_ALL_EAS: + return NT_STATUS_ACCESS_DENIED; + default: + return ntvfs_map_qfileinfo(ntvfs, req, info); + } + return NT_STATUS_ACCESS_DENIED; } -- cgit From 4febada51fca5953b84b71b71c9aa0a430c4ee3d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 May 2007 06:51:18 +0000 Subject: r22882: It seems entirly reasonable to follow metze's suggestion and check for a valid file handle first. Andrew Bartlett (This used to be commit 3947db3dcbfe97e9ccb9b9bd2b3a69cf7683af9f) --- source4/ntvfs/ipc/vfs_ipc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 20b70415aa..70dd3e3561 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -610,14 +610,13 @@ static NTSTATUS ipc_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { struct ipc_private *private = ntvfs->private_data; + struct pipe_state *p = pipe_state_find(private, info->generic.in.file.ntvfs); + if (!p) { + return NT_STATUS_INVALID_HANDLE; + } switch (info->generic.level) { case RAW_FILEINFO_GENERIC: { - struct pipe_state *p; - p = pipe_state_find(private, info->generic.in.file.ntvfs); - if (!p) { - return NT_STATUS_INVALID_HANDLE; - } ZERO_STRUCT(info->generic.out); info->generic.out.attrib = FILE_ATTRIBUTE_NORMAL; info->generic.out.fname.s = strrchr(p->pipe_name, '\\'); -- cgit From 283aeb2a37ba7fd05957ae15bd83276cadf31f0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 May 2007 18:23:58 +0000 Subject: r22913: try to work arround the unaligned memory access bug on Tru64 metze (This used to be commit 3a7a30ab1cf724ad2420ae2a1011479fffd826fe) --- source4/ntvfs/posix/pvfs_wait.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 3d0bb465e3..e21b5766cb 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -61,14 +61,20 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin { struct pvfs_wait *pwait = private; struct ntvfs_request *req; + void *p = NULL; /* we need to check that this one is for us. See messaging_send_ptr() for the other side of this. */ - if (data->length != sizeof(void *) || - *(void **)data->data != pwait->private) { + if (data->length == sizeof(void *)) { + void **pp; + pp = (void **)data->data; + p = *pp; + } + if (p == NULL || p != pwait->private) { return; } + pwait->reason = PVFS_WAIT_EVENT; req = pwait->req; -- cgit From e3036006fe99893eb6c4f69ca2e70e48d35e8f24 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 20 May 2007 08:01:02 +0000 Subject: r23017: fixed the warning we have been getting for a long time: pvfs_close: failed to delete XXX during the BASE-DELETE test. It was a real bug, and could result in a delete on close triggering for a handle that had never fully opened. (This used to be commit 398c3724b4cd8c8073c8a77f8b0568d6b3ce1e7d) --- source4/ntvfs/posix/pvfs_open.c | 12 ++++++++++++ source4/ntvfs/posix/vfs_posix.h | 3 +++ 2 files changed, 15 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a0ef77b0ff..b737fa328a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -270,6 +270,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->position = 0; f->handle->mode = 0; f->handle->sticky_write_time = False; + f->handle->open_completed = False; if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && pvfs_directory_empty(pvfs, f->handle->name)) { @@ -379,6 +380,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, goto cleanup_delete; } + f->handle->open_completed = True; + io->generic.out.oplock_level = OPLOCK_NONE; io->generic.out.file.ntvfs = h; io->generic.out.create_action = create_action; @@ -437,6 +440,7 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) } if (h->name->stream_name == NULL && + h->open_completed && pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && open_count == 1) { NTSTATUS status; @@ -701,6 +705,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->mode = 0; f->handle->have_opendb_entry = True; f->handle->sticky_write_time = False; + f->handle->open_completed = False; DLIST_ADD(pvfs->files.list, f); @@ -729,6 +734,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, goto cleanup_delete; } + f->handle->open_completed = True; + notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_FILE_NAME, @@ -1129,6 +1136,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->mode = 0; f->handle->have_opendb_entry = False; f->handle->sticky_write_time = False; + f->handle->open_completed = False; /* form the lock context used for byte range locking and opendb locking */ @@ -1264,6 +1272,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, status = ntvfs_handle_set_backend_data(h, ntvfs, f); NT_STATUS_NOT_OK_RETURN(status); + /* mark the open as having completed fully, so delete on close + can now be used */ + f->handle->open_completed = True; + io->generic.out.oplock_level = oplock_granted; io->generic.out.file.ntvfs = h; io->generic.out.create_action = stream_existed? diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index e79eadd03a..cff0206f61 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -150,6 +150,9 @@ struct pvfs_file_handle { /* have we set a sticky write time that we should remove on close */ BOOL sticky_write_time; + + /* the open went through to completion */ + BOOL open_completed; }; /* open file state */ -- cgit From 615fea1c5c6e742b6e2c9d7a79a7f76435d0788c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 May 2007 05:22:18 +0000 Subject: r23064: Clarify comment and indent (This used to be commit 607e8409f86b28c51a058555021cd45c1cb72a26) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 185e9a3438..c0311ec94f 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -186,7 +186,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, DEBUG(5, ("CIFS backend: Using delegated credentials\n")); credentials = req->session_info->credentials; } else { - DEBUG(1,("CIFS backend: You must supply server, user and password and or have delegated credentials\n")); + DEBUG(1,("CIFS backend: NO delegated credentials found: You must supply server, user and password or the client must supply delegated credentials\n")); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 42c1ef4025186066660b1bb187d063e07bb493ff Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 22 May 2007 09:25:58 +0000 Subject: r23067: use 'const union smb_search_data *file' also in the server code to get rid of compiler warnings in the cifs backend metze (This used to be commit 34ef07b1f5acdad27edd80de8de4c6de7f879f9b) --- source4/ntvfs/cifs/vfs_cifs.c | 4 ++-- source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c | 4 ++-- source4/ntvfs/ipc/vfs_ipc.c | 4 ++-- source4/ntvfs/nbench/vfs_nbench.c | 4 ++-- source4/ntvfs/ntvfs.h | 4 ++-- source4/ntvfs/ntvfs_interface.c | 8 ++++---- source4/ntvfs/posix/pvfs_search.c | 18 +++++++++--------- source4/ntvfs/simple/vfs_simple.c | 4 ++-- source4/ntvfs/unixuid/vfs_unixuid.c | 4 ++-- 9 files changed, 27 insertions(+), 27 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index c0311ec94f..94be3e886b 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -920,7 +920,7 @@ static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct cvfs_private *private = ntvfs->private_data; @@ -933,7 +933,7 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct cvfs_private *private = ntvfs->private_data; diff --git a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c index d0813b9556..91ff4eedd1 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c @@ -830,7 +830,7 @@ static NTSTATUS cifspsx_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS cifspsx_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct cifspsx_dir *dir; int i; @@ -904,7 +904,7 @@ static NTSTATUS cifspsx_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS cifspsx_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct cifspsx_dir *dir; int i; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 70dd3e3561..f05c3c29e3 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -669,7 +669,7 @@ static NTSTATUS ipc_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS ipc_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { return NT_STATUS_ACCESS_DENIED; } @@ -680,7 +680,7 @@ static NTSTATUS ipc_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS ipc_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index a56338d931..c361d8abf6 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -842,7 +842,7 @@ static void nbench_search_first_send(struct ntvfs_request *req) static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; @@ -864,7 +864,7 @@ static void nbench_search_next_send(struct ntvfs_request *req) static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index e805c97bbd..c346c0b9e9 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -92,11 +92,11 @@ struct ntvfs_ops { NTSTATUS (*search_first)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)); + BOOL (*callback)(void *private, const union smb_search_data *file)); NTSTATUS (*search_next)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)); + BOOL (*callback)(void *private, const union smb_search_data *file)); NTSTATUS (*search_close)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io); diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index fc8fccca33..4a5fd42384 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -150,7 +150,7 @@ _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) /* directory search */ _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private, - BOOL ntvfs_callback(void *private, union smb_search_data *file)) + BOOL ntvfs_callback(void *private, const union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_first) { @@ -160,7 +160,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search } _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private, - BOOL ntvfs_callback(void *private, union smb_search_data *file)) + BOOL ntvfs_callback(void *private, const union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_next) { @@ -470,7 +470,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + BOOL (*callback)(void *private, const union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_first) { return NT_STATUS_NOT_IMPLEMENTED; @@ -481,7 +481,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, _PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, union smb_search_data *file)) + BOOL (*callback)(void *private, const union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_next) { return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 609538f678..f33acb80b1 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -238,7 +238,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, enum smb_search_data_level level, uint_t *reply_count, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir = search->dir; NTSTATUS status; @@ -314,7 +314,7 @@ static void pvfs_search_cleanup(struct pvfs_state *pvfs) static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir; struct pvfs_state *pvfs = ntvfs->private_data; @@ -404,7 +404,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; @@ -453,7 +453,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir; struct pvfs_state *pvfs = ntvfs->private_data; @@ -549,7 +549,7 @@ static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; @@ -610,7 +610,7 @@ static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const struct smb2_find *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir; struct pvfs_state *pvfs = ntvfs->private_data; @@ -713,7 +713,7 @@ static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_next_smb2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const struct smb2_find *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; @@ -766,7 +766,7 @@ static NTSTATUS pvfs_search_next_smb2(struct ntvfs_module_context *ntvfs, NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { switch (io->generic.level) { case RAW_SEARCH_SEARCH: @@ -788,7 +788,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { switch (io->generic.level) { case RAW_SEARCH_SEARCH: diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 5bfc0f2e5c..006042b495 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -827,7 +827,7 @@ static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct svfs_dir *dir; int i; @@ -901,7 +901,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { struct svfs_dir *dir; int i; diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index b430d3048b..56df008c2a 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -592,7 +592,7 @@ static NTSTATUS unixuid_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; @@ -605,7 +605,7 @@ static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS unixuid_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, union smb_search_data *)) + BOOL (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; -- cgit From 6d52f4a63f89f771707cd617a19b4162dabbd88a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 May 2007 08:44:33 +0000 Subject: r23136: Set the event context onto the credentials in more places. This helps ensure that the kerberos code uses the right event context. Andrew Bartlett (This used to be commit cbdce358ae8f86c9b76a50537b931e56b07ee213) --- source4/ntvfs/cifs/vfs_cifs.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 94be3e886b..4e6be4c979 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -165,6 +165,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, if (!credentials) { return NT_STATUS_NO_MEMORY; } + cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); cli_credentials_set_conf(credentials); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { @@ -174,6 +175,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, } else if (machine_account) { DEBUG(5, ("CIFS backend: Using machine account\n")); credentials = cli_credentials_init(private); + cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); cli_credentials_set_conf(credentials); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); -- cgit From 879e1e0ec746d9d06c3bef1c91d1d2cd6f916442 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2007 04:16:16 +0000 Subject: r23697: use the file perm options in the posix backend (This used to be commit 701d06ac016c69fcd9ac92b5afefa2346c9bc26f) --- source4/ntvfs/posix/pvfs_fileinfo.c | 25 +++++++++++++++---------- source4/ntvfs/posix/vfs_posix.c | 13 +++++++++++++ source4/ntvfs/posix/vfs_posix.h | 8 ++++++++ 3 files changed, 36 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 8226b66d1f..b244019d56 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -88,15 +88,11 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, */ mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32_t attrib) { - mode_t mode = S_IRUSR; + mode_t mode = (S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH); - if (attrib & FILE_ATTRIBUTE_DIRECTORY) { - mode |= S_IXUSR; - } - - if (!(attrib & FILE_ATTRIBUTE_READONLY) || - (pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { - mode |= S_IWUSR; + if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE) && + (attrib & FILE_ATTRIBUTE_READONLY)) { + mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH); } if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { @@ -104,18 +100,27 @@ mode_t pvfs_fileperms(struct pvfs_state *pvfs, uint32_t attrib) (pvfs->flags & PVFS_FLAG_MAP_ARCHIVE)) { mode |= S_IXUSR; } - if ((attrib & FILE_ATTRIBUTE_SYSTEM) && (pvfs->flags & PVFS_FLAG_MAP_SYSTEM)) { mode |= S_IXGRP; } - if ((attrib & FILE_ATTRIBUTE_HIDDEN) && (pvfs->flags & PVFS_FLAG_MAP_HIDDEN)) { mode |= S_IXOTH; } } + if (attrib & FILE_ATTRIBUTE_DIRECTORY) { + mode |= (S_IFDIR | S_IWUSR); + mode |= (S_IXUSR | S_IXGRP | S_IXOTH); + mode &= pvfs->options.dir_mask; + mode |= pvfs->options.force_dir_mode; + } else { + mode &= pvfs->options.create_mask; + mode |= pvfs->options.force_create_mode; + } + return mode; } + diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index c8d85b557c..2508496fac 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -60,6 +60,19 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) if (share_bool_option(scfg, PVFS_AIO, False)) pvfs->flags |= PVFS_FLAG_LINUX_AIO; + /* file perm options */ + pvfs->options.create_mask = share_int_option(scfg, + SHARE_CREATE_MASK, + SHARE_CREATE_MASK_DEFAULT); + pvfs->options.dir_mask = share_int_option(scfg, + SHARE_DIR_MASK, + SHARE_DIR_MASK_DEFAULT); + pvfs->options.force_dir_mode = share_int_option(scfg, + SHARE_FORCE_DIR_MODE, + SHARE_FORCE_DIR_MODE_DEFAULT); + pvfs->options.force_create_mode = share_int_option(scfg, + SHARE_FORCE_CREATE_MODE, + SHARE_FORCE_CREATE_MODE_DEFAULT); /* this must be a power of 2 */ pvfs->alloc_size_rounding = share_int_option(scfg, PVFS_ALLOCATION_ROUNDING, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index cff0206f61..78b63612da 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -86,6 +86,14 @@ struct pvfs_state { /* the acl backend */ const struct pvfs_acl_ops *acl_ops; + + /* non-flag share options */ + struct { + mode_t dir_mask; + mode_t force_dir_mode; + mode_t create_mask; + mode_t force_create_mode; + } options; }; /* this is the basic information needed about a file from the filesystem */ -- cgit From d1984d5cf3dd43b3bbc214dd8c091b5fc2a86a46 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2007 04:18:44 +0000 Subject: r23698: fixed notify:backend so it actually works again (This used to be commit d49ce1d752fdf6a6e1d6b9da12e7afb7d385ef8c) --- source4/ntvfs/sysdep/sys_notify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 1c0467236a..cae07a1e69 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -34,7 +34,7 @@ static struct sys_notify_backend *backends; static uint32_t num_backends; -#define NOTIFY_BACKEND "notify-backend" +#define NOTIFY_BACKEND "notify:backend" /* initialise a system change notify backend -- cgit From 0479a2f1cbae51fcd8dbdc3c148c808421fb4d25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 02:07:03 +0000 Subject: r23792: convert Samba4 to GPLv3 There are still a few tidyups of old FSF addresses to come (in both s3 and s4). More commits soon. (This used to be commit fcf38a38ac691abd0fa51b89dc951a08e89fdafa) --- source4/ntvfs/cifs/vfs_cifs.c | 5 ++--- source4/ntvfs/cifs_posix_cli/svfs_util.c | 5 ++--- source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c | 5 ++--- source4/ntvfs/common/brlock.c | 5 ++--- source4/ntvfs/common/brlock.h | 5 ++--- source4/ntvfs/common/brlock_tdb.c | 5 ++--- source4/ntvfs/common/init.c | 5 ++--- source4/ntvfs/common/notify.c | 5 ++--- source4/ntvfs/common/ntvfs_common.h | 5 ++--- source4/ntvfs/common/opendb.c | 5 ++--- source4/ntvfs/common/opendb.h | 5 ++--- source4/ntvfs/common/opendb_tdb.c | 5 ++--- source4/ntvfs/ipc/ipc_rap.c | 5 ++--- source4/ntvfs/ipc/rap_server.c | 5 ++--- source4/ntvfs/ipc/vfs_ipc.c | 5 ++--- source4/ntvfs/nbench/vfs_nbench.c | 5 ++--- source4/ntvfs/ntvfs.h | 5 ++--- source4/ntvfs/ntvfs_base.c | 5 ++--- source4/ntvfs/ntvfs_generic.c | 5 ++--- source4/ntvfs/ntvfs_interface.c | 5 ++--- source4/ntvfs/ntvfs_util.c | 5 ++--- source4/ntvfs/posix/pvfs_acl.c | 5 ++--- source4/ntvfs/posix/pvfs_acl_nfs4.c | 5 ++--- source4/ntvfs/posix/pvfs_acl_xattr.c | 5 ++--- source4/ntvfs/posix/pvfs_aio.c | 5 ++--- source4/ntvfs/posix/pvfs_dirlist.c | 5 ++--- source4/ntvfs/posix/pvfs_fileinfo.c | 5 ++--- source4/ntvfs/posix/pvfs_flush.c | 5 ++--- source4/ntvfs/posix/pvfs_fsinfo.c | 5 ++--- source4/ntvfs/posix/pvfs_ioctl.c | 5 ++--- source4/ntvfs/posix/pvfs_lock.c | 5 ++--- source4/ntvfs/posix/pvfs_mkdir.c | 5 ++--- source4/ntvfs/posix/pvfs_notify.c | 5 ++--- source4/ntvfs/posix/pvfs_open.c | 5 ++--- source4/ntvfs/posix/pvfs_qfileinfo.c | 5 ++--- source4/ntvfs/posix/pvfs_read.c | 5 ++--- source4/ntvfs/posix/pvfs_rename.c | 5 ++--- source4/ntvfs/posix/pvfs_resolve.c | 5 ++--- source4/ntvfs/posix/pvfs_search.c | 5 ++--- source4/ntvfs/posix/pvfs_seek.c | 5 ++--- source4/ntvfs/posix/pvfs_setfileinfo.c | 5 ++--- source4/ntvfs/posix/pvfs_shortname.c | 5 ++--- source4/ntvfs/posix/pvfs_streams.c | 5 ++--- source4/ntvfs/posix/pvfs_unlink.c | 5 ++--- source4/ntvfs/posix/pvfs_util.c | 5 ++--- source4/ntvfs/posix/pvfs_wait.c | 5 ++--- source4/ntvfs/posix/pvfs_write.c | 5 ++--- source4/ntvfs/posix/pvfs_xattr.c | 5 ++--- source4/ntvfs/posix/vfs_posix.c | 5 ++--- source4/ntvfs/posix/vfs_posix.h | 5 ++--- source4/ntvfs/posix/xattr_system.c | 5 ++--- source4/ntvfs/posix/xattr_tdb.c | 5 ++--- source4/ntvfs/print/vfs_print.c | 5 ++--- source4/ntvfs/simple/svfs_util.c | 5 ++--- source4/ntvfs/simple/vfs_simple.c | 5 ++--- source4/ntvfs/sysdep/inotify.c | 5 ++--- source4/ntvfs/sysdep/sys_notify.c | 5 ++--- source4/ntvfs/sysdep/sys_notify.h | 5 ++--- source4/ntvfs/unixuid/vfs_unixuid.c | 5 ++--- 59 files changed, 118 insertions(+), 177 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 4e6be4c979..4c079b36fc 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements a CIFS->CIFS NTVFS filesystem backend. diff --git a/source4/ntvfs/cifs_posix_cli/svfs_util.c b/source4/ntvfs/cifs_posix_cli/svfs_util.c index 5622d775ac..42d869209d 100644 --- a/source4/ntvfs/cifs_posix_cli/svfs_util.c +++ b/source4/ntvfs/cifs_posix_cli/svfs_util.c @@ -10,7 +10,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -19,8 +19,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* utility functions for cifs posix backend diff --git a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c index 91ff4eedd1..088d1644d3 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements a very simple NTVFS filesystem backend. diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 8397c3bdd3..56d3ff80f6 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* This module implements a tdb based byte range locking service, diff --git a/source4/ntvfs/common/brlock.h b/source4/ntvfs/common/brlock.h index a462254ddf..5a040dc234 100644 --- a/source4/ntvfs/common/brlock.h +++ b/source4/ntvfs/common/brlock.h @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ struct brlock_ops { diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index d5eb7d82fb..6e75a6fb0a 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* This module implements a tdb based byte range locking service, diff --git a/source4/ntvfs/common/init.c b/source4/ntvfs/common/init.c index 6cdc70dc50..1889bef23d 100644 --- a/source4/ntvfs/common/init.c +++ b/source4/ntvfs/common/init.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 91fa8a1d78..0d36a20a60 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/common/ntvfs_common.h b/source4/ntvfs/common/ntvfs_common.h index 4cc7ebe752..37dd553a4e 100644 --- a/source4/ntvfs/common/ntvfs_common.h +++ b/source4/ntvfs/common/ntvfs_common.h @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifndef _NTVFS_COMMON_H_ diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index ea27efdf3b..69282dd12e 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 85bb678d77..835fb19046 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ struct opendb_ops { diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index c181b033e7..0bfe6e4eb3 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 48a7822446..605a172a70 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index f92b02c20a..d1a4dd9edc 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index f05c3c29e3..aeb99e50b0 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements the IPC$ backend, called by the NTVFS subsystem to diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index c361d8abf6..9379419c50 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index c346c0b9e9..12a4b3a4df 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifndef _NTVFS_H_ diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 599669360b..03c5aff01c 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements the core code for all NTVFS modules. Backends register themselves here. diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index aa3009d86e..8ed99ce3f1 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements mappings between info levels for NTVFS backend calls diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 4a5fd42384..74fb815359 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index fc457f21c4..3158bdf1fd 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements common utility functions that many NTVFS backends may wish to use diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 1a3fc184de..4302b7f890 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_acl_nfs4.c b/source4/ntvfs/posix/pvfs_acl_nfs4.c index b0a329c639..2abb1482a4 100644 --- a/source4/ntvfs/posix/pvfs_acl_nfs4.c +++ b/source4/ntvfs/posix/pvfs_acl_nfs4.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_acl_xattr.c b/source4/ntvfs/posix/pvfs_acl_xattr.c index 705f525507..1cf52718c2 100644 --- a/source4/ntvfs/posix/pvfs_acl_xattr.c +++ b/source4/ntvfs/posix/pvfs_acl_xattr.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_aio.c b/source4/ntvfs/posix/pvfs_aio.c index f40382b5ec..2a10b03fda 100644 --- a/source4/ntvfs/posix/pvfs_aio.c +++ b/source4/ntvfs/posix/pvfs_aio.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index 7efc091c42..e54cb847f5 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* directory listing functions for posix backend diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index b244019d56..4c383ed45d 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index a9f36d1ae1..61e73cedba 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_fsinfo.c b/source4/ntvfs/posix/pvfs_fsinfo.c index c1df33be18..9a836fac32 100644 --- a/source4/ntvfs/posix/pvfs_fsinfo.c +++ b/source4/ntvfs/posix/pvfs_fsinfo.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index 8ba662d3e7..d0360e67ed 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 9b5823e69e..bf17ceb83b 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_mkdir.c b/source4/ntvfs/posix/pvfs_mkdir.c index 2f5ba0a744..8cc96173ad 100644 --- a/source4/ntvfs/posix/pvfs_mkdir.c +++ b/source4/ntvfs/posix/pvfs_mkdir.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index cc91c678b1..3e289a0948 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index b737fa328a..269df13069 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index b76cafb38a..2f01c08fb0 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 91945dbb0f..418b7e09fb 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 73513fdf00..3aa63bd2ca 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 3e5457f0cd..94fa0263ad 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index f33acb80b1..cefcee6155 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index 7365f33b15..3ea8b7cb6e 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 6c7c6dc6f7..f20270c743 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 00647f1299..5df4a57f9c 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 159cf7470d..a3b98feead 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index c02f704bd5..ef56d99fb5 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index f286dfdc48..895fcd9685 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* utility functions for posix backend diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index e21b5766cb..989985a033 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index d433a80cc6..5a11f01952 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index fcc2d351c9..61a95ec824 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 2508496fac..2c414065cb 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements most of the POSIX NTVFS backend diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 78b63612da..b08110915b 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifndef _VFS_POSIX_H_ diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index ab2337c200..7283d716b4 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index 1e0b100ba8..b49b11a72d 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index dfe76b846e..30bb530ee9 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements the print backend, called by the NTVFS subsystem to diff --git a/source4/ntvfs/simple/svfs_util.c b/source4/ntvfs/simple/svfs_util.c index c3c0412f4b..286c556e30 100644 --- a/source4/ntvfs/simple/svfs_util.c +++ b/source4/ntvfs/simple/svfs_util.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* utility functions for simple backend diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 006042b495..95ea6d8647 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* this implements a very simple NTVFS filesystem backend. diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index cc612d8f9a..afeb319b35 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index cae07a1e69..8d2aed7fa0 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /* diff --git a/source4/ntvfs/sysdep/sys_notify.h b/source4/ntvfs/sysdep/sys_notify.h index a660ee7de5..63d4282e7c 100644 --- a/source4/ntvfs/sysdep/sys_notify.h +++ b/source4/ntvfs/sysdep/sys_notify.h @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "librpc/gen_ndr/notify.h" diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 56df008c2a..74bc6309c1 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From bd750a77c086da01a389f567b99cdbb7bf2bd7d9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 30 Jul 2007 09:04:28 +0000 Subject: r24075: As suggested by metze, match the behaviour of ntvfs_posix, and remove the backend data (effectivly closing the handle) when we close an IPC FD. This should fix #4821. Andrew Bartlett (This used to be commit efaf91b9d53c1d9b882c53e069e8e7c15394e0f3) --- source4/ntvfs/ipc/vfs_ipc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index aeb99e50b0..fbac82a305 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -174,6 +174,7 @@ static NTSTATUS ipc_setpathinfo(struct ntvfs_module_context *ntvfs, static int ipc_fd_destructor(struct pipe_state *p) { DLIST_REMOVE(p->private->pipe_list, p); + ntvfs_handle_remove_backend_data(p->handle, p->private->ntvfs); return 0; } -- cgit From 4792285282e2ec78ccb0ebc3cac6465d1d26ef10 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 9 Aug 2007 06:36:16 +0000 Subject: r24284: change brlock_tdb.c to use the dbwrap API. This actually makes the backend abstraction for brlock pointless, but I have left it in place for now. It would be useful for other clustering systems that can't map to dbwrap, and would also be useful if we wanted to keep the remote function call capabilities in ctdb instead of the less efficient fetch_locked() call in dbwrap (This used to be commit 912c014b7c131ab051ff6eb2db4e68cb6fbbeb14) --- source4/ntvfs/common/brlock.c | 6 +- source4/ntvfs/common/brlock_tdb.c | 159 ++++++++++++++++---------------------- source4/ntvfs/common/config.mk | 2 +- 3 files changed, 67 insertions(+), 100 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 56d3ff80f6..27d7437f4f 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -52,11 +52,7 @@ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx) { if (ops == NULL) { - if (lp_parm_bool(-1, "ctdb", "brlock", False)) { - brl_ctdb_init_ops(); - } else { - brl_tdb_init_ops(); - } + brl_tdb_init_ops(); } return ops->brl_init(mem_ctx, server, messaging_ctx); } diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 6e75a6fb0a..25a0a040a5 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -28,7 +28,7 @@ #include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messaging/messaging.h" -#include "db_wrap.h" +#include "lib/dbwrap/dbwrap.h" #include "lib/messaging/irpc.h" #include "libcli/libcli.h" #include "cluster/cluster.h" @@ -45,7 +45,7 @@ /* this struct is typicaly attached to tcon */ struct brl_context { - struct tdb_wrap *w; + struct db_context *db; struct server_id server; struct messaging_context *messaging_ctx; }; @@ -94,8 +94,8 @@ static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id se return NULL; } - brl->w = cluster_tdb_tmp_open(brl, "brlock.tdb", TDB_DEFAULT); - if (brl->w == NULL) { + brl->db = db_tmp_open(brl, "brlock.tdb", TDB_DEFAULT); + if (brl->db == NULL) { talloc_free(brl); return NULL; } @@ -281,11 +281,13 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, int count=0, i; struct lock_struct lock, *locks=NULL; NTSTATUS status; + struct db_record *rec = NULL; kbuf.dptr = brlh->key.data; kbuf.dsize = brlh->key.length; - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + rec = brl->db->fetch_locked(brl->db, brl, kbuf); + if (rec == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } @@ -303,12 +305,12 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, brlh->last_lock = lock; if (NT_STATUS_IS_OK(status)) { - tdb_chainunlock(brl->w->tdb, kbuf); + talloc_free(rec); return NT_STATUS_OK; } } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = rec->value; lock.context.smbpid = smbpid; lock.context.server = brl->server; @@ -333,7 +335,7 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, } /* no conflicts - add it to the list of locks */ - locks = realloc_p(locks, struct lock_struct, count+1); + locks = talloc_realloc(rec, locks, struct lock_struct, count+1); if (!locks) { status = NT_STATUS_NO_MEMORY; goto fail; @@ -343,13 +345,12 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, locks[count] = lock; dbuf.dsize += sizeof(lock); - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; + status = rec->store(rec, dbuf, TDB_REPLACE); + if (!NT_STATUS_IS_OK(status)) { goto fail; } - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); + talloc_free(rec); /* the caller needs to know if the real lock was granted. If we have reached here then it must be a pending lock that @@ -361,9 +362,7 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, return NT_STATUS_OK; fail: - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); + talloc_free(rec); return status; } @@ -431,20 +430,23 @@ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, struct lock_struct *locks, *lock; struct lock_context context; NTSTATUS status; + struct db_record *rec = NULL; kbuf.dptr = brlh->key.data; kbuf.dsize = brlh->key.length; - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + rec = brl->db->fetch_locked(brl->db, brl, kbuf); + if (rec == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); + if (!rec->value.dptr) { + talloc_free(rec); return NT_STATUS_RANGE_NOT_LOCKED; } + dbuf = rec->value; + context.smbpid = smbpid; context.server = brl->server; context.ctx = brl; @@ -477,43 +479,27 @@ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, } found: - if (i < count) { - /* found it - delete it */ - if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } else { - struct lock_struct removed_lock = *lock; - if (i < count-1) { - memmove(&locks[i], &locks[i+1], - sizeof(*locks)*((count-1) - i)); - } - count--; - - /* send notifications for any relevant pending locks */ - brl_tdb_notify_unlock(brl, locks, count, &removed_lock); - - dbuf.dsize = count * sizeof(*locks); - - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } + if (i == count) { + status = NT_STATUS_RANGE_NOT_LOCKED; + } else if (count == 1) { + status = rec->delete_rec(rec); + } else { + struct lock_struct removed_lock = *lock; + if (i < count-1) { + memmove(&locks[i], &locks[i+1], + sizeof(*locks)*((count-1) - i)); } + count--; - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; + /* send notifications for any relevant pending locks */ + brl_tdb_notify_unlock(brl, locks, count, &removed_lock); + + dbuf.dsize = count * sizeof(*locks); + + status = rec->store(rec, dbuf, TDB_REPLACE); } - - /* we didn't find it */ - status = NT_STATUS_RANGE_NOT_LOCKED; - fail: - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); + talloc_free(rec); return status; } @@ -531,24 +517,24 @@ static NTSTATUS brl_tdb_remove_pending(struct brl_context *brl, int count, i; struct lock_struct *locks; NTSTATUS status; + struct db_record *rec = NULL; kbuf.dptr = brlh->key.data; kbuf.dsize = brlh->key.length; - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + rec = brl->db->fetch_locked(brl->db, brl, kbuf); + if (rec == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_RANGE_NOT_LOCKED; - } + dbuf = rec->value; /* there are existing locks - find a match */ locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); + status = NT_STATUS_RANGE_NOT_LOCKED; + for (i=0; icontext.server, &brl->server)) { /* found it - delete it */ if (count == 1) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } + status = rec->delete_rec(rec); } else { if (i < count-1) { memmove(&locks[i], &locks[i+1], @@ -568,24 +551,13 @@ static NTSTATUS brl_tdb_remove_pending(struct brl_context *brl, } count--; dbuf.dsize = count * sizeof(*locks); - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - goto fail; - } - } - - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); - return NT_STATUS_OK; + status = rec->store(rec, dbuf, TDB_REPLACE); + } + break; } } - - /* we didn't find it */ - status = NT_STATUS_RANGE_NOT_LOCKED; - fail: - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); + talloc_free(rec); return status; } @@ -602,12 +574,12 @@ static NTSTATUS brl_tdb_locktest(struct brl_context *brl, TDB_DATA kbuf, dbuf; int count, i; struct lock_struct lock, *locks; + NTSTATUS status; kbuf.dptr = brlh->key.data; kbuf.dsize = brlh->key.length; - dbuf = tdb_fetch(brl->w->tdb, kbuf); - if (dbuf.dptr == NULL) { + if (brl->db->fetch(brl->db, brl, kbuf, &dbuf) != 0) { return NT_STATUS_OK; } @@ -623,15 +595,17 @@ static NTSTATUS brl_tdb_locktest(struct brl_context *brl, locks = (struct lock_struct *)dbuf.dptr; count = dbuf.dsize / sizeof(*locks); + status = NT_STATUS_OK; + for (i=0; ikey.data; kbuf.dsize = brlh->key.length; - if (tdb_chainlock(brl->w->tdb, kbuf) != 0) { + rec = brl->db->fetch_locked(brl->db, brl, kbuf); + if (rec == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } - dbuf = tdb_fetch(brl->w->tdb, kbuf); + dbuf = rec->value; if (!dbuf.dptr) { - tdb_chainunlock(brl->w->tdb, kbuf); + talloc_free(rec); return NT_STATUS_OK; } @@ -683,9 +659,7 @@ static NTSTATUS brl_tdb_close(struct brl_context *brl, status = NT_STATUS_OK; if (count == 0) { - if (tdb_delete(brl->w->tdb, kbuf) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } + status = rec->delete_rec(rec); } else if (dcount != 0) { /* tell all pending lock holders for this file that they have a chance now. This is a bit indiscriminant, @@ -694,13 +668,10 @@ static NTSTATUS brl_tdb_close(struct brl_context *brl, dbuf.dsize = count * sizeof(*locks); - if (tdb_store(brl->w->tdb, kbuf, dbuf, TDB_REPLACE) != 0) { - status = NT_STATUS_INTERNAL_DB_CORRUPTION; - } + status = rec->store(rec, dbuf, TDB_REPLACE); } - free(dbuf.dptr); - tdb_chainunlock(brl->w->tdb, kbuf); + talloc_free(rec); return status; } diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 5c744f9c90..2fc0942ed4 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -9,7 +9,7 @@ OBJ_FILES = \ opendb.o \ opendb_tdb.o \ notify.o -PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share +PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ -- cgit From 10d8f0086ba950de206f74cbdf062caeee913fde Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2007 02:35:46 +0000 Subject: r24641: fixed several memory leaks in the brlock code (This used to be commit aa0a3489646ee0ce9d69e4c57c60f83e4894c8a3) --- source4/ntvfs/posix/pvfs_lock.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index bf17ceb83b..989e3c56a4 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -155,6 +155,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas if (timed_out) { /* no more chances */ pvfs_lock_async_failed(pvfs, req, f, locks, pending->pending_lock, status); + talloc_free(pending); } else { /* we can try again */ DLIST_ADD(f->pending_list, pending); @@ -192,6 +193,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas pending); if (pending->wait_handle == NULL) { pvfs_lock_async_failed(pvfs, req, f, locks, i, NT_STATUS_NO_MEMORY); + talloc_free(pending); } else { talloc_steal(pending, pending->wait_handle); DLIST_ADD(f->pending_list, pending); @@ -199,6 +201,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas return; } pvfs_lock_async_failed(pvfs, req, f, locks, i, status); + talloc_free(pending); return; } @@ -208,6 +211,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas /* we've managed to get all the locks. Tell the client */ req->async_states->status = NT_STATUS_OK; req->async_states->send_fn(req); + talloc_free(pending); } @@ -323,17 +327,20 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, } if (lck->lockx.in.mode & LOCKING_ANDX_CANCEL_LOCK) { + talloc_free(pending); return pvfs_lock_cancel(pvfs, req, lck, f); } if (lck->lockx.in.mode & LOCKING_ANDX_CHANGE_LOCKTYPE) { /* this seems to not be supported by any windows server, or used by any clients */ + talloc_free(pending); return NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks); } if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) { DEBUG(0,("received unexpected oplock break\n")); + talloc_free(pending); return NT_STATUS_NOT_IMPLEMENTED; } @@ -348,6 +355,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, locks[i].offset, locks[i].count); if (!NT_STATUS_IS_OK(status)) { + talloc_free(pending); return status; } f->lock_count--; @@ -375,6 +383,7 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, pvfs_pending_lock_continue, pending); if (pending->wait_handle == NULL) { + talloc_free(pending); return NT_STATUS_NO_MEMORY; } talloc_steal(pending, pending->wait_handle); @@ -394,10 +403,12 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, locks[i].count); f->lock_count--; } + talloc_free(pending); return status; } f->lock_count++; } + talloc_free(pending); return NT_STATUS_OK; } -- cgit From fe5124e38d8fbc271a3b5553f54dd6ecd33cf7c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2007 02:37:38 +0000 Subject: r24642: prevent recursion with fetch_locked add a note about server_id exists checking (This used to be commit dd951b983c0cde2dd54c5370dc8d6440509b0559) --- source4/ntvfs/common/brlock_tdb.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 25a0a040a5..0bca9d2590 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -135,9 +135,12 @@ static BOOL brl_tdb_same_context(struct lock_context *ctx1, struct lock_context /* see if lck1 and lck2 overlap + + lck1 is the existing lock. lck2 is the new lock we are + looking at adding */ static BOOL brl_tdb_overlap(struct lock_struct *lck1, - struct lock_struct *lck2) + struct lock_struct *lck2) { /* this extra check is not redundent - it copes with locks that go beyond the end of 64 bit file space */ @@ -151,6 +154,15 @@ static BOOL brl_tdb_overlap(struct lock_struct *lck1, lck2->start >= (lck1->start+lck1->size)) { return False; } + + /* we have a conflict. Now check to see if lck1 really still + * exists, which involves checking if the process still + * exists. We leave this test to last as its the most + * expensive test, especially when we are clustered */ + /* TODO: need to do this via a server_id_exists() call, which + * hasn't been written yet. When clustered this will need to + * call into ctdb */ + return True; } @@ -283,14 +295,6 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, NTSTATUS status; struct db_record *rec = NULL; - kbuf.dptr = brlh->key.data; - kbuf.dsize = brlh->key.length; - - rec = brl->db->fetch_locked(brl->db, brl, kbuf); - if (rec == NULL) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - /* if this is a pending lock, then with the chainlock held we try to get the real lock. If we succeed then we don't need to make it pending. This prevents a possible race condition @@ -305,11 +309,19 @@ static NTSTATUS brl_tdb_lock(struct brl_context *brl, brlh->last_lock = lock; if (NT_STATUS_IS_OK(status)) { - talloc_free(rec); return NT_STATUS_OK; } } + kbuf.dptr = brlh->key.data; + kbuf.dsize = brlh->key.length; + + rec = brl->db->fetch_locked(brl->db, brl, kbuf); + if (rec == NULL) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + dbuf = rec->value; lock.context.smbpid = smbpid; -- cgit From 3b3bfed2c3964a6c5e8299d0a7871f412e03fa67 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2007 03:40:40 +0000 Subject: r24646: fixed the handling of case insensitive paths with wildcards (This used to be commit 066bcd8420045f095130674e32bdee97cb1471be) --- source4/ntvfs/posix/pvfs_resolve.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 94fa0263ad..fae5ec432c 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -480,8 +480,40 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return status; } - /* if it has a wildcard then no point doing a stat() */ + /* if it has a wildcard then no point doing a stat() of the + full name. Instead We need check if the directory exists + */ if ((*name)->has_wildcard) { + const char *p; + char *dir_name, *saved_name; + p = strrchr((*name)->full_name, '/'); + if (p == NULL) { + /* root directory wildcard is OK */ + return NT_STATUS_OK; + } + dir_name = talloc_strndup(*name, (*name)->full_name, (p-(*name)->full_name)); + if (stat(dir_name, &(*name)->st) == 0) { + talloc_free(dir_name); + return NT_STATUS_OK; + } + /* we need to search for a matching name */ + saved_name = (*name)->full_name; + (*name)->full_name = dir_name; + status = pvfs_case_search(pvfs, *name); + if (!NT_STATUS_IS_OK(status)) { + /* the directory doesn't exist */ + (*name)->full_name = saved_name; + return status; + } + /* it does exist, but might need a case change */ + if (dir_name != (*name)->full_name) { + (*name)->full_name = talloc_asprintf(*name, "%s%s", + (*name)->full_name, p); + NT_STATUS_HAVE_NO_MEMORY((*name)->full_name); + } else { + (*name)->full_name = saved_name; + talloc_free(dir_name); + } return NT_STATUS_OK; } -- cgit From 61ffa08f4c95e29d301de9fbabd6e71c2dbc1056 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 27 Aug 2007 18:10:19 +0000 Subject: r24712: No longer expose the 'BOOL' data type in any interfaces. (This used to be commit 1ce32673d960c8b05b6c1b1b99e1976a402417ae) --- source4/ntvfs/common/opendb.h | 6 +++--- source4/ntvfs/ntvfs.h | 4 ++-- source4/ntvfs/posix/vfs_posix.h | 12 ++++++------ 3 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 835fb19046..231ae3d7de 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -26,16 +26,16 @@ struct opendb_ops { struct odb_context *odb, DATA_BLOB *file_key); NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle, uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, BOOL delete_on_close, + uint32_t access_mask, bool delete_on_close, const char *path, uint32_t oplock_level, uint32_t *oplock_granted); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle); NTSTATUS (*odb_remove_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path); - NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, BOOL del_on_close); + NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close); NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, - DATA_BLOB *key, BOOL *del_on_close, + DATA_BLOB *key, bool *del_on_close, int *open_count, char **path); NTSTATUS (*odb_can_open)(struct odb_lock *lck, uint32_t share_access, uint32_t create_options, diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 12a4b3a4df..9ac6f85321 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -91,11 +91,11 @@ struct ntvfs_ops { NTSTATUS (*search_first)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, const union smb_search_data *file)); + bool (*callback)(void *private, const union smb_search_data *file)); NTSTATUS (*search_next)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, const union smb_search_data *file)); + bool (*callback)(void *private, const union smb_search_data *file)); NTSTATUS (*search_close)(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io); diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index b08110915b..dcf082fd88 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -118,9 +118,9 @@ struct pvfs_filename { char *full_name; const char *stream_name; /* does not include :$DATA suffix */ uint32_t stream_id; /* this uses a hash, so is probabilistic */ - BOOL has_wildcard; - BOOL exists; /* true if the base filename exists */ - BOOL stream_exists; /* true if the stream exists */ + bool has_wildcard; + bool exists; /* true if the base filename exists */ + bool stream_exists; /* true if the stream exists */ struct stat st; struct pvfs_dos_fileinfo dos; }; @@ -150,16 +150,16 @@ struct pvfs_file_handle { uint64_t seek_offset; uint64_t position; - BOOL have_opendb_entry; + bool have_opendb_entry; /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; /* have we set a sticky write time that we should remove on close */ - BOOL sticky_write_time; + bool sticky_write_time; /* the open went through to completion */ - BOOL open_completed; + bool open_completed; }; /* open file state */ -- cgit From 8d182d881d189e9855165b3a423f2d545a97fae8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 31 Aug 2007 00:31:32 +0000 Subject: r24816: Move the rest of the contents of core.h to more appropriate places. include/ now only contains build system related headers, all other headers are now near the source code they're related to. (This used to be commit 6890a01dbfc6d8041a88ef5c6be52dfcd046fe80) --- source4/ntvfs/common/brlock.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.h b/source4/ntvfs/common/brlock.h index 5a040dc234..50f30ec276 100644 --- a/source4/ntvfs/common/brlock.h +++ b/source4/ntvfs/common/brlock.h @@ -19,6 +19,8 @@ along with this program. If not, see . */ +#include "libcli/libcli.h" + struct brlock_ops { struct brl_context *(*brl_init)(TALLOC_CTX *, struct server_id , struct messaging_context *); -- cgit From ffeee68e4b72dd94fee57366bd8d38b8c284c3d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 12:42:09 +0000 Subject: r25026: Move param/param.h out of includes.h (This used to be commit abe8349f9b4387961ff3665d8c589d61cd2edf31) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + source4/ntvfs/common/opendb.c | 1 + source4/ntvfs/common/opendb_tdb.c | 1 + source4/ntvfs/ntvfs_base.c | 1 + source4/ntvfs/posix/pvfs_shortname.c | 1 + source4/ntvfs/print/vfs_print.c | 1 + source4/ntvfs/sysdep/inotify.c | 1 + source4/ntvfs/sysdep/sys_notify.c | 1 + 8 files changed, 8 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 4c079b36fc..d248bd7552 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -31,6 +31,7 @@ #include "auth/credentials/credentials.h" #include "ntvfs/ntvfs.h" #include "lib/util/dlinklist.h" +#include "param/param.h" struct cvfs_file { struct cvfs_file *prev, *next; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 69282dd12e..63c6abd3de 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -41,6 +41,7 @@ #include "ntvfs/ntvfs.h" #include "ntvfs/common/ntvfs_common.h" #include "cluster/cluster.h" +#include "param/param.h" static const struct opendb_ops *ops; diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 0bfe6e4eb3..0a79b79125 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -47,6 +47,7 @@ #include "ntvfs/ntvfs.h" #include "ntvfs/common/ntvfs_common.h" #include "cluster/cluster.h" +#include "param/param.h" struct odb_context { struct tdb_wrap *w; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 03c5aff01c..39e4ca73ea 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -26,6 +26,7 @@ #include "lib/util/dlinklist.h" #include "build.h" #include "ntvfs/ntvfs.h" +#include "param/param.h" /* the list of currently registered NTVFS backends, note that there * can be more than one backend with the same name, as long as they diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 5df4a57f9c..75e474a94e 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -22,6 +22,7 @@ #include "includes.h" #include "system/locale.h" #include "vfs_posix.h" +#include "param/param.h" /* this mangling scheme uses the following format diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 30bb530ee9..120f88373c 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -24,6 +24,7 @@ #include "includes.h" #include "libcli/raw/ioctl.h" #include "ntvfs/ntvfs.h" +#include "param/param.h" /* connect to a share - used when a tree_connect operation comes diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index afeb319b35..6fab1018ca 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -27,6 +27,7 @@ #include "lib/events/events.h" #include "lib/util/dlinklist.h" #include "libcli/raw/smb.h" +#include "param/param.h" #include #include diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 8d2aed7fa0..53ac7faa7e 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -27,6 +27,7 @@ #include "ntvfs/sysdep/sys_notify.h" #include "lib/events/events.h" #include "lib/util/dlinklist.h" +#include "param/param.h" #include "build.h" /* list of registered backends */ -- cgit From 98b57d5eb61094a9c88e2f7d90d3e21b7e74e9d8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Sep 2007 16:46:30 +0000 Subject: r25035: Fix some more warnings, use service pointer rather than service number in more places. (This used to be commit df9cebcb97e20564359097148665bd519f31bc6f) --- source4/ntvfs/common/opendb.c | 2 +- source4/ntvfs/common/opendb_tdb.c | 2 +- source4/ntvfs/posix/pvfs_shortname.c | 4 ++-- source4/ntvfs/sysdep/inotify.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 63c6abd3de..1b1573bc96 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -62,7 +62,7 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, struct ntvfs_context *ntvfs_ctx) { if (ops == NULL) { - if (lp_parm_bool(-1, "ctdb", "opendb", False)) { + if (lp_parm_bool(NULL, "ctdb", "opendb", false)) { odb_ctdb_init_ops(); } else { odb_tdb_init_ops(); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 0a79b79125..7c6e9f48b3 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -88,7 +88,7 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, odb->ntvfs_ctx = ntvfs_ctx; /* leave oplocks disabled by default until the code is working */ - odb->oplocks = lp_parm_bool(-1, "opendb", "oplocks", False); + odb->oplocks = lp_parm_bool(NULL, "opendb", "oplocks", false); return odb; } diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 75e474a94e..9e02125dc7 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -614,7 +614,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) } /* by default have a max of 512 entries in the cache. */ - ctx->cache_size = lp_parm_int(-1, "mangle", "cachesize", 512); + ctx->cache_size = lp_parm_int(NULL, "mangle", "cachesize", 512); ctx->prefix_cache = talloc_array(ctx, char *, ctx->cache_size); if (ctx->prefix_cache == NULL) { @@ -628,7 +628,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) memset(ctx->prefix_cache, 0, sizeof(char *) * ctx->cache_size); memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t) * ctx->cache_size); - ctx->mangle_prefix = lp_parm_int(-1, "mangle", "prefix", -1); + ctx->mangle_prefix = lp_parm_int(NULL, "mangle", "prefix", -1); if (ctx->mangle_prefix < 0 || ctx->mangle_prefix > 6) { ctx->mangle_prefix = DEFAULT_MANGLE_PREFIX; } diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 6fab1018ca..b73ee2c526 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -245,7 +245,7 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) { struct inotify_private *in; - if (!lp_parm_bool(-1, "notify", "inotify", True)) { + if (!lp_parm_bool(NULL, "notify", "inotify", true)) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } -- cgit From 37d53832a4623653f706e77985a79d84bd7c6694 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Sep 2007 01:17:46 +0000 Subject: r25398: Parse loadparm context to all lp_*() functions. (This used to be commit 3fcc960839c6e5ca4de2c3c042f12f369ac5f238) --- source4/ntvfs/cifs/vfs_cifs.c | 6 +++--- source4/ntvfs/print/vfs_print.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index d248bd7552..ed7065b3bd 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -166,7 +166,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); - cli_credentials_set_conf(credentials); + cli_credentials_set_conf(credentials, global_loadparm); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); @@ -176,7 +176,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, DEBUG(5, ("CIFS backend: Using machine account\n")); credentials = cli_credentials_init(private); cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); - cli_credentials_set_conf(credentials); + cli_credentials_set_conf(credentials, global_loadparm); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } @@ -198,7 +198,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.called_name = host; io.in.credentials = credentials; io.in.fallback_to_anonymous = False; - io.in.workgroup = lp_workgroup(); + io.in.workgroup = lp_workgroup(global_loadparm); io.in.service = remote_share; io.in.service_type = "?????"; diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 120f88373c..f9d3235116 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -83,7 +83,7 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); - push_string(p+2, lp_netbios_name(), 15, STR_TERMINATE|STR_ASCII); + push_string(p+2, lp_netbios_name(global_loadparm), 15, STR_TERMINATE|STR_ASCII); push_string(p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } -- cgit From 60a1046c5c5783799bd64fe18e03534670f83d82 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Sep 2007 18:00:19 +0000 Subject: r25430: Add the loadparm context to all parametric options. (This used to be commit fd697d77c9fe67a00939a1f04b35c451316fff58) --- source4/ntvfs/common/opendb.c | 2 +- source4/ntvfs/common/opendb_tdb.c | 2 +- source4/ntvfs/posix/pvfs_shortname.c | 4 ++-- source4/ntvfs/sysdep/inotify.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 1b1573bc96..112de1d7d4 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -62,7 +62,7 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, struct ntvfs_context *ntvfs_ctx) { if (ops == NULL) { - if (lp_parm_bool(NULL, "ctdb", "opendb", false)) { + if (lp_parm_bool(global_loadparm, NULL, "ctdb", "opendb", false)) { odb_ctdb_init_ops(); } else { odb_tdb_init_ops(); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 7c6e9f48b3..60ab11b96a 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -88,7 +88,7 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, odb->ntvfs_ctx = ntvfs_ctx; /* leave oplocks disabled by default until the code is working */ - odb->oplocks = lp_parm_bool(NULL, "opendb", "oplocks", false); + odb->oplocks = lp_parm_bool(global_loadparm, NULL, "opendb", "oplocks", false); return odb; } diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 9e02125dc7..141f5a30a1 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -614,7 +614,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) } /* by default have a max of 512 entries in the cache. */ - ctx->cache_size = lp_parm_int(NULL, "mangle", "cachesize", 512); + ctx->cache_size = lp_parm_int(global_loadparm, NULL, "mangle", "cachesize", 512); ctx->prefix_cache = talloc_array(ctx, char *, ctx->cache_size); if (ctx->prefix_cache == NULL) { @@ -628,7 +628,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) memset(ctx->prefix_cache, 0, sizeof(char *) * ctx->cache_size); memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t) * ctx->cache_size); - ctx->mangle_prefix = lp_parm_int(NULL, "mangle", "prefix", -1); + ctx->mangle_prefix = lp_parm_int(global_loadparm, NULL, "mangle", "prefix", -1); if (ctx->mangle_prefix < 0 || ctx->mangle_prefix > 6) { ctx->mangle_prefix = DEFAULT_MANGLE_PREFIX; } diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index b73ee2c526..191212580b 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -245,7 +245,7 @@ static NTSTATUS inotify_setup(struct sys_notify_context *ctx) { struct inotify_private *in; - if (!lp_parm_bool(NULL, "notify", "inotify", true)) { + if (!lp_parm_bool(global_loadparm, NULL, "notify", "inotify", true)) { return NT_STATUS_INVALID_SYSTEM_SERVICE; } -- cgit From 2f3551ca7cee59d4d053cceb87abdf1da1b3a1ad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 1 Oct 2007 18:52:55 +0000 Subject: r25446: Merge some changes I made on the way home from SFO: 2007-09-29 More higher-level passing around of lp_ctx. 2007-09-29 Fix warning. 2007-09-29 Pass loadparm contexts on a higher level. 2007-09-29 Avoid using global loadparm context. (This used to be commit 3468952e771ab31f90b6c374ade01c5550810f42) --- source4/ntvfs/ntvfs_base.c | 2 +- source4/ntvfs/sysdep/sys_notify.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 39e4ca73ea..c837e5898b 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -200,7 +200,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(void) { init_module_fn static_init[] = STATIC_ntvfs_MODULES; - init_module_fn *shared_init = load_samba_modules(NULL, "ntvfs"); + init_module_fn *shared_init = load_samba_modules(NULL, global_loadparm, "ntvfs"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 53ac7faa7e..a13d02c12e 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -131,7 +131,7 @@ _PUBLIC_ NTSTATUS sys_notify_init(void) if (initialized) return NT_STATUS_OK; initialized = True; - shared_init = load_samba_modules(NULL, "sys_notify"); + shared_init = load_samba_modules(NULL, global_loadparm, "sys_notify"); run_init_functions(static_init); run_init_functions(shared_init); -- cgit From 2151cde58014ea2e822c13d2f8a369b45dc19ca8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 6 Oct 2007 22:28:14 +0000 Subject: r25554: Convert last instances of BOOL, True and False to the standard types. (This used to be commit 566aa14139510788548a874e9213d91317f83ca9) --- source4/ntvfs/cifs/vfs_cifs.c | 26 +++++------ source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c | 8 ++-- source4/ntvfs/common/brlock_tdb.c | 26 +++++------ source4/ntvfs/common/notify.c | 4 +- source4/ntvfs/common/opendb.c | 6 +-- source4/ntvfs/common/opendb_tdb.c | 16 +++---- source4/ntvfs/ipc/vfs_ipc.c | 4 +- source4/ntvfs/nbench/vfs_nbench.c | 4 +- source4/ntvfs/ntvfs_base.c | 18 ++++---- source4/ntvfs/ntvfs_generic.c | 10 ++--- source4/ntvfs/ntvfs_interface.c | 8 ++-- source4/ntvfs/ntvfs_util.c | 2 +- source4/ntvfs/posix/pvfs_acl.c | 22 ++++----- source4/ntvfs/posix/pvfs_dirlist.c | 38 ++++++++-------- source4/ntvfs/posix/pvfs_lock.c | 4 +- source4/ntvfs/posix/pvfs_notify.c | 14 +++--- source4/ntvfs/posix/pvfs_open.c | 60 ++++++++++++------------- source4/ntvfs/posix/pvfs_resolve.c | 28 ++++++------ source4/ntvfs/posix/pvfs_search.c | 18 ++++---- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_shortname.c | 64 +++++++++++++-------------- source4/ntvfs/posix/pvfs_streams.c | 6 +-- source4/ntvfs/posix/pvfs_util.c | 8 ++-- source4/ntvfs/posix/pvfs_xattr.c | 4 +- source4/ntvfs/posix/vfs_posix.c | 4 +- source4/ntvfs/posix/vfs_posix.h | 4 +- source4/ntvfs/simple/vfs_simple.c | 8 ++-- source4/ntvfs/sysdep/inotify.c | 14 +++--- source4/ntvfs/sysdep/sys_notify.c | 4 +- source4/ntvfs/unixuid/vfs_unixuid.c | 4 +- 30 files changed, 219 insertions(+), 219 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index ed7065b3bd..cd4e363906 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -46,8 +46,8 @@ struct cvfs_private { struct ntvfs_module_context *ntvfs; struct async_info *pending; struct cvfs_file *files; - BOOL map_generic; - BOOL map_trans2; + bool map_generic; + bool map_trans2; }; @@ -84,15 +84,15 @@ struct async_info { #define CIFS_MAP_GENERIC "cifs:map-generic" #define CIFS_MAP_TRANS2 "cifs:map-trans2" -#define CIFS_USE_MACHINE_ACCT_DEFAULT False -#define CIFS_MAP_GENERIC_DEFAULT False -#define CIFS_MAP_TRANS2_DEFAULT True +#define CIFS_USE_MACHINE_ACCT_DEFAULT false +#define CIFS_MAP_GENERIC_DEFAULT false +#define CIFS_MAP_TRANS2_DEFAULT true /* a handler for oplock break events from the server - these need to be passed along to the client */ -static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) +static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) { struct cvfs_private *private = p_private; NTSTATUS status; @@ -107,13 +107,13 @@ static BOOL oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin if (!h) { DEBUG(5,("vfs_cifs: ignoring oplock break level %d for fnum %d\n", level, fnum)); - return True; + return true; } DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); status = ntvfs_send_oplock_break(private->ntvfs, h, level); - if (!NT_STATUS_IS_OK(status)) return False; - return True; + if (!NT_STATUS_IS_OK(status)) return false; + return true; } /* @@ -130,7 +130,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct share_config *scfg = ntvfs->ctx->config; struct cli_credentials *credentials; - BOOL machine_account; + bool machine_account; /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. @@ -197,7 +197,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.port = 0; io.in.called_name = host; io.in.credentials = credentials; - io.in.fallback_to_anonymous = False; + io.in.fallback_to_anonymous = false; io.in.workgroup = lp_workgroup(global_loadparm); io.in.service = remote_share; io.in.service_type = "?????"; @@ -922,7 +922,7 @@ static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct cvfs_private *private = ntvfs->private_data; @@ -935,7 +935,7 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct cvfs_private *private = ntvfs->private_data; diff --git a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c index 088d1644d3..a61ac16669 100644 --- a/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c +++ b/source4/ntvfs/cifs_posix_cli/vfs_cifs_posix.c @@ -39,7 +39,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, true)) return NT_STATUS_ACCESS_DENIED; } while (0) /* connect to a share - used when a tree_connect operation comes @@ -311,7 +311,7 @@ static NTSTATUS cifspsx_open(struct ntvfs_module_context *ntvfs, int fd, flags; struct cifspsx_file *f; int create_flags, rdwr_flags; - BOOL readonly; + bool readonly; NTSTATUS status; struct ntvfs_handle *handle; @@ -829,7 +829,7 @@ static NTSTATUS cifspsx_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS cifspsx_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct cifspsx_dir *dir; int i; @@ -903,7 +903,7 @@ static NTSTATUS cifspsx_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS cifspsx_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct cifspsx_dir *dir; int i; diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 0bca9d2590..2b81521a2c 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -126,7 +126,7 @@ static struct brl_handle *brl_tdb_create_handle(TALLOC_CTX *mem_ctx, struct ntvf /* see if two locking contexts are equal */ -static BOOL brl_tdb_same_context(struct lock_context *ctx1, struct lock_context *ctx2) +static bool brl_tdb_same_context(struct lock_context *ctx1, struct lock_context *ctx2) { return (cluster_id_equal(&ctx1->server, &ctx2->server) && ctx1->smbpid == ctx2->smbpid && @@ -139,7 +139,7 @@ static BOOL brl_tdb_same_context(struct lock_context *ctx1, struct lock_context lck1 is the existing lock. lck2 is the new lock we are looking at adding */ -static BOOL brl_tdb_overlap(struct lock_struct *lck1, +static bool brl_tdb_overlap(struct lock_struct *lck1, struct lock_struct *lck2) { /* this extra check is not redundent - it copes with locks @@ -147,12 +147,12 @@ static BOOL brl_tdb_overlap(struct lock_struct *lck1, if (lck1->size != 0 && lck1->start == lck2->start && lck1->size == lck2->size) { - return True; + return true; } if (lck1->start >= (lck2->start+lck2->size) || lck2->start >= (lck1->start+lck1->size)) { - return False; + return false; } /* we have a conflict. Now check to see if lck1 really still @@ -163,28 +163,28 @@ static BOOL brl_tdb_overlap(struct lock_struct *lck1, * hasn't been written yet. When clustered this will need to * call into ctdb */ - return True; + return true; } /* See if lock2 can be added when lock1 is in place. */ -static BOOL brl_tdb_conflict(struct lock_struct *lck1, +static bool brl_tdb_conflict(struct lock_struct *lck1, struct lock_struct *lck2) { /* pending locks don't conflict with anything */ if (lck1->lock_type >= PENDING_READ_LOCK || lck2->lock_type >= PENDING_READ_LOCK) { - return False; + return false; } if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) { - return False; + return false; } if (brl_tdb_same_context(&lck1->context, &lck2->context) && lck2->lock_type == READ_LOCK && lck1->ntvfs == lck2->ntvfs) { - return False; + return false; } return brl_tdb_overlap(lck1, lck2); @@ -195,16 +195,16 @@ static BOOL brl_tdb_conflict(struct lock_struct *lck1, Check to see if this lock conflicts, but ignore our own locks on the same fnum only. */ -static BOOL brl_tdb_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) +static bool brl_tdb_conflict_other(struct lock_struct *lck1, struct lock_struct *lck2) { /* pending locks don't conflict with anything */ if (lck1->lock_type >= PENDING_READ_LOCK || lck2->lock_type >= PENDING_READ_LOCK) { - return False; + return false; } if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK) - return False; + return false; /* * note that incoming write calls conflict with existing READ @@ -214,7 +214,7 @@ static BOOL brl_tdb_conflict_other(struct lock_struct *lck1, struct lock_struct if (brl_tdb_same_context(&lck1->context, &lck2->context) && lck1->ntvfs == lck2->ntvfs && (lck2->lock_type == READ_LOCK || lck1->lock_type == WRITE_LOCK)) { - return False; + return false; } return brl_tdb_overlap(lck1, lck2); diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 0d36a20a60..0214c39b2d 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -58,7 +58,7 @@ struct notify_list { #define NOTIFY_KEY "notify array" #define NOTIFY_ENABLE "notify:enable" -#define NOTIFY_ENABLE_DEFAULT True +#define NOTIFY_ENABLE_DEFAULT true static NTSTATUS notify_remove_all(struct notify_context *notify); static void notify_handler(struct messaging_context *msg_ctx, void *private_data, @@ -86,7 +86,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, { struct notify_context *notify; - if (share_bool_option(scfg, NOTIFY_ENABLE, NOTIFY_ENABLE_DEFAULT) != True) { + if (share_bool_option(scfg, NOTIFY_ENABLE, NOTIFY_ENABLE_DEFAULT) != true) { return NULL; } diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 112de1d7d4..59990d2fc1 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -91,7 +91,7 @@ _PUBLIC_ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, */ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, BOOL delete_on_close, + uint32_t access_mask, bool delete_on_close, const char *path, uint32_t oplock_level, uint32_t *oplock_granted) { @@ -139,7 +139,7 @@ _PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) /* update delete on close flag on an open file */ -_PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) +_PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_close) { return ops->odb_set_delete_on_close(lck, del_on_close); } @@ -149,7 +149,7 @@ _PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_clos people still have the file open */ _PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, - DATA_BLOB *key, BOOL *del_on_close, + DATA_BLOB *key, bool *del_on_close, int *open_count, char **path) { return ops->odb_get_delete_on_close(odb, key, del_on_close, open_count, path); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 60ab11b96a..a037e7e47e 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -52,7 +52,7 @@ struct odb_context { struct tdb_wrap *w; struct ntvfs_context *ntvfs_ctx; - BOOL oplocks; + bool oplocks; }; /* @@ -266,7 +266,7 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_ent */ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, BOOL delete_on_close, + uint32_t access_mask, bool delete_on_close, const char *path, uint32_t oplock_level, uint32_t *oplock_granted) { @@ -276,7 +276,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, struct opendb_file file; NTSTATUS status; - if (odb->oplocks == False) { + if (odb->oplocks == false) { oplock_level = OPLOCK_NONE; } @@ -407,7 +407,7 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle) if (file_handle == file.entries[i].file_handle && cluster_id_equal(&odb->ntvfs_ctx->server_id, &file.entries[i].server)) { if (file.entries[i].delete_on_close) { - file.delete_on_close = True; + file.delete_on_close = true; } if (i < file.num_entries-1) { memmove(file.entries+i, file.entries+i+1, @@ -494,7 +494,7 @@ static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path) /* update delete on close flag on an open file */ -static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_close) +static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_close) { NTSTATUS status; struct opendb_file file; @@ -512,7 +512,7 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, BOOL del_on_cl people still have the file open */ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, - DATA_BLOB *key, BOOL *del_on_close, + DATA_BLOB *key, bool *del_on_close, int *open_count, char **path) { NTSTATUS status; @@ -525,7 +525,7 @@ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, status = odb_pull_record(lck, &file); if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { talloc_free(lck); - (*del_on_close) = False; + (*del_on_close) = false; return NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { @@ -541,7 +541,7 @@ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, *path = talloc_strdup(odb, file.path); NT_STATUS_HAVE_NO_MEMORY(*path); if (file.num_entries == 1 && file.entries[0].delete_on_close) { - (*del_on_close) = True; + (*del_on_close) = true; } } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index fbac82a305..fc3c74ca6c 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -669,7 +669,7 @@ static NTSTATUS ipc_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS ipc_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { return NT_STATUS_ACCESS_DENIED; } @@ -680,7 +680,7 @@ static NTSTATUS ipc_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS ipc_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index 9379419c50..987227a0b7 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -841,7 +841,7 @@ static void nbench_search_first_send(struct ntvfs_request *req) static NTSTATUS nbench_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; @@ -863,7 +863,7 @@ static void nbench_search_next_send(struct ntvfs_request *req) static NTSTATUS nbench_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index c837e5898b..20197a4ba9 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -113,7 +113,7 @@ _PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) return &critical_sizes; } -_PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) +_PUBLIC_ bool ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) { /* The comparison would be easier with memcmp, but compiler-interset * alignment padding is not guaranteed to be zeroed. @@ -122,28 +122,28 @@ _PUBLIC_ BOOL ntvfs_interface_differs(const struct ntvfs_critical_sizes *const i #define FIELD_DIFFERS(field) (iface->field != critical_sizes.field) if (FIELD_DIFFERS(interface_version)) - return True; + return true; if (FIELD_DIFFERS(sizeof_ntvfs_critical_sizes)) - return True; + return true; if (FIELD_DIFFERS(sizeof_ntvfs_context)) - return True; + return true; if (FIELD_DIFFERS(sizeof_ntvfs_module_context)) - return True; + return true; if (FIELD_DIFFERS(sizeof_ntvfs_ops)) - return True; + return true; if (FIELD_DIFFERS(sizeof_ntvfs_async_state)) - return True; + return true; if (FIELD_DIFFERS(sizeof_ntvfs_request)) - return True; + return true; /* Versions match. */ - return False; + return false; #undef FIELD_DIFFERS } diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 8ed99ce3f1..7708f4fc80 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -116,21 +116,21 @@ static NTSTATUS ntvfs_map_async_finish(struct ntvfs_request *req, NTSTATUS statu see if a filename ends in EXE COM DLL or SYM. This is needed for the DENY_DOS mapping for OpenX */ -BOOL is_exe_filename(const char *fname) +bool is_exe_filename(const char *fname) { char *p; p = strrchr(fname, '.'); if (!p) { - return False; + return false; } p++; if (strcasecmp(p, "EXE") == 0 || strcasecmp(p, "COM") == 0 || strcasecmp(p, "DLL") == 0 || strcasecmp(p, "SYM") == 0) { - return True; + return true; } - return False; + return false; } @@ -1247,7 +1247,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, } rd2->readx.level = RAW_READ_READX; - rd2->readx.in.read_for_execute = False; + rd2->readx.in.read_for_execute = false; switch (rd->generic.level) { case RAW_READ_READX: diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 74fb815359..3bd2859388 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -149,7 +149,7 @@ _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) /* directory search */ _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private, - BOOL ntvfs_callback(void *private, const union smb_search_data *file)) + bool ntvfs_callback(void *private, const union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_first) { @@ -159,7 +159,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search } _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private, - BOOL ntvfs_callback(void *private, const union smb_search_data *file)) + bool ntvfs_callback(void *private, const union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_next) { @@ -469,7 +469,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *private, - BOOL (*callback)(void *private, const union smb_search_data *file)) + bool (*callback)(void *private, const union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_first) { return NT_STATUS_NOT_IMPLEMENTED; @@ -480,7 +480,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, _PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *private, - BOOL (*callback)(void *private, const union smb_search_data *file)) + bool (*callback)(void *private, const union smb_search_data *file)) { if (!ntvfs->next || !ntvfs->next->ops->search_next) { return NT_STATUS_NOT_IMPLEMENTED; diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 3158bdf1fd..7432ac2c13 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -112,7 +112,7 @@ _PUBLIC_ NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h, TALLOC_CTX *private_data) { struct ntvfs_handle_data *d; - BOOL first_time = h->backend_data?False:True; + bool first_time = h->backend_data?false:true; for (d=h->backend_data; d; d = d->next) { if (d->owner != ntvfs) continue; diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 4302b7f890..f19dc1f41f 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -365,7 +365,7 @@ NTSTATUS pvfs_acl_query(struct pvfs_state *pvfs, /* check the read only bit against any of the write access bits */ -static BOOL pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask) +static bool pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask) { if ((pvfs->flags & PVFS_FLAG_READONLY) && (access_mask & (SEC_FILE_WRITE_DATA | @@ -376,9 +376,9 @@ static BOOL pvfs_read_only(struct pvfs_state *pvfs, uint32_t access_mask) SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER | SEC_DIR_DELETE_CHILD))) { - return True; + return true; } - return False; + return false; } /* @@ -548,24 +548,24 @@ NTSTATUS pvfs_access_check_parent(struct pvfs_state *pvfs, /* determine if an ACE is inheritable */ -static BOOL pvfs_inheritable_ace(struct pvfs_state *pvfs, +static bool pvfs_inheritable_ace(struct pvfs_state *pvfs, const struct security_ace *ace, - BOOL container) + bool container) { if (!container) { return (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) != 0; } if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) { - return True; + return true; } if ((ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) && !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) { - return True; + return true; } - return False; + return false; } /* @@ -576,7 +576,7 @@ static BOOL pvfs_inheritable_ace(struct pvfs_state *pvfs, static NTSTATUS pvfs_acl_inherit_aces(struct pvfs_state *pvfs, struct security_descriptor *parent_sd, struct security_descriptor *sd, - BOOL container) + bool container) { int i; @@ -663,7 +663,7 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, NTSTATUS status; struct pvfs_filename *parent; struct security_descriptor *parent_sd, *sd; - BOOL container; + bool container; /* form the parents path */ status = pvfs_resolve_parent(pvfs, req, name, &parent); @@ -716,7 +716,7 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, sd->type |= SEC_DESC_DACL_PRESENT; - container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? True:False; + container = (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) ? true:false; /* fill in the aces from the parent */ status = pvfs_acl_inherit_aces(pvfs, parent_sd, sd, container); diff --git a/source4/ntvfs/posix/pvfs_dirlist.c b/source4/ntvfs/posix/pvfs_dirlist.c index e54cb847f5..77f19c3585 100644 --- a/source4/ntvfs/posix/pvfs_dirlist.c +++ b/source4/ntvfs/posix/pvfs_dirlist.c @@ -33,13 +33,13 @@ struct name_cache_entry { struct pvfs_dir { struct pvfs_state *pvfs; - BOOL no_wildcard; + bool no_wildcard; char *single_name; const char *pattern; off_t offset; DIR *dir; const char *unix_path; - BOOL end_of_search; + bool end_of_search; struct name_cache_entry *name_cache; uint32_t name_cache_index; }; @@ -69,8 +69,8 @@ static NTSTATUS pvfs_list_no_wildcard(struct pvfs_state *pvfs, struct pvfs_filen } dir->pvfs = pvfs; - dir->no_wildcard = True; - dir->end_of_search = False; + dir->no_wildcard = true; + dir->end_of_search = false; dir->unix_path = talloc_strdup(dir, name->full_name); if (!dir->unix_path) { return NT_STATUS_NO_MEMORY; @@ -145,8 +145,8 @@ NTSTATUS pvfs_list_start(struct pvfs_state *pvfs, struct pvfs_filename *name, } dir->pvfs = pvfs; - dir->no_wildcard = False; - dir->end_of_search = False; + dir->no_wildcard = false; + dir->end_of_search = false; dir->offset = DIR_OFFSET_DOT; dir->name_cache = talloc_zero_array(dir, struct name_cache_entry, @@ -187,7 +187,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) /* non-wildcard searches are easy */ if (dir->no_wildcard) { - dir->end_of_search = True; + dir->end_of_search = true; if (*ofs != 0) return NULL; (*ofs)++; return dir->single_name; @@ -246,7 +246,7 @@ const char *pvfs_list_next(struct pvfs_dir *dir, off_t *ofs) return dname; } - dir->end_of_search = True; + dir->end_of_search = true; return NULL; } @@ -259,9 +259,9 @@ const char *pvfs_list_unix_path(struct pvfs_dir *dir) } /* - return True if end of search has been reached + return true if end of search has been reached */ -BOOL pvfs_list_eos(struct pvfs_dir *dir, off_t ofs) +bool pvfs_list_eos(struct pvfs_dir *dir, off_t ofs) { return dir->end_of_search; } @@ -274,7 +274,7 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, off_t *ofs) struct dirent *de; int i; - dir->end_of_search = False; + dir->end_of_search = false; if (ISDOT(name)) { dir->offset = DIR_OFFSET_DOTDOT; @@ -313,7 +313,7 @@ NTSTATUS pvfs_list_seek(struct pvfs_dir *dir, const char *name, off_t *ofs) } } - dir->end_of_search = True; + dir->end_of_search = true; return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -326,7 +326,7 @@ NTSTATUS pvfs_list_seek_ofs(struct pvfs_dir *dir, uint32_t resume_key, off_t *of struct dirent *de; int i; - dir->end_of_search = False; + dir->end_of_search = false; if (resume_key == DIR_OFFSET_DOT) { *ofs = DIR_OFFSET_DOTDOT; @@ -341,7 +341,7 @@ NTSTATUS pvfs_list_seek_ofs(struct pvfs_dir *dir, uint32_t resume_key, off_t *of if (resume_key == DIR_OFFSET_BASE) { rewinddir(dir->dir); if ((de=readdir(dir->dir)) == NULL) { - dir->end_of_search = True; + dir->end_of_search = true; return NT_STATUS_OBJECT_NAME_NOT_FOUND; } *ofs = telldir(dir->dir) + DIR_OFFSET_BASE; @@ -374,7 +374,7 @@ NTSTATUS pvfs_list_seek_ofs(struct pvfs_dir *dir, uint32_t resume_key, off_t *of } } - dir->end_of_search = True; + dir->end_of_search = true; return NT_STATUS_OBJECT_NAME_NOT_FOUND; } @@ -383,21 +383,21 @@ NTSTATUS pvfs_list_seek_ofs(struct pvfs_dir *dir, uint32_t resume_key, off_t *of /* see if a directory is empty */ -BOOL pvfs_directory_empty(struct pvfs_state *pvfs, struct pvfs_filename *name) +bool pvfs_directory_empty(struct pvfs_state *pvfs, struct pvfs_filename *name) { struct dirent *de; DIR *dir = opendir(name->full_name); if (dir == NULL) { - return True; + return true; } while ((de = readdir(dir))) { if (!ISDOT(de->d_name) && !ISDOTDOT(de->d_name)) { closedir(dir); - return False; + return false; } } closedir(dir); - return True; + return true; } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 989e3c56a4..b9bb58c71d 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -104,7 +104,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas enum brl_type rw; NTSTATUS status; int i; - BOOL timed_out; + bool timed_out; timed_out = (reason != PVFS_WAIT_EVENT); @@ -136,7 +136,7 @@ static void pvfs_pending_lock_continue(void *private, enum pvfs_wait_notice reas } if (NT_STATUS_IS_OK(status)) { f->lock_count++; - timed_out = False; + timed_out = false; } /* if we have failed and timed out, or succeeded, then we diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 3e289a0948..210f949395 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -58,7 +58,7 @@ static void pvfs_notify_send_next(struct event_context *ev, struct timed_event * send a reply to a pending notify request */ static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, - NTSTATUS status, BOOL immediate) + NTSTATUS status, bool immediate) { struct notify_pending *pending = notify_buffer->pending; struct ntvfs_request *req; @@ -118,7 +118,7 @@ static int pvfs_notify_destructor(struct pvfs_notify_buffer *n) { notify_remove(n->f->pvfs->notify_context, n); n->f->notify_buffer = NULL; - pvfs_notify_send(n, NT_STATUS_OK, True); + pvfs_notify_send(n, NT_STATUS_OK, true); return 0; } @@ -161,7 +161,7 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) /* send what we have, unless its the first part of a rename */ if (ev->action != NOTIFY_ACTION_OLD_NAME) { - pvfs_notify_send(n, NT_STATUS_OK, True); + pvfs_notify_send(n, NT_STATUS_OK, true); } } @@ -169,7 +169,7 @@ static void pvfs_notify_callback(void *private, const struct notify_event *ev) setup a notify buffer on a directory handle */ static NTSTATUS pvfs_notify_setup(struct pvfs_state *pvfs, struct pvfs_file *f, - uint32_t buffer_size, uint32_t filter, BOOL recursive) + uint32_t buffer_size, uint32_t filter, bool recursive) { NTSTATUS status; struct notify_entry e; @@ -206,9 +206,9 @@ static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason) struct pvfs_notify_buffer *notify_buffer = talloc_get_type(private, struct pvfs_notify_buffer); if (reason == PVFS_WAIT_CANCEL) { - pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED, False); + pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED, false); } else { - pvfs_notify_send(notify_buffer, NT_STATUS_OK, True); + pvfs_notify_send(notify_buffer, NT_STATUS_OK, true); } } @@ -277,7 +277,7 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, } req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; - pvfs_notify_send(f->notify_buffer, NT_STATUS_OK, False); + pvfs_notify_send(f->notify_buffer, NT_STATUS_OK, false); return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 269df13069..8558f0476a 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -186,7 +186,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, uint32_t create_action; uint32_t access_mask = io->generic.in.access_mask; struct odb_lock *lck; - BOOL del_on_close; + bool del_on_close; uint32_t create_options; uint32_t share_access; @@ -268,14 +268,14 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; - f->handle->sticky_write_time = False; - f->handle->open_completed = False; + f->handle->sticky_write_time = false; + f->handle->open_completed = false; if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && pvfs_directory_empty(pvfs, f->handle->name)) { - del_on_close = True; + del_on_close = true; } else { - del_on_close = False; + del_on_close = false; } if (name->exists) { @@ -305,7 +305,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return status; } - f->handle->have_opendb_entry = True; + f->handle->have_opendb_entry = true; } DLIST_ADD(pvfs->files.list, f); @@ -357,7 +357,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, goto cleanup_delete; } - f->handle->have_opendb_entry = True; + f->handle->have_opendb_entry = true; create_action = NTCREATEX_ACTION_CREATED; @@ -379,7 +379,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, goto cleanup_delete; } - f->handle->open_completed = True; + f->handle->open_completed = true; io->generic.out.oplock_level = OPLOCK_NONE; io->generic.out.file.ntvfs = h; @@ -552,7 +552,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t access_mask = io->generic.in.access_mask; mode_t mode; uint32_t attrib; - BOOL del_on_close; + bool del_on_close; struct pvfs_filename *parent; uint32_t oplock_level = OPLOCK_NONE, oplock_granted; @@ -656,9 +656,9 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { - del_on_close = True; + del_on_close = true; } else { - del_on_close = False; + del_on_close = false; } if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { @@ -702,9 +702,9 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; - f->handle->have_opendb_entry = True; - f->handle->sticky_write_time = False; - f->handle->open_completed = False; + f->handle->have_opendb_entry = true; + f->handle->sticky_write_time = false; + f->handle->open_completed = false; DLIST_ADD(pvfs->files.list, f); @@ -733,7 +733,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, goto cleanup_delete; } - f->handle->open_completed = True; + f->handle->open_completed = true; notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, @@ -989,8 +989,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t create_options; uint32_t share_access; uint32_t access_mask; - BOOL del_on_close; - BOOL stream_existed, stream_truncate=False; + bool del_on_close; + bool stream_existed, stream_truncate=false; uint32_t oplock_level = OPLOCK_NONE, oplock_granted; /* use the generic mapping code to avoid implementing all the @@ -1035,7 +1035,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, if (name->stream_name == NULL) { flags = O_TRUNC; } else { - stream_truncate = True; + stream_truncate = true; } break; @@ -1053,7 +1053,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, if (name->stream_name == NULL) { flags = O_TRUNC; } else { - stream_truncate = True; + stream_truncate = true; } break; @@ -1133,9 +1133,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; - f->handle->have_opendb_entry = False; - f->handle->sticky_write_time = False; - f->handle->open_completed = False; + f->handle->have_opendb_entry = false; + f->handle->sticky_write_time = false; + f->handle->open_completed = false; /* form the lock context used for byte range locking and opendb locking */ @@ -1172,9 +1172,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, */ if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE && req->ctx->protocol == PROTOCOL_SMB2) { - del_on_close = True; + del_on_close = true; } else { - del_on_close = False; + del_on_close = false; } if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { @@ -1206,7 +1206,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, oplock_granted = OPLOCK_BATCH; } - f->handle->have_opendb_entry = True; + f->handle->have_opendb_entry = true; if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { flags |= O_RDWR; @@ -1273,7 +1273,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* mark the open as having completed fully, so delete on close can now be used */ - f->handle->open_completed = True; + f->handle->open_completed = true; io->generic.out.oplock_level = oplock_granted; io->generic.out.file.ntvfs = h; @@ -1379,7 +1379,7 @@ NTSTATUS pvfs_exit(struct ntvfs_module_context *ntvfs, */ NTSTATUS pvfs_set_delete_on_close(struct pvfs_state *pvfs, struct ntvfs_request *req, - struct pvfs_file *f, BOOL del_on_close) + struct pvfs_file *f, bool del_on_close) { struct odb_lock *lck; NTSTATUS status; @@ -1532,17 +1532,17 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, /* determine if delete on close is set on */ -BOOL pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h, +bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h, int *open_count, char **path) { NTSTATUS status; - BOOL del_on_close; + bool del_on_close; status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, &del_on_close, open_count, path); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("WARNING: unable to determine delete on close status for open file\n")); - return False; + return false; } return del_on_close; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index fae5ec432c..8a7aa13351 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -121,7 +121,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * talloc_free(partial_name); partial_name = test_name; if (i == num_components - 1) { - name->exists = True; + name->exists = true; } continue; } @@ -166,7 +166,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * if (!name->exists) { if (stat(partial_name, &name->st) == 0) { - name->exists = True; + name->exists = true; } } @@ -229,7 +229,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, name->original_name = talloc_strdup(name, cifs_name); name->stream_name = NULL; name->stream_id = 0; - name->has_wildcard = False; + name->has_wildcard = false; while (*cifs_name == '\\') { cifs_name++; @@ -291,7 +291,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, if (!(flags & PVFS_RESOLVE_WILDCARD)) { return NT_STATUS_OBJECT_NAME_INVALID; } - name->has_wildcard = True; + name->has_wildcard = true; break; case '/': case '|': @@ -456,8 +456,8 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - (*name)->exists = False; - (*name)->stream_exists = False; + (*name)->exists = false; + (*name)->stream_exists = false; if (!(pvfs->fs_attribs & FS_ATTR_NAMED_STREAMS)) { flags &= ~PVFS_RESOLVE_STREAMS; @@ -519,7 +519,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* if we can stat() the full name now then we are done */ if (stat((*name)->full_name, &(*name)->st) == 0) { - (*name)->exists = True; + (*name)->exists = true; return pvfs_fill_dos_info(pvfs, *name, -1); } @@ -558,9 +558,9 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - (*name)->exists = True; - (*name)->stream_exists = True; - (*name)->has_wildcard = False; + (*name)->exists = true; + (*name)->stream_exists = true; + (*name)->has_wildcard = false; (*name)->original_name = talloc_strdup(*name, fname); (*name)->stream_name = NULL; (*name)->stream_id = 0; @@ -608,7 +608,7 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, return NT_STATUS_UNEXPECTED_IO_ERROR; } - name->exists = True; + name->exists = true; return pvfs_fill_dos_info(pvfs, name, fd); } @@ -650,9 +650,9 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - (*name)->exists = True; - (*name)->stream_exists = True; - (*name)->has_wildcard = False; + (*name)->exists = true; + (*name)->stream_exists = true; + (*name)->has_wildcard = false; /* we can't get the correct 'original_name', but for the purposes of this call this is close enough */ (*name)->original_name = talloc_reference(*name, child->original_name); diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index cefcee6155..e47406dc09 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -237,7 +237,7 @@ static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, enum smb_search_data_level level, uint_t *reply_count, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir = search->dir; NTSTATUS status; @@ -313,7 +313,7 @@ static void pvfs_search_cleanup(struct pvfs_state *pvfs) static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir; struct pvfs_state *pvfs = ntvfs->private_data; @@ -403,7 +403,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; @@ -452,7 +452,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir; struct pvfs_state *pvfs = ntvfs->private_data; @@ -548,7 +548,7 @@ static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; @@ -609,7 +609,7 @@ static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const struct smb2_find *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct pvfs_dir *dir; struct pvfs_state *pvfs = ntvfs->private_data; @@ -712,7 +712,7 @@ static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs, static NTSTATUS pvfs_search_next_smb2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const struct smb2_find *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_search_state *search; @@ -765,7 +765,7 @@ static NTSTATUS pvfs_search_next_smb2(struct ntvfs_module_context *ntvfs, NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { switch (io->generic.level) { case RAW_SEARCH_SEARCH: @@ -787,7 +787,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs, NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { switch (io->generic.level) { case RAW_SEARCH_SEARCH: diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index f20270c743..340913cd4d 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -323,7 +323,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, if (!null_nttime(info->basic_info.in.write_time)) { newstats.dos.write_time = info->basic_info.in.write_time; newstats.dos.flags |= XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; - h->sticky_write_time = True; + h->sticky_write_time = true; } if (!null_nttime(info->basic_info.in.change_time)) { newstats.dos.change_time = info->basic_info.in.change_time; diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 141f5a30a1..1cbe287a4b 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -159,7 +159,7 @@ static const char *cache_lookup(struct pvfs_mangle_context *ctx, uint32_t hash) In this algorithm, mangled names use only pure ascii characters (no multi-byte) so we can avoid doing a UCS2 conversion */ -static BOOL is_mangled_component(struct pvfs_mangle_context *ctx, +static bool is_mangled_component(struct pvfs_mangle_context *ctx, const char *name, size_t len) { unsigned int i; @@ -168,19 +168,19 @@ static BOOL is_mangled_component(struct pvfs_mangle_context *ctx, /* check the length */ if (len > 12 || len < 8) - return False; + return false; /* the best distinguishing characteristic is the ~ */ if (name[6] != '~') - return False; + return false; /* check extension */ if (len > 8) { if (name[8] != '.') - return False; + return false; for (i=9; name[i] && i < len; i++) { if (! FLAG_CHECK(name[i], FLAG_ASCII)) { - return False; + return false; } } } @@ -188,23 +188,23 @@ static BOOL is_mangled_component(struct pvfs_mangle_context *ctx, /* check lead characters */ for (i=0;imangle_prefix;i++) { if (! FLAG_CHECK(name[i], FLAG_ASCII)) { - return False; + return false; } } /* check rest of hash */ if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) { - return False; + return false; } for (i=ctx->mangle_prefix;i<6;i++) { if (! FLAG_CHECK(name[i], FLAG_BASECHAR)) { - return False; + return false; } } M_DEBUG(10,("is_mangled_component %s (len %u) -> yes\n", name, (unsigned int)len)); - return True; + return true; } @@ -220,7 +220,7 @@ static BOOL is_mangled_component(struct pvfs_mangle_context *ctx, directory separators. It should return true if any component is mangled */ -static BOOL is_mangled(struct pvfs_mangle_context *ctx, const char *name) +static bool is_mangled(struct pvfs_mangle_context *ctx, const char *name) { const char *p; const char *s; @@ -229,7 +229,7 @@ static BOOL is_mangled(struct pvfs_mangle_context *ctx, const char *name) for (s=name; (p=strchr(s, '/')); s=p+1) { if (is_mangled_component(ctx, s, PTR_DIFF(p, s))) { - return True; + return true; } } @@ -245,8 +245,8 @@ static BOOL is_mangled(struct pvfs_mangle_context *ctx, const char *name) simplifies things greatly (it means that we know the string won't get larger when converted from UNIX to DOS formats) */ -static BOOL is_8_3(struct pvfs_mangle_context *ctx, - const char *name, BOOL check_case, BOOL allow_wildcards) +static bool is_8_3(struct pvfs_mangle_context *ctx, + const char *name, bool check_case, bool allow_wildcards) { int len, i; char *dot_p; @@ -254,7 +254,7 @@ static BOOL is_8_3(struct pvfs_mangle_context *ctx, /* as a special case, the names '.' and '..' are allowable 8.3 names */ if (name[0] == '.') { if (!name[1] || (name[1] == '.' && !name[2])) { - return True; + return true; } } @@ -265,7 +265,7 @@ static BOOL is_8_3(struct pvfs_mangle_context *ctx, only be slower, it would be incorrect */ len = strlen(name); if (len > 12) - return False; + return false; /* find the '.'. Note that once again we use the non-multibyte function */ @@ -275,7 +275,7 @@ static BOOL is_8_3(struct pvfs_mangle_context *ctx, /* if the name doesn't contain a '.' then its length must be less than 8 */ if (len > 8) { - return False; + return false; } } else { int prefix_len, suffix_len; @@ -286,12 +286,12 @@ static BOOL is_8_3(struct pvfs_mangle_context *ctx, suffix_len = len - (prefix_len+1); if (prefix_len > 8 || suffix_len > 3 || suffix_len == 0) { - return False; + return false; } /* a 8.3 name cannot contain more than 1 '.' */ if (strchr(dot_p+1, '.')) { - return False; + return false; } } @@ -300,12 +300,12 @@ static BOOL is_8_3(struct pvfs_mangle_context *ctx, /* note that we may allow wildcard petterns! */ if (!FLAG_CHECK(name[i], FLAG_ASCII|(allow_wildcards ? FLAG_WILDCARD : 0)) && name[i] != '.') { - return False; + return false; } } /* it is a good 8.3 name */ - return True; + return true; } @@ -361,7 +361,7 @@ static char *check_cache(struct pvfs_mangle_context *ctx, /* look for a DOS reserved name */ -static BOOL is_reserved_name(struct pvfs_mangle_context *ctx, const char *name) +static bool is_reserved_name(struct pvfs_mangle_context *ctx, const char *name) { if (FLAG_CHECK(name[0], FLAG_POSSIBLE1) && FLAG_CHECK(name[1], FLAG_POSSIBLE2) && @@ -371,12 +371,12 @@ static BOOL is_reserved_name(struct pvfs_mangle_context *ctx, const char *name) int i; for (i=0; reserved_names[i]; i++) { if (strcasecmp(name, reserved_names[i]) == 0) { - return True; + return true; } } } - return False; + return false; } @@ -384,13 +384,13 @@ static BOOL is_reserved_name(struct pvfs_mangle_context *ctx, const char *name) See if a filename is a legal long filename. A filename ending in a '.' is not legal unless it's "." or "..". JRA. */ -static BOOL is_legal_name(struct pvfs_mangle_context *ctx, const char *name) +static bool is_legal_name(struct pvfs_mangle_context *ctx, const char *name) { while (*name) { size_t c_size; codepoint_t c = next_codepoint(name, &c_size); if (c == INVALID_CODEPOINT) { - return False; + return false; } /* all high chars are OK */ if (c >= 128) { @@ -398,12 +398,12 @@ static BOOL is_legal_name(struct pvfs_mangle_context *ctx, const char *name) continue; } if (FLAG_CHECK(c, FLAG_ILLEGAL)) { - return False; + return false; } name += c_size; } - return True; + return true; } /* @@ -418,7 +418,7 @@ static BOOL is_legal_name(struct pvfs_mangle_context *ctx, const char *name) return NULL if we don't need to do any conversion */ static char *name_map(struct pvfs_mangle_context *ctx, - const char *name, BOOL need83, BOOL cache83) + const char *name, bool need83, bool cache83) { char *dot_p; char lead_chars[7]; @@ -433,7 +433,7 @@ static char *name_map(struct pvfs_mangle_context *ctx, if (!is_reserved_name(ctx, name)) { /* if the name is already a valid 8.3 name then we don't need to do anything */ - if (is_8_3(ctx, name, False, False)) { + if (is_8_3(ctx, name, false, false)) { return NULL; } @@ -646,7 +646,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) */ char *pvfs_short_name_component(struct pvfs_state *pvfs, const char *name) { - return name_map(pvfs->mangle_ctx, name, True, True); + return name_map(pvfs->mangle_ctx, name, true, true); } @@ -679,7 +679,7 @@ char *pvfs_mangled_lookup(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* look for a DOS reserved name */ -BOOL pvfs_is_reserved_name(struct pvfs_state *pvfs, const char *name) +bool pvfs_is_reserved_name(struct pvfs_state *pvfs, const char *name) { return is_reserved_name(pvfs->mangle_ctx, name); } @@ -689,7 +689,7 @@ BOOL pvfs_is_reserved_name(struct pvfs_state *pvfs, const char *name) see if a component of a filename could be a mangled name from our mangling code */ -BOOL pvfs_is_mangled_component(struct pvfs_state *pvfs, const char *name) +bool pvfs_is_mangled_component(struct pvfs_state *pvfs, const char *name) { return is_mangled_component(pvfs->mangle_ctx, name, strlen(name)); } diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index a3b98feead..7e6173ef2f 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -79,7 +79,7 @@ NTSTATUS pvfs_stream_info(struct pvfs_state *pvfs, struct pvfs_filename *name, i /* the NULL stream always exists */ if (name->stream_name == NULL) { - name->stream_exists = True; + name->stream_exists = true; return NT_STATUS_OK; } @@ -99,7 +99,7 @@ NTSTATUS pvfs_stream_info(struct pvfs_state *pvfs, struct pvfs_filename *name, i if (strcasecmp_m(s->name, name->stream_name) == 0) { name->dos.alloc_size = pvfs_round_alloc_size(pvfs, s->alloc_size); name->st.st_size = s->size; - name->stream_exists = True; + name->stream_exists = true; talloc_free(streams); return NT_STATUS_OK; } @@ -109,7 +109,7 @@ NTSTATUS pvfs_stream_info(struct pvfs_state *pvfs, struct pvfs_filename *name, i name->dos.alloc_size = 0; name->st.st_size = 0; - name->stream_exists = False; + name->stream_exists = false; return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index 895fcd9685..fd9724f7e2 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -24,14 +24,14 @@ #include "vfs_posix.h" /* - return True if a string contains one of the CIFS wildcard characters + return true if a string contains one of the CIFS wildcard characters */ -BOOL pvfs_has_wildcard(const char *str) +bool pvfs_has_wildcard(const char *str) { if (strpbrk(str, "*?<>\"")) { - return True; + return true; } - return False; + return false; } /* diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 61a95ec824..ead3585e0d 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -158,9 +158,9 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name struct xattr_DosInfo2 *info2; if (name->stream_name != NULL) { - name->stream_exists = False; + name->stream_exists = false; } else { - name->stream_exists = True; + name->stream_exists = true; } if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 2c414065cb..208c9e62b7 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -56,7 +56,7 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) pvfs->flags |= PVFS_FLAG_CI_FILESYSTEM; if (share_bool_option(scfg, PVFS_FAKE_OPLOCKS, PVFS_FAKE_OPLOCKS_DEFAULT)) pvfs->flags |= PVFS_FLAG_FAKE_OPLOCKS; - if (share_bool_option(scfg, PVFS_AIO, False)) + if (share_bool_option(scfg, PVFS_AIO, false)) pvfs->flags |= PVFS_FLAG_LINUX_AIO; /* file perm options */ @@ -234,7 +234,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, #ifdef SIGXFSZ /* who had the stupid idea to generate a signal on a large file write instead of just failing it!? */ - BlockSignals(True, SIGXFSZ); + BlockSignals(true, SIGXFSZ); #endif return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index dcf082fd88..a660da329a 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -237,8 +237,8 @@ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; #define PVFS_ACL "posix:acl" #define PVFS_AIO "posix:aio" -#define PVFS_XATTR_DEFAULT True -#define PVFS_FAKE_OPLOCKS_DEFAULT False +#define PVFS_XATTR_DEFAULT true +#define PVFS_FAKE_OPLOCKS_DEFAULT false #define PVFS_SHARE_DELAY_DEFAULT 1000000 #define PVFS_ALLOCATION_ROUNDING_DEFAULT 512 #define PVFS_SEARCH_INACTIVITY_DEFAULT 300 diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 95ea6d8647..dfc07f3483 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -38,7 +38,7 @@ #define O_DIRECTORY 0 #endif -#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, True)) return NT_STATUS_ACCESS_DENIED; } while (0) +#define CHECK_READ_ONLY(req) do { if (share_bool_option(ntvfs->ctx->config, SHARE_READONLY, true)) return NT_STATUS_ACCESS_DENIED; } while (0) /* connect to a share - used when a tree_connect operation comes @@ -308,7 +308,7 @@ static NTSTATUS svfs_open(struct ntvfs_module_context *ntvfs, int fd, flags; struct svfs_file *f; int create_flags, rdwr_flags; - BOOL readonly; + bool readonly; NTSTATUS status; struct ntvfs_handle *handle; @@ -826,7 +826,7 @@ static NTSTATUS svfs_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct svfs_dir *dir; int i; @@ -900,7 +900,7 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { struct svfs_dir *dir; int i; diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 191212580b..3fa710415b 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -83,19 +83,19 @@ struct inotify_watch_context { see if a particular event from inotify really does match a requested notify event in SMB */ -static BOOL filter_match(struct inotify_watch_context *w, +static bool filter_match(struct inotify_watch_context *w, struct inotify_event *e) { if ((e->mask & w->mask) == 0) { /* this happens because inotify_add_watch() coalesces watches on the same path, oring their masks together */ - return False; + return false; } /* SMB separates the filters for files and directories */ if (e->mask & IN_ISDIR) { if ((w->filter & FILE_NOTIFY_CHANGE_DIR_NAME) == 0) { - return False; + return false; } } else { if ((e->mask & IN_ATTRIB) && @@ -104,18 +104,18 @@ static BOOL filter_match(struct inotify_watch_context *w, FILE_NOTIFY_CHANGE_LAST_ACCESS| FILE_NOTIFY_CHANGE_EA| FILE_NOTIFY_CHANGE_SECURITY))) { - return True; + return true; } if ((e->mask & IN_MODIFY) && (w->filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)) { - return True; + return true; } if ((w->filter & FILE_NOTIFY_CHANGE_FILE_NAME) == 0) { - return False; + return false; } } - return True; + return true; } diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index a13d02c12e..1664461d33 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -123,13 +123,13 @@ _PUBLIC_ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) _PUBLIC_ NTSTATUS sys_notify_init(void) { - static BOOL initialized = False; + static bool initialized = false; init_module_fn static_init[] = STATIC_sys_notify_MODULES; init_module_fn *shared_init; if (initialized) return NT_STATUS_OK; - initialized = True; + initialized = true; shared_init = load_samba_modules(NULL, global_loadparm, "sys_notify"); diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 74bc6309c1..0ad8a8501b 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -591,7 +591,7 @@ static NTSTATUS unixuid_lpq(struct ntvfs_module_context *ntvfs, static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; @@ -604,7 +604,7 @@ static NTSTATUS unixuid_search_first(struct ntvfs_module_context *ntvfs, static NTSTATUS unixuid_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *search_private, - BOOL (*callback)(void *, const union smb_search_data *)) + bool (*callback)(void *, const union smb_search_data *)) { NTSTATUS status; -- cgit From 6ce86941de76b27772172717ba5de17ab6fb081d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 5 Nov 2007 15:47:34 +0100 Subject: r25839: use nss_wrapper code in samba4 if --enable-nss-wrapper or --enable-developer is given metze (This used to be commit f8bc6b9ad0eec60bff7fdc5653397efd9a044a29) --- source4/ntvfs/unixuid/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index d078e9f5c6..91976c6811 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -5,6 +5,6 @@ INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs OBJ_FILES = \ vfs_unixuid.o -PRIVATE_DEPENDENCIES = SAMDB +PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER # End MODULE ntvfs_unixuid ################################################ -- cgit From 529763a9aa192a6785ba878aceeb1683c2510913 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 9 Nov 2007 19:24:51 +0100 Subject: r25920: ndr: change NTSTAUS into enum ndr_err_code (samba4 callers) lib/messaging/ lib/registry/ lib/ldb-samba/ librpc/rpc/ auth/auth_winbind.c auth/gensec/ auth/kerberos/ dsdb/repl/ dsdb/samdb/ dsdb/schema/ torture/ cluster/ctdb/ kdc/ ntvfs/ipc/ torture/rap/ ntvfs/ utils/getntacl.c ntptr/ smb_server/ libcli/wrepl/ wrepl_server/ libcli/cldap/ libcli/dgram/ libcli/ldap/ libcli/raw/ libcli/nbt/ libnet/ winbind/ rpc_server/ metze (This used to be commit 6223c7fddc972687eb577e04fc1c8e0604c35435) --- source4/ntvfs/common/notify.c | 32 +++++---- source4/ntvfs/common/opendb_tdb.c | 20 +++--- source4/ntvfs/ipc/ipc_rap.c | 136 ++++++++++++++++++++++++-------------- source4/ntvfs/posix/pvfs_xattr.c | 15 +++-- 4 files changed, 128 insertions(+), 75 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 0214c39b2d..4578dfbf10 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -146,7 +146,7 @@ static NTSTATUS notify_load(struct notify_context *notify) { TDB_DATA dbuf; DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; int seqnum; seqnum = tdb_get_seqnum(notify->w->tdb); @@ -169,11 +169,14 @@ static NTSTATUS notify_load(struct notify_context *notify) blob.data = dbuf.dptr; blob.length = dbuf.dsize; - status = ndr_pull_struct_blob(&blob, notify->array, notify->array, - (ndr_pull_flags_fn_t)ndr_pull_notify_array); + ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array, + (ndr_pull_flags_fn_t)ndr_pull_notify_array); free(dbuf.dptr); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } - return status; + return NT_STATUS_OK; } /* @@ -192,7 +195,7 @@ static NTSTATUS notify_save(struct notify_context *notify) { TDB_DATA dbuf; DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; int ret; TALLOC_CTX *tmp_ctx; @@ -214,11 +217,11 @@ static NTSTATUS notify_save(struct notify_context *notify) tmp_ctx = talloc_new(notify); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); - status = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, - (ndr_push_flags_fn_t)ndr_push_notify_array); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, + (ndr_push_flags_fn_t)ndr_push_notify_array); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } dbuf.dptr = blob.data; @@ -241,7 +244,7 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data uint32_t msg_type, struct server_id server_id, DATA_BLOB *data) { struct notify_context *notify = talloc_get_type(private_data, struct notify_context); - NTSTATUS status; + enum ndr_err_code ndr_err; struct notify_event ev; TALLOC_CTX *tmp_ctx = talloc_new(notify); struct notify_list *listel; @@ -250,9 +253,9 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data return; } - status = ndr_pull_struct_blob(data, tmp_ctx, &ev, + ndr_err = ndr_pull_struct_blob(data, tmp_ctx, &ev, (ndr_pull_flags_fn_t)ndr_pull_notify_event); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); return; } @@ -540,6 +543,7 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, struct notify_event ev; DATA_BLOB data; NTSTATUS status; + enum ndr_err_code ndr_err; TALLOC_CTX *tmp_ctx; ev.action = action; @@ -548,9 +552,9 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, tmp_ctx = talloc_new(notify); - status = ndr_push_struct_blob(&data, tmp_ctx, &ev, + ndr_err = ndr_push_struct_blob(&data, tmp_ctx, &ev, (ndr_push_flags_fn_t)ndr_push_notify_event); - if (!NT_STATUS_IS_OK(status)) { + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); return; } diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index a037e7e47e..07eef829e1 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -195,8 +195,8 @@ static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) struct odb_context *odb = lck->odb; TDB_DATA dbuf; DATA_BLOB blob; - NTSTATUS status; - + enum ndr_err_code ndr_err; + dbuf = tdb_fetch(odb->w->tdb, lck->key); if (dbuf.dptr == NULL) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -205,11 +205,13 @@ static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) blob.data = dbuf.dptr; blob.length = dbuf.dsize; - status = ndr_pull_struct_blob(&blob, lck, file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); - + ndr_err = ndr_pull_struct_blob(&blob, lck, file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); free(dbuf.dptr); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } - return status; + return NT_STATUS_OK; } /* @@ -220,7 +222,7 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) struct odb_context *odb = lck->odb; TDB_DATA dbuf; DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; int ret; if (file->num_entries == 0) { @@ -231,8 +233,10 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) return NT_STATUS_OK; } - status = ndr_push_struct_blob(&blob, lck, file, (ndr_push_flags_fn_t)ndr_push_opendb_file); - NT_STATUS_NOT_OK_RETURN(status); + ndr_err = ndr_push_struct_blob(&blob, lck, file, (ndr_push_flags_fn_t)ndr_push_opendb_file); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } dbuf.dptr = blob.data; dbuf.dsize = blob.length; diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 605a172a70..2a9d66cae8 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -24,6 +24,33 @@ #include "ntvfs/ipc/proto.h" #include "librpc/ndr/libndr.h" +#define NDR_RETURN(call) do { \ + enum ndr_err_code _ndr_err; \ + _ndr_err = call; \ + if (!NDR_ERR_CODE_IS_SUCCESS(_ndr_err)) { \ + return ndr_map_error2ntstatus(_ndr_err); \ + } \ +} while (0) + +#define RAP_GOTO(call) do { \ + result = call; \ + if (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) {\ + goto buffer_overflow; \ + } \ + if (!NT_STATUS_IS_OK(result)) { \ + goto done; \ + } \ +} while (0) + +#define NDR_GOTO(call) do { \ + enum ndr_err_code _ndr_err; \ + _ndr_err = call; \ + if (!NDR_ERR_CODE_IS_SUCCESS(_ndr_err)) { \ + RAP_GOTO(ndr_map_error2ntstatus(_ndr_err)); \ + } \ +} while (0) + + #define NERR_Success 0 #define NERR_badpass 86 #define NERR_notsupported 50 @@ -108,22 +135,37 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, static NTSTATUS rap_srv_pull_word(struct rap_call *call, uint16_t *result) { + enum ndr_err_code ndr_err; + if (*call->paramdesc++ != 'W') return NT_STATUS_INVALID_PARAMETER; - return ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, result); + ndr_err = ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, result); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + return NT_STATUS_OK; } static NTSTATUS rap_srv_pull_dword(struct rap_call *call, uint32_t *result) { + enum ndr_err_code ndr_err; + if (*call->paramdesc++ != 'D') return NT_STATUS_INVALID_PARAMETER; - return ndr_pull_uint32(call->ndr_pull_param, NDR_SCALARS, result); + ndr_err = ndr_pull_uint32(call->ndr_pull_param, NDR_SCALARS, result); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + return NT_STATUS_OK; } static NTSTATUS rap_srv_pull_string(struct rap_call *call, const char **result) { + enum ndr_err_code ndr_err; char paramdesc = *call->paramdesc++; if (paramdesc == 'O') { @@ -134,20 +176,25 @@ static NTSTATUS rap_srv_pull_string(struct rap_call *call, const char **result) if (paramdesc != 'z') return NT_STATUS_INVALID_PARAMETER; - return ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, result); + ndr_err = ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, result); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + return NT_STATUS_OK; } static NTSTATUS rap_srv_pull_bufsize(struct rap_call *call, uint16_t *bufsize) { - NTSTATUS result; + enum ndr_err_code ndr_err; if ( (*call->paramdesc++ != 'r') || (*call->paramdesc++ != 'L') ) return NT_STATUS_INVALID_PARAMETER; - result = ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, bufsize); - - if (!NT_STATUS_IS_OK(result)) - return result; + ndr_err = ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, bufsize); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } call->heap->offset = *bufsize; @@ -178,8 +225,8 @@ static NTSTATUS rap_push_string(struct ndr_push *data_push, heap->offset -= space; - NDR_CHECK(ndr_push_uint16(data_push, NDR_SCALARS, heap->offset)); - NDR_CHECK(ndr_push_uint16(data_push, NDR_SCALARS, 0)); + NDR_RETURN(ndr_push_uint16(data_push, NDR_SCALARS, heap->offset)); + NDR_RETURN(ndr_push_uint16(data_push, NDR_SCALARS, 0)); heap->strings = talloc_realloc(heap->mem_ctx, heap->strings, @@ -195,21 +242,14 @@ static NTSTATUS rap_push_string(struct ndr_push *data_push, return NT_STATUS_OK; } -#define NDR_OK(call) do { result = call; \ - if (NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL)) \ - goto buffer_overflow; \ - if (!NT_STATUS_IS_OK(result)) \ - goto done; \ - } while (0) - static NTSTATUS _rap_netshareenum(struct rap_call *call) { struct rap_NetShareEnum r; NTSTATUS result; - NDR_OK(rap_srv_pull_word(call, &r.in.level)); - NDR_OK(rap_srv_pull_bufsize(call, &r.in.bufsize)); - NDR_OK(rap_srv_pull_expect_multiple(call)); + RAP_GOTO(rap_srv_pull_word(call, &r.in.level)); + RAP_GOTO(rap_srv_pull_bufsize(call, &r.in.bufsize)); + RAP_GOTO(rap_srv_pull_expect_multiple(call)); switch(r.in.level) { case 0: @@ -241,20 +281,20 @@ static NTSTATUS _rap_netshareenum(struct rap_call *call) switch(r.in.level) { case 0: - NDR_OK(ndr_push_bytes(call->ndr_push_data, + NDR_GOTO(ndr_push_bytes(call->ndr_push_data, (const uint8_t *)r.out.info[i].info0.name, sizeof(r.out.info[i].info0.name))); break; case 1: - NDR_OK(ndr_push_bytes(call->ndr_push_data, + NDR_GOTO(ndr_push_bytes(call->ndr_push_data, (const uint8_t *)r.out.info[i].info1.name, sizeof(r.out.info[i].info1.name))); - NDR_OK(ndr_push_uint8(call->ndr_push_data, + NDR_GOTO(ndr_push_uint8(call->ndr_push_data, NDR_SCALARS, r.out.info[i].info1.pad)); - NDR_OK(ndr_push_uint16(call->ndr_push_data, + NDR_GOTO(ndr_push_uint16(call->ndr_push_data, NDR_SCALARS, r.out.info[i].info1.type)); - NDR_OK(rap_push_string(call->ndr_push_data, + RAP_GOTO(rap_push_string(call->ndr_push_data, call->heap, r.out.info[i].info1.comment)); @@ -273,8 +313,8 @@ static NTSTATUS _rap_netshareenum(struct rap_call *call) call->status = r.out.status; - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.count)); - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.available)); + NDR_RETURN(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.count)); + NDR_RETURN(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.available)); result = NT_STATUS_OK; @@ -287,11 +327,11 @@ static NTSTATUS _rap_netserverenum2(struct rap_call *call) struct rap_NetServerEnum2 r; NTSTATUS result; - NDR_OK(rap_srv_pull_word(call, &r.in.level)); - NDR_OK(rap_srv_pull_bufsize(call, &r.in.bufsize)); - NDR_OK(rap_srv_pull_expect_multiple(call)); - NDR_OK(rap_srv_pull_dword(call, &r.in.servertype)); - NDR_OK(rap_srv_pull_string(call, &r.in.domain)); + RAP_GOTO(rap_srv_pull_word(call, &r.in.level)); + RAP_GOTO(rap_srv_pull_bufsize(call, &r.in.bufsize)); + RAP_GOTO(rap_srv_pull_expect_multiple(call)); + RAP_GOTO(rap_srv_pull_dword(call, &r.in.servertype)); + RAP_GOTO(rap_srv_pull_string(call, &r.in.domain)); switch(r.in.level) { case 0: @@ -323,22 +363,22 @@ static NTSTATUS _rap_netserverenum2(struct rap_call *call) switch(r.in.level) { case 0: - NDR_OK(ndr_push_bytes(call->ndr_push_data, + NDR_GOTO(ndr_push_bytes(call->ndr_push_data, (const uint8_t *)r.out.info[i].info0.name, sizeof(r.out.info[i].info0.name))); break; case 1: - NDR_OK(ndr_push_bytes(call->ndr_push_data, + NDR_GOTO(ndr_push_bytes(call->ndr_push_data, (const uint8_t *)r.out.info[i].info1.name, sizeof(r.out.info[i].info1.name))); - NDR_OK(ndr_push_uint8(call->ndr_push_data, + NDR_GOTO(ndr_push_uint8(call->ndr_push_data, NDR_SCALARS, r.out.info[i].info1.version_major)); - NDR_OK(ndr_push_uint8(call->ndr_push_data, + NDR_GOTO(ndr_push_uint8(call->ndr_push_data, NDR_SCALARS, r.out.info[i].info1.version_minor)); - NDR_OK(ndr_push_uint32(call->ndr_push_data, + NDR_GOTO(ndr_push_uint32(call->ndr_push_data, NDR_SCALARS, r.out.info[i].info1.servertype)); - NDR_OK(rap_push_string(call->ndr_push_data, + RAP_GOTO(rap_push_string(call->ndr_push_data, call->heap, r.out.info[i].info1.comment)); @@ -357,8 +397,8 @@ static NTSTATUS _rap_netserverenum2(struct rap_call *call) call->status = r.out.status; - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.count)); - NDR_CHECK(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.available)); + NDR_RETURN(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.count)); + NDR_RETURN(ndr_push_uint16(call->ndr_push_param, NDR_SCALARS, r.out.available)); result = NT_STATUS_OK; @@ -398,10 +438,10 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) if (call == NULL) return NT_STATUS_NO_MEMORY; - NDR_CHECK(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &call->callno)); - NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, + NDR_RETURN(ndr_pull_uint16(call->ndr_pull_param, NDR_SCALARS, &call->callno)); + NDR_RETURN(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, &call->paramdesc)); - NDR_CHECK(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, + NDR_RETURN(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, &call->datadesc)); call->ndr_push_param = ndr_push_init_ctx(call); @@ -439,17 +479,17 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) final_param->flags = RAPNDR_FLAGS; final_data->flags = RAPNDR_FLAGS; - NDR_CHECK(ndr_push_uint16(final_param, NDR_SCALARS, call->status)); - NDR_CHECK(ndr_push_uint16(final_param, + NDR_RETURN(ndr_push_uint16(final_param, NDR_SCALARS, call->status)); + NDR_RETURN(ndr_push_uint16(final_param, NDR_SCALARS, call->heap->offset - result_data.length)); - NDR_CHECK(ndr_push_bytes(final_param, result_param.data, + NDR_RETURN(ndr_push_bytes(final_param, result_param.data, result_param.length)); - NDR_CHECK(ndr_push_bytes(final_data, result_data.data, + NDR_RETURN(ndr_push_bytes(final_data, result_data.data, result_data.length)); for (i=call->heap->num_strings-1; i>=0; i--) - NDR_CHECK(ndr_push_string(final_data, NDR_SCALARS, + NDR_RETURN(ndr_push_string(final_data, NDR_SCALARS, call->heap->strings[i])); trans->out.setup_count = 0; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index ead3585e0d..f723aad955 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -107,6 +107,7 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, { NTSTATUS status; DATA_BLOB blob; + enum ndr_err_code ndr_err; status = pull_xattr_blob(pvfs, mem_ctx, attr_name, fname, fd, XATTR_DOSATTRIB_ESTIMATED_SIZE, &blob); @@ -115,11 +116,14 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, } /* pull the blob */ - status = ndr_pull_struct_blob(&blob, mem_ctx, p, (ndr_pull_flags_fn_t)pull_fn); + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, p, (ndr_pull_flags_fn_t)pull_fn); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } data_blob_free(&blob); - return status; + return NT_STATUS_OK; } /* @@ -132,11 +136,12 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx = talloc_new(NULL); DATA_BLOB blob; NTSTATUS status; + enum ndr_err_code ndr_err; - status = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn); - if (!NT_STATUS_IS_OK(status)) { + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); - return status; + return ndr_map_error2ntstatus(ndr_err); } status = push_xattr_blob(pvfs, attr_name, fname, fd, &blob); -- cgit From ca0b72a1fdb7bd965065e833df34662afef0423e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 16 Nov 2007 20:12:00 +0100 Subject: r26003: Split up DB_WRAP, as first step in an attempt to sanitize dependencies. (This used to be commit 56dfcb4f2f8e74c9d8b2fe3a0df043781188a555) --- source4/ntvfs/common/brlock.c | 1 - source4/ntvfs/common/notify.c | 2 +- source4/ntvfs/common/opendb_tdb.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 3 ++- source4/ntvfs/posix/xattr_tdb.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index 27d7437f4f..ddf3219a9a 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -28,7 +28,6 @@ #include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messaging/messaging.h" -#include "db_wrap.h" #include "lib/messaging/irpc.h" #include "libcli/libcli.h" #include "cluster/cluster.h" diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 4578dfbf10..16cf4e4b54 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -28,7 +28,7 @@ #include "lib/tdb/include/tdb.h" #include "lib/util/util_tdb.h" #include "messaging/messaging.h" -#include "db_wrap.h" +#include "tdb_wrap.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_notify.h" #include "lib/util/dlinklist.h" diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 07eef829e1..9926bf8d3e 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -41,7 +41,7 @@ #include "system/filesys.h" #include "lib/tdb/include/tdb.h" #include "messaging/messaging.h" -#include "db_wrap.h" +#include "tdb_wrap.h" #include "lib/messaging/irpc.h" #include "librpc/gen_ndr/ndr_opendb.h" #include "ntvfs/ntvfs.h" diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 208c9e62b7..24aa023de5 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -27,7 +27,8 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/security.h" #include "lib/tdb/include/tdb.h" -#include "db_wrap.h" +#include "tdb_wrap.h" +#include "util/util_ldb.h" #include "libcli/security/security.h" #include "lib/events/events.h" diff --git a/source4/ntvfs/posix/xattr_tdb.c b/source4/ntvfs/posix/xattr_tdb.c index b49b11a72d..1113ac1739 100644 --- a/source4/ntvfs/posix/xattr_tdb.c +++ b/source4/ntvfs/posix/xattr_tdb.c @@ -22,7 +22,7 @@ #include "includes.h" #include "vfs_posix.h" #include "lib/tdb/include/tdb.h" -#include "db_wrap.h" +#include "tdb_wrap.h" #define XATTR_LIST_ATTR ".xattr_list" -- cgit From 981437efbc966c4bb0880fc0b02715d297ae6644 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Nov 2007 11:08:24 +0100 Subject: r26053: IPC_RAP: don't use ndr_pull_save anymore metze (This used to be commit 590dd7f8a1ccba762dfcdfb036cf44306da2354a) --- source4/ntvfs/ipc/ipc_rap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 2a9d66cae8..d8e9812dd8 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -273,10 +273,10 @@ static NTSTATUS _rap_netshareenum(struct rap_call *call) for (r.out.count = 0; r.out.count < r.out.available; r.out.count++) { int i = r.out.count; - struct ndr_push_save data_save; + uint32_t offset_save; struct rap_heap_save heap_save; - ndr_push_save(call->ndr_push_data, &data_save); + offset_save = call->ndr_push_data->offset; rap_heap_save(call->heap, &heap_save); switch(r.in.level) { @@ -305,7 +305,7 @@ static NTSTATUS _rap_netshareenum(struct rap_call *call) buffer_overflow: - ndr_push_restore(call->ndr_push_data, &data_save); + call->ndr_push_data->offset = offset_save; rap_heap_restore(call->heap, &heap_save); break; } @@ -355,10 +355,10 @@ static NTSTATUS _rap_netserverenum2(struct rap_call *call) for (r.out.count = 0; r.out.count < r.out.available; r.out.count++) { int i = r.out.count; - struct ndr_push_save data_save; + uint32_t offset_save; struct rap_heap_save heap_save; - ndr_push_save(call->ndr_push_data, &data_save); + offset_save = call->ndr_push_data->offset; rap_heap_save(call->heap, &heap_save); switch(r.in.level) { @@ -389,7 +389,7 @@ static NTSTATUS _rap_netserverenum2(struct rap_call *call) buffer_overflow: - ndr_push_restore(call->ndr_push_data, &data_save); + call->ndr_push_data->offset = offset_save; rap_heap_restore(call->heap, &heap_save); break; } -- cgit From 0ac6bffdf46003517127fbd9763f74e09e96c21a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 27 Nov 2007 02:04:38 +0100 Subject: r26136: Attempt to fix dependencies for auth. (This used to be commit abf2600a044cdbab6c5d7880d18217bff3d15c39) --- source4/ntvfs/config.mk | 1 - 1 file changed, 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index b1aada7b31..ae8d5d9b4a 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -90,7 +90,6 @@ OBJ_FILES = \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o -PRIVATE_DEPENDENCIES = auth # # End SUBSYSTEM NTVFS ################################################ -- cgit From 51db4c3f3d81d1ed03beae6426786c843ac59807 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 2 Dec 2007 17:56:09 +0100 Subject: r26228: Store loadparm context in auth context, move more loadparm_contexts up the call stack. (This used to be commit ba75f1613a9aac69dd5df94dd8a2b37820acd166) --- source4/ntvfs/common/brlock_tdb.c | 3 ++- source4/ntvfs/posix/vfs_posix.c | 4 ++-- source4/ntvfs/unixuid/vfs_unixuid.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 2b81521a2c..25642d5f5c 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -34,6 +34,7 @@ #include "cluster/cluster.h" #include "ntvfs/common/brlock.h" #include "ntvfs/ntvfs.h" +#include "param/param.h" /* in this module a "DATA_BLOB *file_key" is a blob that uniquely identifies @@ -94,7 +95,7 @@ static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id se return NULL; } - brl->db = db_tmp_open(brl, "brlock.tdb", TDB_DEFAULT); + brl->db = db_tmp_open(brl, global_loadparm, "brlock.tdb", TDB_DEFAULT); if (brl->db == NULL) { talloc_free(brl); return NULL; diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 24aa023de5..07948a64e2 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -31,7 +31,7 @@ #include "util/util_ldb.h" #include "libcli/security/security.h" #include "lib/events/events.h" - +#include "param/param.h" /* setup config options for a posix share @@ -216,7 +216,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, event_context_find(pvfs), pvfs->ntvfs->ctx->config); - pvfs->sidmap = sidmap_open(pvfs); + pvfs->sidmap = sidmap_open(pvfs, global_loadparm); if (pvfs->sidmap == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 0ad8a8501b..d7b64b01f2 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -26,6 +26,7 @@ #include "auth/auth.h" #include "ntvfs/ntvfs.h" #include "dsdb/samdb/samdb.h" +#include "param/param.h" struct unixuid_private { struct sidmap_context *sidmap; @@ -215,7 +216,7 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - private->sidmap = sidmap_open(private); + private->sidmap = sidmap_open(private, global_loadparm); if (private->sidmap == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From 57f20ccd242e45ff91850341594aa040d113c19e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Dec 2007 20:05:00 +0100 Subject: r26296: Store loadparm context in DCE/RPC server context. (This used to be commit fc1f4d2d65d4c983cba5421e7ffb64dd75482860) --- source4/ntvfs/ipc/vfs_ipc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index fc3c74ca6c..4a5ddd7a9c 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -31,6 +31,7 @@ #include "ntvfs/ipc/proto.h" #include "rpc_server/dcerpc_server.h" #include "libcli/raw/ioctl.h" +#include "param/param.h" /* this is the private structure used to keep the state of an open ipc$ connection. It needs to keep information about all open @@ -108,7 +109,7 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, private->pipe_list = NULL; /* setup the DCERPC server subsystem */ - status = dcesrv_init_ipc_context(private, &private->dcesrv); + status = dcesrv_init_ipc_context(private, global_loadparm, &private->dcesrv); NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; -- cgit From 39ee38d9c1aabf4db065b433d067d0da053d7d61 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 6 Dec 2007 17:52:23 +0100 Subject: r26316: Use contexts for conversion functions. (This used to be commit f6420d933b5b011d428974f3a2a57edf19e6f482) --- source4/ntvfs/posix/pvfs_rename.c | 8 ++++---- source4/ntvfs/posix/pvfs_resolve.c | 6 +++--- source4/ntvfs/posix/pvfs_shortname.c | 2 +- source4/ntvfs/posix/pvfs_util.c | 2 +- source4/ntvfs/print/vfs_print.c | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 3aa63bd2ca..5c351b2df2 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -107,16 +107,16 @@ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, while (*p2) { codepoint_t c1, c2; size_t c_size1, c_size2; - c1 = next_codepoint(p1, &c_size1); - c2 = next_codepoint(p2, &c_size2); + c1 = next_codepoint(global_smb_iconv_convenience, p1, &c_size1); + c2 = next_codepoint(global_smb_iconv_convenience, p2, &c_size2); if (c2 == '?') { - d += push_codepoint(d, c1); + d += push_codepoint(global_smb_iconv_convenience, d, c1); } else if (c2 == '*') { memcpy(d, p1, strlen(p1)); d += strlen(p1); break; } else { - d += push_codepoint(d, c2); + d += push_codepoint(global_smb_iconv_convenience, d, c2); } p1 += c_size1; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 8a7aa13351..f1d701b343 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -256,7 +256,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, while (*p) { size_t c_size; - codepoint_t c = next_codepoint(p, &c_size); + codepoint_t c = next_codepoint(global_smb_iconv_convenience, p, &c_size); switch (c) { case '\\': if (name->has_wildcard) { @@ -340,7 +340,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t if (s == NULL) return NT_STATUS_NO_MEMORY; for (num_components=1, p=s; *p; p += c_size) { - c = next_codepoint(p, &c_size); + c = next_codepoint(global_smb_iconv_convenience, p, &c_size); if (c == '\\') num_components++; } @@ -352,7 +352,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t components[0] = s; for (i=0, p=s; *p; p += c_size) { - c = next_codepoint(p, &c_size); + c = next_codepoint(global_smb_iconv_convenience, p, &c_size); if (c == '\\') { *p = 0; components[++i] = p+1; diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 1cbe287a4b..e671804ca6 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -388,7 +388,7 @@ static bool is_legal_name(struct pvfs_mangle_context *ctx, const char *name) { while (*name) { size_t c_size; - codepoint_t c = next_codepoint(name, &c_size); + codepoint_t c = next_codepoint(global_smb_iconv_convenience, name, &c_size); if (c == INVALID_CODEPOINT) { return false; } diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index fd9724f7e2..b7cba00d9b 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -181,7 +181,7 @@ uint32_t pvfs_name_hash(const char *key, size_t length) while (*key && length--) { size_t c_size; - codepoint_t c = next_codepoint(key, &c_size); + codepoint_t c = next_codepoint(global_smb_iconv_convenience, key, &c_size); c = toupper_w(c); value *= fnv1_prime; value ^= (uint32_t)c; diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index f9d3235116..baa1d876d6 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -83,8 +83,8 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); - push_string(p+2, lp_netbios_name(global_loadparm), 15, STR_TERMINATE|STR_ASCII); - push_string(p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); + push_string(global_smb_iconv_convenience, p+2, lp_netbios_name(global_loadparm), 15, STR_TERMINATE|STR_ASCII); + push_string(global_smb_iconv_convenience, p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } -- cgit From a72c5053c587f0ed6113ef514fe3739cb81e7abf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Dec 2007 23:32:43 +0100 Subject: r26353: Remove use of global_loadparm. (This used to be commit 17637e4490e42db6cdef619286c4d5a0982e9d1a) --- source4/ntvfs/cifs/vfs_cifs.c | 6 +++--- source4/ntvfs/common/opendb_tdb.c | 2 +- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/ntvfs.h | 1 + source4/ntvfs/ntvfs_base.c | 2 ++ source4/ntvfs/posix/pvfs_shortname.c | 4 ++-- source4/ntvfs/posix/vfs_posix.c | 2 +- source4/ntvfs/print/vfs_print.c | 2 +- source4/ntvfs/unixuid/vfs_unixuid.c | 2 +- 9 files changed, 13 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index cd4e363906..152a4056c5 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -166,7 +166,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); - cli_credentials_set_conf(credentials, global_loadparm); + cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); @@ -176,7 +176,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, DEBUG(5, ("CIFS backend: Using machine account\n")); credentials = cli_credentials_init(private); cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); - cli_credentials_set_conf(credentials, global_loadparm); + cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } @@ -198,7 +198,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.called_name = host; io.in.credentials = credentials; io.in.fallback_to_anonymous = false; - io.in.workgroup = lp_workgroup(global_loadparm); + io.in.workgroup = lp_workgroup(ntvfs->ctx->lp_ctx); io.in.service = remote_share; io.in.service_type = "?????"; diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 9926bf8d3e..b8b8a5cb33 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -88,7 +88,7 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, odb->ntvfs_ctx = ntvfs_ctx; /* leave oplocks disabled by default until the code is working */ - odb->oplocks = lp_parm_bool(global_loadparm, NULL, "opendb", "oplocks", false); + odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", false); return odb; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 4a5ddd7a9c..b69fb98c5d 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -109,7 +109,7 @@ static NTSTATUS ipc_connect(struct ntvfs_module_context *ntvfs, private->pipe_list = NULL; /* setup the DCERPC server subsystem */ - status = dcesrv_init_ipc_context(private, global_loadparm, &private->dcesrv); + status = dcesrv_init_ipc_context(private, ntvfs->ctx->lp_ctx, &private->dcesrv); NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 9ac6f85321..fe5f956426 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -187,6 +187,7 @@ struct ntvfs_context { struct share_config *config; struct server_id server_id; + struct loadparm_context *lp_ctx; struct event_context *event_ctx; struct messaging_context *msg_ctx; diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 20197a4ba9..9172fe1580 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -154,6 +154,7 @@ _PUBLIC_ bool ntvfs_interface_differs(const struct ntvfs_critical_sizes *const i NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, enum ntvfs_type type, enum protocol_types protocol, struct event_context *ev, struct messaging_context *msg, + struct loadparm_context *lp_ctx, struct server_id server_id, struct ntvfs_context **_ctx) { const char **handlers = share_string_list_option(mem_ctx, scfg, SHARE_NTVFS_HANDLER); @@ -172,6 +173,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e ctx->event_ctx = ev; ctx->msg_ctx = msg; ctx->server_id = server_id; + ctx->lp_ctx = lp_ctx; for (i=0; handlers[i]; i++) { struct ntvfs_module_context *ntvfs; diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index e671804ca6..68e415000e 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -614,7 +614,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) } /* by default have a max of 512 entries in the cache. */ - ctx->cache_size = lp_parm_int(global_loadparm, NULL, "mangle", "cachesize", 512); + ctx->cache_size = lp_parm_int(pvfs->ntvfs->ctx->lp_ctx, NULL, "mangle", "cachesize", 512); ctx->prefix_cache = talloc_array(ctx, char *, ctx->cache_size); if (ctx->prefix_cache == NULL) { @@ -628,7 +628,7 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) memset(ctx->prefix_cache, 0, sizeof(char *) * ctx->cache_size); memset(ctx->prefix_cache_hashes, 0, sizeof(uint32_t) * ctx->cache_size); - ctx->mangle_prefix = lp_parm_int(global_loadparm, NULL, "mangle", "prefix", -1); + ctx->mangle_prefix = lp_parm_int(pvfs->ntvfs->ctx->lp_ctx, NULL, "mangle", "prefix", -1); if (ctx->mangle_prefix < 0 || ctx->mangle_prefix > 6) { ctx->mangle_prefix = DEFAULT_MANGLE_PREFIX; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 07948a64e2..c1e15976d2 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -216,7 +216,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, event_context_find(pvfs), pvfs->ntvfs->ctx->config); - pvfs->sidmap = sidmap_open(pvfs, global_loadparm); + pvfs->sidmap = sidmap_open(pvfs, pvfs->ntvfs->ctx->lp_ctx); if (pvfs->sidmap == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index baa1d876d6..5fdb7aada6 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -83,7 +83,7 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); - push_string(global_smb_iconv_convenience, p+2, lp_netbios_name(global_loadparm), 15, STR_TERMINATE|STR_ASCII); + push_string(global_smb_iconv_convenience, p+2, lp_netbios_name(ntvfs->ctx->lp_ctx), 15, STR_TERMINATE|STR_ASCII); push_string(global_smb_iconv_convenience, p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index d7b64b01f2..63889c6677 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -216,7 +216,7 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - private->sidmap = sidmap_open(private, global_loadparm); + private->sidmap = sidmap_open(private, ntvfs->ctx->lp_ctx); if (private->sidmap == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } -- cgit From b65dba2245bf382c47d65c95ac9b1efa43918fc0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 04:33:16 +0100 Subject: r26355: Eliminate global_loadparm in more places. (This used to be commit 5d589a0d94bd76a9b4c9fc748854e8098ea43c4d) --- source4/ntvfs/common/brlock.c | 3 ++- source4/ntvfs/common/brlock.h | 1 + source4/ntvfs/common/brlock_tdb.c | 3 ++- source4/ntvfs/common/opendb.c | 2 +- source4/ntvfs/ntvfs_base.c | 4 ++-- source4/ntvfs/posix/vfs_posix.c | 1 + 6 files changed, 9 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index ddf3219a9a..c87eca8aff 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -48,12 +48,13 @@ void brl_set_ops(const struct brlock_ops *new_ops) need the messaging_ctx to allow for pending lock notifications. */ struct brl_context *brl_init(TALLOC_CTX *mem_ctx, struct server_id server, + struct loadparm_context *lp_ctx, struct messaging_context *messaging_ctx) { if (ops == NULL) { brl_tdb_init_ops(); } - return ops->brl_init(mem_ctx, server, messaging_ctx); + return ops->brl_init(mem_ctx, server, lp_ctx, messaging_ctx); } struct brl_handle *brl_create_handle(TALLOC_CTX *mem_ctx, struct ntvfs_handle *ntvfs, DATA_BLOB *file_key) diff --git a/source4/ntvfs/common/brlock.h b/source4/ntvfs/common/brlock.h index 50f30ec276..aff30d138e 100644 --- a/source4/ntvfs/common/brlock.h +++ b/source4/ntvfs/common/brlock.h @@ -23,6 +23,7 @@ struct brlock_ops { struct brl_context *(*brl_init)(TALLOC_CTX *, struct server_id , + struct loadparm_context *lp_ctx, struct messaging_context *); struct brl_handle *(*brl_create_handle)(TALLOC_CTX *, struct ntvfs_handle *, DATA_BLOB *); NTSTATUS (*brl_lock)(struct brl_context *, diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 25642d5f5c..362a6d01e2 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -86,6 +86,7 @@ struct brl_handle { pending lock notifications. */ static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id server, + struct loadparm_context *lp_ctx, struct messaging_context *messaging_ctx) { struct brl_context *brl; @@ -95,7 +96,7 @@ static struct brl_context *brl_tdb_init(TALLOC_CTX *mem_ctx, struct server_id se return NULL; } - brl->db = db_tmp_open(brl, global_loadparm, "brlock.tdb", TDB_DEFAULT); + brl->db = db_tmp_open(brl, lp_ctx, "brlock.tdb", TDB_DEFAULT); if (brl->db == NULL) { talloc_free(brl); return NULL; diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 59990d2fc1..4826ca5c26 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -62,7 +62,7 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, struct ntvfs_context *ntvfs_ctx) { if (ops == NULL) { - if (lp_parm_bool(global_loadparm, NULL, "ctdb", "opendb", false)) { + if (lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "ctdb", "opendb", false)) { odb_ctdb_init_ops(); } else { odb_tdb_init_ops(); diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 9172fe1580..3873afbdfa 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -199,10 +199,10 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e return NT_STATUS_OK; } -NTSTATUS ntvfs_init(void) +NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { init_module_fn static_init[] = STATIC_ntvfs_MODULES; - init_module_fn *shared_init = load_samba_modules(NULL, global_loadparm, "ntvfs"); + init_module_fn *shared_init = load_samba_modules(NULL, lp_ctx, "ntvfs"); run_init_functions(static_init); run_init_functions(shared_init); diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index c1e15976d2..8e5e5a6942 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -199,6 +199,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->brl_context = brl_init(pvfs, pvfs->ntvfs->ctx->server_id, + pvfs->ntvfs->ctx->lp_ctx, pvfs->ntvfs->ctx->msg_ctx); if (pvfs->brl_context == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; -- cgit From f055893ca571fbeac3675c02344c7cc53106bea1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 18:41:55 +0100 Subject: r26382: Remove more uses of global_loadparm. (This used to be commit 6d4c59853481855c232e7cf97264a391f40af2b5) --- source4/ntvfs/ipc/rap_server.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index d1a4dd9edc..9113bef894 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -23,6 +23,7 @@ #include "libcli/rap/rap.h" #include "librpc/gen_ndr/srvsvc.h" #include "rpc_server/common/common.h" +#include "param/param.h" /* At this moment these are just dummy functions, but you might get the * idea. */ @@ -40,7 +41,7 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, r->out.available = 0; r->out.info = NULL; - nterr = share_get_context(mem_ctx, &sctx); + nterr = share_get_context_by_name(mem_ctx, lp_share_backend(global_loadparm), &sctx); if (!NT_STATUS_IS_OK(nterr)) { return nterr; } -- cgit From 28671c54cf154131ca6b601cac283933664829c7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 11 Dec 2007 22:23:25 +0100 Subject: r26403: Make sure ntvfs is only initialized once. (This used to be commit 32b44e10747d704ce9a21cb8d34606cb0e41efab) --- source4/ntvfs/ntvfs_base.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 3873afbdfa..28f43eabe8 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -201,8 +201,14 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { + static bool initialized = false; init_module_fn static_init[] = STATIC_ntvfs_MODULES; - init_module_fn *shared_init = load_samba_modules(NULL, lp_ctx, "ntvfs"); + init_module_fn *shared_init; + + if (initialized) return NT_STATUS_OK; + initialized = true; + + shared_init = load_samba_modules(NULL, lp_ctx, "ntvfs"); run_init_functions(static_init); run_init_functions(shared_init); -- cgit From 4b0199a5493ea2b88558cc40871e63c1dc8dbb56 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 12 Dec 2007 02:15:29 +0100 Subject: r26409: Pass smb ports along. (This used to be commit 2833f320de1f1fd39c710ad0a61c3fa1bb1df31f) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 152a4056c5..178e9b01cc 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -194,7 +194,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* connect to the server, using the smbd event context */ io.in.dest_host = host; - io.in.port = 0; + io.in.dest_ports = lp_smb_ports(ntvfs->ctx->lp_ctx); io.in.called_name = host; io.in.credentials = credentials; io.in.fallback_to_anonymous = false; -- cgit From d891c0c74a03d797aed1c5ac0329fd9d1d78da63 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:09 +0100 Subject: r26429: Avoid use of global_smb_iconv_convenience. (This used to be commit d37136b7abfbba75ef2e5ab855eb3382b9648b8c) --- source4/ntvfs/posix/pvfs_rename.c | 9 +++++---- source4/ntvfs/posix/pvfs_resolve.c | 9 +++++---- source4/ntvfs/posix/pvfs_shortname.c | 2 +- source4/ntvfs/posix/pvfs_util.c | 3 ++- source4/ntvfs/print/vfs_print.c | 4 ++-- 5 files changed, 15 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 5c351b2df2..3b9842db7f 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" #include "librpc/gen_ndr/security.h" +#include "param/param.h" /* @@ -107,16 +108,16 @@ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, while (*p2) { codepoint_t c1, c2; size_t c_size1, c_size2; - c1 = next_codepoint(global_smb_iconv_convenience, p1, &c_size1); - c2 = next_codepoint(global_smb_iconv_convenience, p2, &c_size2); + c1 = next_codepoint(lp_iconv_convenience(global_loadparm), p1, &c_size1); + c2 = next_codepoint(lp_iconv_convenience(global_loadparm), p2, &c_size2); if (c2 == '?') { - d += push_codepoint(global_smb_iconv_convenience, d, c1); + d += push_codepoint(lp_iconv_convenience(global_loadparm), d, c1); } else if (c2 == '*') { memcpy(d, p1, strlen(p1)); d += strlen(p1); break; } else { - d += push_codepoint(global_smb_iconv_convenience, d, c2); + d += push_codepoint(lp_iconv_convenience(global_loadparm), d, c2); } p1 += c_size1; diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index f1d701b343..d9a60e3857 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -29,8 +29,9 @@ #include "includes.h" #include "vfs_posix.h" #include "system/dir.h" +#include "param/param.h" -/* +/** compare two filename components. This is where the name mangling hook will go */ static int component_compare(struct pvfs_state *pvfs, const char *comp, const char *name) @@ -256,7 +257,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, while (*p) { size_t c_size; - codepoint_t c = next_codepoint(global_smb_iconv_convenience, p, &c_size); + codepoint_t c = next_codepoint(lp_iconv_convenience(global_loadparm), p, &c_size); switch (c) { case '\\': if (name->has_wildcard) { @@ -340,7 +341,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t if (s == NULL) return NT_STATUS_NO_MEMORY; for (num_components=1, p=s; *p; p += c_size) { - c = next_codepoint(global_smb_iconv_convenience, p, &c_size); + c = next_codepoint(lp_iconv_convenience(global_loadparm), p, &c_size); if (c == '\\') num_components++; } @@ -352,7 +353,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t components[0] = s; for (i=0, p=s; *p; p += c_size) { - c = next_codepoint(global_smb_iconv_convenience, p, &c_size); + c = next_codepoint(lp_iconv_convenience(global_loadparm), p, &c_size); if (c == '\\') { *p = 0; components[++i] = p+1; diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 68e415000e..083a281819 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -388,7 +388,7 @@ static bool is_legal_name(struct pvfs_mangle_context *ctx, const char *name) { while (*name) { size_t c_size; - codepoint_t c = next_codepoint(global_smb_iconv_convenience, name, &c_size); + codepoint_t c = next_codepoint(lp_iconv_convenience(global_loadparm), name, &c_size); if (c == INVALID_CODEPOINT) { return false; } diff --git a/source4/ntvfs/posix/pvfs_util.c b/source4/ntvfs/posix/pvfs_util.c index b7cba00d9b..b52c3e387b 100644 --- a/source4/ntvfs/posix/pvfs_util.c +++ b/source4/ntvfs/posix/pvfs_util.c @@ -22,6 +22,7 @@ #include "includes.h" #include "vfs_posix.h" +#include "param/param.h" /* return true if a string contains one of the CIFS wildcard characters @@ -181,7 +182,7 @@ uint32_t pvfs_name_hash(const char *key, size_t length) while (*key && length--) { size_t c_size; - codepoint_t c = next_codepoint(global_smb_iconv_convenience, key, &c_size); + codepoint_t c = next_codepoint(lp_iconv_convenience(global_loadparm), key, &c_size); c = toupper_w(c); value *= fnv1_prime; value ^= (uint32_t)c; diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 5fdb7aada6..267f325dd4 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -83,8 +83,8 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); - push_string(global_smb_iconv_convenience, p+2, lp_netbios_name(ntvfs->ctx->lp_ctx), 15, STR_TERMINATE|STR_ASCII); - push_string(global_smb_iconv_convenience, p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); + push_string(lp_iconv_convenience(global_loadparm), p+2, lp_netbios_name(ntvfs->ctx->lp_ctx), 15, STR_TERMINATE|STR_ASCII); + push_string(lp_iconv_convenience(global_loadparm), p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } -- cgit From a2cea02584256e2cf59da5420e8e080e70c66939 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:17 +0100 Subject: r26430: require explicit specification of loadparm context. (This used to be commit 1b947fe0e6e16318e5a8127bb4932d6b5d20bcf6) --- source4/ntvfs/cifs/vfs_cifs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 178e9b01cc..9426355ecb 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -180,7 +180,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } - status = cli_credentials_set_machine_account(credentials); + status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 61873ce94c172c801a4831de5550a8e0fe54c5f5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:23 +0100 Subject: r26431: Require ndr_push creators to specify a iconv_convenience context. (This used to be commit 7352206f4450fdf881b95bda064cedd9d2477e4c) --- source4/ntvfs/common/notify.c | 3 ++- source4/ntvfs/common/opendb_tdb.c | 2 +- source4/ntvfs/ipc/ipc_rap.c | 9 +++++---- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 16cf4e4b54..187a349b4b 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -35,6 +35,7 @@ #include "ntvfs/common/ntvfs_common.h" #include "ntvfs/sysdep/sys_notify.h" #include "cluster/cluster.h" +#include "param/param.h" struct notify_context { struct tdb_wrap *w; @@ -95,7 +96,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, return NULL; } - notify->w = cluster_tdb_tmp_open(notify, "notify.tdb", TDB_SEQNUM); + notify->w = cluster_tdb_tmp_open(notify, global_loadparm, "notify.tdb", TDB_SEQNUM); if (notify->w == NULL) { talloc_free(notify); return NULL; diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index b8b8a5cb33..41b5ad2ebe 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -79,7 +79,7 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, return NULL; } - odb->w = cluster_tdb_tmp_open(odb, "openfiles.tdb", TDB_DEFAULT); + odb->w = cluster_tdb_tmp_open(odb, ntvfs_ctx->lp_ctx, "openfiles.tdb", TDB_DEFAULT); if (odb->w == NULL) { talloc_free(odb); return NULL; diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index d8e9812dd8..0636e42e16 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -23,6 +23,7 @@ #include "libcli/rap/rap.h" #include "ntvfs/ipc/proto.h" #include "librpc/ndr/libndr.h" +#include "param/param.h" #define NDR_RETURN(call) do { \ enum ndr_err_code _ndr_err; \ @@ -444,8 +445,8 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) NDR_RETURN(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, &call->datadesc)); - call->ndr_push_param = ndr_push_init_ctx(call); - call->ndr_push_data = ndr_push_init_ctx(call); + call->ndr_push_param = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); + call->ndr_push_data = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); if ((call->ndr_push_param == NULL) || (call->ndr_push_data == NULL)) return NT_STATUS_NO_MEMORY; @@ -470,8 +471,8 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) result_param = ndr_push_blob(call->ndr_push_param); result_data = ndr_push_blob(call->ndr_push_data); - final_param = ndr_push_init_ctx(call); - final_data = ndr_push_init_ctx(call); + final_param = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); + final_data = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); if ((final_param == NULL) || (final_data == NULL)) return NT_STATUS_NO_MEMORY; -- cgit From d1e716cf4331bf09cfe15a6634bc5887aff81d20 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:27 +0100 Subject: r26432: Require ndr_pull users to specify iconv_convenience. (This used to be commit 28b1d36551b75241c1cf9fca5d74f45a6dc884ab) --- source4/ntvfs/ipc/ipc_rap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 0636e42e16..85bc5c212f 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -116,10 +116,10 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, call->mem_ctx = mem_ctx; - call->ndr_pull_param = ndr_pull_init_blob(&trans->in.params, mem_ctx); + call->ndr_pull_param = ndr_pull_init_blob(&trans->in.params, mem_ctx, lp_iconv_convenience(global_loadparm)); call->ndr_pull_param->flags = RAPNDR_FLAGS; - call->ndr_pull_data = ndr_pull_init_blob(&trans->in.data, mem_ctx); + call->ndr_pull_data = ndr_pull_init_blob(&trans->in.data, mem_ctx, lp_iconv_convenience(global_loadparm)); call->ndr_pull_data->flags = RAPNDR_FLAGS; call->heap = talloc(mem_ctx, struct rap_string_heap); -- cgit From e31abef15f7696cf39e9e81307f153da93568e02 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 13 Dec 2007 22:46:55 +0100 Subject: r26440: Remove more uses of global_loadparm. (This used to be commit 8858cf39722f192865e531164c72039fd18d7a8d) --- source4/ntvfs/common/notify.c | 3 ++- source4/ntvfs/ipc/rap_server.c | 2 +- source4/ntvfs/posix/vfs_posix.c | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 187a349b4b..8bbf2d04b3 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -82,6 +82,7 @@ static int notify_destructor(struct notify_context *notify) */ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, struct messaging_context *messaging_ctx, + struct loadparm_context *lp_ctx, struct event_context *ev, struct share_config *scfg) { @@ -96,7 +97,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, return NULL; } - notify->w = cluster_tdb_tmp_open(notify, global_loadparm, "notify.tdb", TDB_SEQNUM); + notify->w = cluster_tdb_tmp_open(notify, lp_ctx, "notify.tdb", TDB_SEQNUM); if (notify->w == NULL) { talloc_free(notify); return NULL; diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 9113bef894..7d3020a259 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -41,7 +41,7 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, r->out.available = 0; r->out.info = NULL; - nterr = share_get_context_by_name(mem_ctx, lp_share_backend(global_loadparm), &sctx); + nterr = share_get_context_by_name(mem_ctx, lp_share_backend(global_loadparm), global_loadparm, &sctx); if (!NT_STATUS_IS_OK(nterr)) { return nterr; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 8e5e5a6942..e058e6f546 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -214,6 +214,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->notify_context = notify_init(pvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, + pvfs->ntvfs->ctx->lp_ctx, event_context_find(pvfs), pvfs->ntvfs->ctx->config); -- cgit From 96a200511e884a88dcf48fa5b313b2cddb2df566 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 14 Dec 2007 00:27:31 +0100 Subject: r26443: Remove global_loadparm instances. (This used to be commit 8242c696235d1bfb402b5c276a57f36d93610545) --- source4/ntvfs/posix/pvfs_resolve.c | 2 +- source4/ntvfs/print/vfs_print.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index d9a60e3857..949fa131a4 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -257,7 +257,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, while (*p) { size_t c_size; - codepoint_t c = next_codepoint(lp_iconv_convenience(global_loadparm), p, &c_size); + codepoint_t c = next_codepoint(lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), p, &c_size); switch (c) { case '\\': if (name->has_wildcard) { diff --git a/source4/ntvfs/print/vfs_print.c b/source4/ntvfs/print/vfs_print.c index 267f325dd4..aa9b11a973 100644 --- a/source4/ntvfs/print/vfs_print.c +++ b/source4/ntvfs/print/vfs_print.c @@ -83,8 +83,8 @@ static NTSTATUS print_ioctl(struct ntvfs_module_context *ntvfs, p = (char *)io->ioctl.out.blob.data; SSVAL(p,0, 1 /* REWRITE: fsp->rap_print_jobid */); - push_string(lp_iconv_convenience(global_loadparm), p+2, lp_netbios_name(ntvfs->ctx->lp_ctx), 15, STR_TERMINATE|STR_ASCII); - push_string(lp_iconv_convenience(global_loadparm), p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); + push_string(lp_iconv_convenience(ntvfs->ctx->lp_ctx), p+2, lp_netbios_name(ntvfs->ctx->lp_ctx), 15, STR_TERMINATE|STR_ASCII); + push_string(lp_iconv_convenience(ntvfs->ctx->lp_ctx), p+18, ntvfs->ctx->config->name, 13, STR_TERMINATE|STR_ASCII); return NT_STATUS_OK; } -- cgit From be33f4c611d37ebba59ff618033dc73601339ad1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 23:54:30 -0600 Subject: r26576: Allow the static module loading code to be used for the Python modules. Simplify the way module initialization functions are handled. (This used to be commit ba8be2dfc0de4434c798663336b81f7f95cde520) --- source4/ntvfs/ntvfs_base.c | 2 +- source4/ntvfs/sysdep/sys_notify.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 28f43eabe8..d4ae6c8b4f 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -202,7 +202,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { static bool initialized = false; - init_module_fn static_init[] = STATIC_ntvfs_MODULES; + init_module_fn static_init[] = { STATIC_ntvfs_MODULES, NULL }; init_module_fn *shared_init; if (initialized) return NT_STATUS_OK; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 1664461d33..a6d0a698bc 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -125,7 +125,7 @@ _PUBLIC_ NTSTATUS sys_notify_init(void) { static bool initialized = false; - init_module_fn static_init[] = STATIC_sys_notify_MODULES; + init_module_fn static_init[] = { STATIC_sys_notify_MODULES, NULL }; init_module_fn *shared_init; if (initialized) return NT_STATUS_OK; -- cgit From c13ae707313c5bf9819a75c1699d099565d2494d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Dec 2007 01:28:22 -0600 Subject: r26580: Include sentinel in build.h, in case the list is empty. (This used to be commit f1997dabed584bdc864c4b7235c29603c312ef46) --- source4/ntvfs/ntvfs_base.c | 2 +- source4/ntvfs/sysdep/sys_notify.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index d4ae6c8b4f..f5a24f23a0 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -202,7 +202,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { static bool initialized = false; - init_module_fn static_init[] = { STATIC_ntvfs_MODULES, NULL }; + init_module_fn static_init[] = { STATIC_ntvfs_MODULES }; init_module_fn *shared_init; if (initialized) return NT_STATUS_OK; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index a6d0a698bc..2ed9908af7 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -125,7 +125,7 @@ _PUBLIC_ NTSTATUS sys_notify_init(void) { static bool initialized = false; - init_module_fn static_init[] = { STATIC_sys_notify_MODULES, NULL }; + init_module_fn static_init[] = { STATIC_sys_notify_MODULES }; init_module_fn *shared_init; if (initialized) return NT_STATUS_OK; -- cgit From 86dc05e99f124db47f2743d1fc23117a7f5145ab Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:05 -0600 Subject: r26638: libndr: Require explicitly specifying iconv_convenience for ndr_struct_push_blob(). (This used to be commit 61ad78ac98937ef7a9aa32075a91a1c95b7606b3) --- source4/ntvfs/common/notify.c | 5 ++--- source4/ntvfs/common/opendb_tdb.c | 2 +- source4/ntvfs/posix/pvfs_xattr.c | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 8bbf2d04b3..ad0a55da79 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -219,7 +219,7 @@ static NTSTATUS notify_save(struct notify_context *notify) tmp_ctx = talloc_new(notify); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->array, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), notify->array, (ndr_push_flags_fn_t)ndr_push_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -554,8 +554,7 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, tmp_ctx = talloc_new(notify); - ndr_err = ndr_push_struct_blob(&data, tmp_ctx, &ev, - (ndr_push_flags_fn_t)ndr_push_notify_event); + ndr_err = ndr_push_struct_blob(&data, tmp_ctx, lp_iconv_convenience(global_loadparm), &ev, (ndr_push_flags_fn_t)ndr_push_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); return; diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 41b5ad2ebe..7408f3a3df 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -233,7 +233,7 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) return NT_STATUS_OK; } - ndr_err = ndr_push_struct_blob(&blob, lck, file, (ndr_push_flags_fn_t)ndr_push_opendb_file); + ndr_err = ndr_push_struct_blob(&blob, lck, lp_iconv_convenience(global_loadparm), file, (ndr_push_flags_fn_t)ndr_push_opendb_file); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index f723aad955..c0a04b4099 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -23,6 +23,7 @@ #include "vfs_posix.h" #include "lib/util/unix_privs.h" #include "librpc/gen_ndr/ndr_xattr.h" +#include "param/param.h" /* pull a xattr as a blob @@ -138,7 +139,7 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, NTSTATUS status; enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, p, (ndr_push_flags_fn_t)push_fn); + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(global_loadparm), p, (ndr_push_flags_fn_t)push_fn); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); return ndr_map_error2ntstatus(ndr_err); -- cgit From 7d5f0e0893d42b56145a3ffa34e3b4b9906cbd91 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 1 Jan 2008 22:05:13 -0600 Subject: r26639: librpc: Pass iconv convenience on from RPC connection to NDR library, so it can be overridden by OpenChange. (This used to be commit 2f29f80e07adef1f020173f2cd6d947d0ef505ce) --- source4/ntvfs/common/notify.c | 5 +++-- source4/ntvfs/common/opendb_tdb.c | 2 +- source4/ntvfs/posix/pvfs_xattr.c | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index ad0a55da79..94d32488eb 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -171,7 +171,8 @@ static NTSTATUS notify_load(struct notify_context *notify) blob.data = dbuf.dptr; blob.length = dbuf.dsize; - ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->array, + ndr_err = ndr_pull_struct_blob(&blob, notify->array, lp_iconv_convenience(global_loadparm), + notify->array, (ndr_pull_flags_fn_t)ndr_pull_notify_array); free(dbuf.dptr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -255,7 +256,7 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data return; } - ndr_err = ndr_pull_struct_blob(data, tmp_ctx, &ev, + ndr_err = ndr_pull_struct_blob(data, tmp_ctx, lp_iconv_convenience(global_loadparm), &ev, (ndr_pull_flags_fn_t)ndr_pull_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 7408f3a3df..9bb6784df3 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -205,7 +205,7 @@ static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) blob.data = dbuf.dptr; blob.length = dbuf.dsize; - ndr_err = ndr_pull_struct_blob(&blob, lck, file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); + ndr_err = ndr_pull_struct_blob(&blob, lck, lp_iconv_convenience(global_loadparm), file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); free(dbuf.dptr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index c0a04b4099..39090bf702 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -117,7 +117,8 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, } /* pull the blob */ - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, p, (ndr_pull_flags_fn_t)pull_fn); + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), + p, (ndr_pull_flags_fn_t)pull_fn); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } -- cgit From 771b347f9b185895390445be96081c781e28a26d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Jan 2008 18:39:01 -0600 Subject: r26644: Janitorial: Pass resolve_context explicitly to various SMB functions, should help fix the build for OpenChange. (This used to be commit 385ffe4f4cc9a21a760c0f00410f56e2592fd507) --- source4/ntvfs/cifs/vfs_cifs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 9426355ecb..adfea6d2a2 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -32,6 +32,7 @@ #include "ntvfs/ntvfs.h" #include "lib/util/dlinklist.h" #include "param/param.h" +#include "libcli/resolve/resolve.h" struct cvfs_file { struct cvfs_file *prev, *next; @@ -202,7 +203,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.service = remote_share; io.in.service_type = "?????"; - creq = smb_composite_connect_send(&io, private, ntvfs->ctx->event_ctx); + creq = smb_composite_connect_send(&io, private, + lp_resolve_context(ntvfs->ctx->lp_ctx), + ntvfs->ctx->event_ctx); status = smb_composite_connect_recv(creq, private); NT_STATUS_NOT_OK_RETURN(status); -- cgit From 969b8579c755441092e27b499ecedbd7d725816d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Jan 2008 18:39:15 -0600 Subject: r26646: libcli/smb_composite: Allow specifying SMB parameters in smb_composite_connect structure. AFAIK no global variables will now be used when doing RPC client connections. (This used to be commit 0ef75e4e3cb0e1bd10e367a00f5e9b725587c40a) --- source4/ntvfs/cifs/vfs_cifs.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index adfea6d2a2..0b4cbb8a13 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -202,6 +202,12 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.workgroup = lp_workgroup(ntvfs->ctx->lp_ctx); io.in.service = remote_share; io.in.service_type = "?????"; + io.in.max_xmit = lp_max_xmit(ntvfs->ctx->lp_ctx); + io.in.max_mux = lp_maxmux(ntvfs->ctx->lp_ctx); + io.in.ntstatus_support = lp_nt_status_support(ntvfs->ctx->lp_ctx); + io.in.max_protocol = lp_cli_maxprotocol(ntvfs->ctx->lp_ctx); + io.in.unicode = lp_unicode(ntvfs->ctx->lp_ctx); + io.in.use_spnego = lp_use_spnego(ntvfs->ctx->lp_ctx) && lp_nt_status_support(ntvfs->ctx->lp_ctx); creq = smb_composite_connect_send(&io, private, lp_resolve_context(ntvfs->ctx->lp_ctx), -- cgit From 425732f688865ebe2bfe568c8278edec50cbdedf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Jan 2008 17:21:58 -0600 Subject: r26651: libsmb: Allow specifying signing policy from higher up. The number of arguments is getting a bit excessive now, so it probably makes sense to pass in the smbcli_options struct rather than all members individually and add a convenience function for obtaining a smbcli_options struct from a loadparm context. (This used to be commit 9f64213463b5bf3bcbf36913139e9a5042e967a2) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 0b4cbb8a13..0b0c9b1037 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -208,6 +208,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.max_protocol = lp_cli_maxprotocol(ntvfs->ctx->lp_ctx); io.in.unicode = lp_unicode(ntvfs->ctx->lp_ctx); io.in.use_spnego = lp_use_spnego(ntvfs->ctx->lp_ctx) && lp_nt_status_support(ntvfs->ctx->lp_ctx); + io.in.signing = lp_client_signing(ntvfs->ctx->lp_ctx); creq = smb_composite_connect_send(&io, private, lp_resolve_context(ntvfs->ctx->lp_ctx), -- cgit From dcc282590b34537fc1ead61c3300172528273b44 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 3 Jan 2008 17:22:12 -0600 Subject: r26654: libcli/smb_composite: Rather than specifying each of the gazillion options for SMB individually, just specify the smbcli_options struct. (This used to be commit 8a97886e24a4b969aa91409c06f423b71a45f6eb) --- source4/ntvfs/cifs/vfs_cifs.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 0b0c9b1037..910401f157 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -202,13 +202,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.workgroup = lp_workgroup(ntvfs->ctx->lp_ctx); io.in.service = remote_share; io.in.service_type = "?????"; - io.in.max_xmit = lp_max_xmit(ntvfs->ctx->lp_ctx); - io.in.max_mux = lp_maxmux(ntvfs->ctx->lp_ctx); - io.in.ntstatus_support = lp_nt_status_support(ntvfs->ctx->lp_ctx); - io.in.max_protocol = lp_cli_maxprotocol(ntvfs->ctx->lp_ctx); - io.in.unicode = lp_unicode(ntvfs->ctx->lp_ctx); - io.in.use_spnego = lp_use_spnego(ntvfs->ctx->lp_ctx) && lp_nt_status_support(ntvfs->ctx->lp_ctx); - io.in.signing = lp_client_signing(ntvfs->ctx->lp_ctx); + lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); creq = smb_composite_connect_send(&io, private, lp_resolve_context(ntvfs->ctx->lp_ctx), -- cgit From 2da3464080e1a45f5c76231668a546ad7f10e790 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 15:36:37 -0600 Subject: r26670: Janitorial: Remove global_loadparm uses. (This used to be commit 13cc6ca1d3c2b5899bdd02c4c7306a92baa260f5) --- source4/ntvfs/common/opendb_tdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 9bb6784df3..abd9ca708b 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -205,7 +205,7 @@ static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file) blob.data = dbuf.dptr; blob.length = dbuf.dsize; - ndr_err = ndr_pull_struct_blob(&blob, lck, lp_iconv_convenience(global_loadparm), file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); + ndr_err = ndr_pull_struct_blob(&blob, lck, lp_iconv_convenience(lck->odb->ntvfs_ctx->lp_ctx), file, (ndr_pull_flags_fn_t)ndr_pull_opendb_file); free(dbuf.dptr); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); @@ -233,7 +233,7 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) return NT_STATUS_OK; } - ndr_err = ndr_push_struct_blob(&blob, lck, lp_iconv_convenience(global_loadparm), file, (ndr_push_flags_fn_t)ndr_push_opendb_file); + ndr_err = ndr_push_struct_blob(&blob, lck, lp_iconv_convenience(lck->odb->ntvfs_ctx->lp_ctx), file, (ndr_push_flags_fn_t)ndr_push_opendb_file); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } -- cgit From df408d056ec03f2abe08ce0ea487e1875b90e7bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Jan 2008 19:03:43 -0600 Subject: r26672: Janitorial: Remove uses of global_loadparm. (This used to be commit 18cd08623eaad7d2cd63b82ea5275d4dfd21cf00) --- source4/ntvfs/ipc/ipc_rap.c | 26 ++++++++++++++++---------- source4/ntvfs/ipc/rap_server.c | 4 +++- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/sysdep/sys_notify.c | 6 ------ 4 files changed, 20 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index 85bc5c212f..faf48705c4 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -82,6 +82,8 @@ static void rap_heap_restore(struct rap_string_heap *heap, } struct rap_call { + struct loadparm_context *lp_ctx; + TALLOC_CTX *mem_ctx; uint16_t callno; const char *paramdesc; @@ -103,6 +105,7 @@ struct rap_call { #define RAPNDR_FLAGS (LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, struct smb_trans2 *trans) { struct rap_call *call; @@ -114,12 +117,14 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(call); + call->lp_ctx = talloc_reference(call, lp_ctx); + call->mem_ctx = mem_ctx; - call->ndr_pull_param = ndr_pull_init_blob(&trans->in.params, mem_ctx, lp_iconv_convenience(global_loadparm)); + call->ndr_pull_param = ndr_pull_init_blob(&trans->in.params, mem_ctx, lp_iconv_convenience(lp_ctx)); call->ndr_pull_param->flags = RAPNDR_FLAGS; - call->ndr_pull_data = ndr_pull_init_blob(&trans->in.data, mem_ctx, lp_iconv_convenience(global_loadparm)); + call->ndr_pull_data = ndr_pull_init_blob(&trans->in.data, mem_ctx, lp_iconv_convenience(lp_ctx)); call->ndr_pull_data->flags = RAPNDR_FLAGS; call->heap = talloc(mem_ctx, struct rap_string_heap); @@ -266,7 +271,7 @@ static NTSTATUS _rap_netshareenum(struct rap_call *call) break; } - result = rap_netshareenum(call, &r); + result = rap_netshareenum(call, call->lp_ctx, &r); if (!NT_STATUS_IS_OK(result)) return result; @@ -348,7 +353,7 @@ static NTSTATUS _rap_netserverenum2(struct rap_call *call) break; } - result = rap_netserverenum2(call, &r); + result = rap_netserverenum2(call, call->lp_ctx, &r); if (!NT_STATUS_IS_OK(result)) return result; @@ -425,7 +430,8 @@ static const struct {NULL, -1, api_Unsupported} }; -NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) +NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct smb_trans2 *trans) { int i; NTSTATUS result; @@ -434,7 +440,7 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) struct ndr_push *final_param; struct ndr_push *final_data; - call = new_rap_srv_call(mem_ctx, trans); + call = new_rap_srv_call(mem_ctx, lp_ctx, trans); if (call == NULL) return NT_STATUS_NO_MEMORY; @@ -445,8 +451,8 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) NDR_RETURN(ndr_pull_string(call->ndr_pull_param, NDR_SCALARS, &call->datadesc)); - call->ndr_push_param = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); - call->ndr_push_data = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); + call->ndr_push_param = ndr_push_init_ctx(call, lp_iconv_convenience(lp_ctx)); + call->ndr_push_data = ndr_push_init_ctx(call, lp_iconv_convenience(lp_ctx)); if ((call->ndr_push_param == NULL) || (call->ndr_push_data == NULL)) return NT_STATUS_NO_MEMORY; @@ -471,8 +477,8 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct smb_trans2 *trans) result_param = ndr_push_blob(call->ndr_push_param); result_data = ndr_push_blob(call->ndr_push_data); - final_param = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); - final_data = ndr_push_init_ctx(call, lp_iconv_convenience(global_loadparm)); + final_param = ndr_push_init_ctx(call, lp_iconv_convenience(lp_ctx)); + final_data = ndr_push_init_ctx(call, lp_iconv_convenience(lp_ctx)); if ((final_param == NULL) || (final_data == NULL)) return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 7d3020a259..633f0bf36e 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -29,6 +29,7 @@ * idea. */ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, struct rap_NetShareEnum *r) { NTSTATUS nterr; @@ -41,7 +42,7 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, r->out.available = 0; r->out.info = NULL; - nterr = share_get_context_by_name(mem_ctx, lp_share_backend(global_loadparm), global_loadparm, &sctx); + nterr = share_get_context_by_name(mem_ctx, lp_share_backend(lp_ctx), lp_ctx, &sctx); if (!NT_STATUS_IS_OK(nterr)) { return nterr; } @@ -75,6 +76,7 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, } NTSTATUS rap_netserverenum2(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, struct rap_NetServerEnum2 *r) { r->out.status = 0; diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index b69fb98c5d..81cd984f0b 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -805,7 +805,7 @@ static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) - return ipc_rap_call(req, trans); + return ipc_rap_call(req, ntvfs->ctx->lp_ctx, trans); if (trans->in.setup_count != 2) { return NT_STATUS_INVALID_PARAMETER; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 2ed9908af7..84ba745f5b 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -126,17 +126,11 @@ _PUBLIC_ NTSTATUS sys_notify_init(void) static bool initialized = false; init_module_fn static_init[] = { STATIC_sys_notify_MODULES }; - init_module_fn *shared_init; if (initialized) return NT_STATUS_OK; initialized = true; - shared_init = load_samba_modules(NULL, global_loadparm, "sys_notify"); - run_init_functions(static_init); - run_init_functions(shared_init); - - talloc_free(shared_init); return NT_STATUS_OK; } -- cgit From 03023c4f7d8c7bc6716982db86e8167f1ac6331b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 20 Jan 2008 16:28:43 +0100 Subject: build: Demote a bunch of libraries to subsystems. This makes packaging easier and should also make it easier to migrate to a new build system. (This used to be commit 77b400764e3dadfa05407343af649ad9298cc085) --- source4/ntvfs/config.mk | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index ae8d5d9b4a..017614b7be 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -79,11 +79,8 @@ OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS -[LIBRARY::ntvfs] +[SUBSYSTEM::ntvfs] PUBLIC_HEADERS = ntvfs.h -VERSION = 0.0.1 -SO_VERSION = 0 -DESCRIPTION = Virtual File System with NTFS semantics PRIVATE_PROTO_HEADER = ntvfs_proto.h OBJ_FILES = \ ntvfs_base.o \ -- cgit From cb2f8d6cf4e6739f9dd5b4a9b21c9fbb4fb59609 Mon Sep 17 00:00:00 2001 From: Amin Azez Date: Tue, 29 Jan 2008 16:10:48 +0000 Subject: Fix open file tracking in vfs_cifs so that oplock breaks can propagate Oplock breaks were not propagating because the list of open files was not being maintained. This fixes that based on best-guess of how it should work. It has been tested manually with windows XP client obtaining an oplock from a windows 2003 server, which then broke the lock when smbclient read the same file. Previously the smbclient read blocked until the oplock timed out (This used to be commit 1a53aeff9a9e8fe83fde5a617463a5b363c45313) --- source4/ntvfs/cifs/vfs_cifs.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 910401f157..901dd2cf7c 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -64,12 +64,16 @@ struct async_info { #define SETUP_PID private->tree->session->pid = req->smbpid -#define SETUP_FILE do { \ - struct cvfs_file *f; \ +#define SETUP_FILE_HERE(f) do { \ f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \ if (!f) return NT_STATUS_INVALID_HANDLE; \ io->generic.in.file.fnum = f->fnum; \ -} while (0) +} while (0) + +#define SETUP_FILE do { \ + struct cvfs_file *f; \ + SETUP_FILE_HERE(f); \ +} while (0) #define SETUP_PID_AND_FILE do { \ SETUP_PID; \ @@ -484,6 +488,7 @@ static void async_open(struct smbcli_request *c_req) req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f); if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; file->ntvfs = f->h; + DLIST_ADD(cvfs->files, f); failed: req->async_states->send_fn(req); } @@ -526,6 +531,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f); NT_STATUS_NOT_OK_RETURN(status); file->ntvfs = f->h; + DLIST_ADD(private->files, f); return NT_STATUS_OK; } @@ -752,6 +758,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; + struct cvfs_file *f; SETUP_PID; @@ -759,7 +766,12 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, private->map_generic) { return ntvfs_map_close(ntvfs, req, io); } - SETUP_FILE; + SETUP_FILE_HERE(f); + /* Note, we aren't free-ing f, or it's h here. Should we? + even if file-close fails, we'll remove it from the list, + what else would we do? Maybe we should not remove until + after the proxied call completes? */ + DLIST_REMOVE(private->files, f); if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_close(private->tree, io); -- cgit From e94d710b0b959d8e69eb02ef0704ebcff56485fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 10:13:28 +1100 Subject: updated SMB2 tcon as per WSPP docs (This used to be commit 5913e3e549e71affc66c28cacb6563331fb0c790) --- source4/ntvfs/ntvfs.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index fe5f956426..a708dbff51 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -32,9 +32,11 @@ struct ntvfs_module_context; struct ntvfs_request; /* each backend has to be one one of the following 3 basic types. In - * earlier versions of Samba backends needed to handle all types, now - * we implement them separately. */ -enum ntvfs_type {NTVFS_DISK, NTVFS_PRINT, NTVFS_IPC}; + earlier versions of Samba backends needed to handle all types, now + we implement them separately. + The values 1..3 match the SMB2 SMB2_SHARE_TYPE_* values + */ +enum ntvfs_type {NTVFS_DISK=1, NTVFS_IPC=2, NTVFS_PRINT=3}; /* the ntvfs operations structure - contains function pointers to the backend implementations of each operation */ -- cgit From 88d2e0522737fb8856fb0f52c2af8a2f56130f19 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 15:05:44 +1100 Subject: updated SMB2 create operation to match WSPP. Adding some defined for various new create options (This used to be commit d037dc23ced3df6bce98cbf4810fb5f1247336bd) --- source4/ntvfs/ipc/vfs_ipc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 81cd984f0b..92f0eadae1 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -322,7 +322,7 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs, NT_STATUS_NOT_OK_RETURN(status); oi->smb2.out.file.ntvfs = p->handle; - oi->smb2.out.oplock_flags = oi->smb2.in.oplock_flags; + oi->smb2.out.oplock_level = oi->smb2.in.oplock_level; oi->smb2.out.create_action = NTCREATEX_ACTION_EXISTED; oi->smb2.out.create_time = 0; oi->smb2.out.access_time = 0; @@ -331,7 +331,7 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs, oi->smb2.out.alloc_size = 4096; oi->smb2.out.size = 0; oi->smb2.out.file_attr = FILE_ATTRIBUTE_NORMAL; - oi->smb2.out._pad = 0; + oi->smb2.out.reserved2 = 0; oi->smb2.out.blob = data_blob(NULL, 0); return status; -- cgit From 158bd784fc235cc34287971ee04107742dc40cca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 Feb 2008 17:36:41 +1100 Subject: missed another spot in the SMB2 create conversion (This used to be commit df82b0aa6990b59cde20893cb690a8a260526178) --- source4/ntvfs/ntvfs_generic.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 7708f4fc80..5092e732b4 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -208,7 +208,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; - io->smb2.out.oplock_flags = 0; + io->smb2.out.oplock_level = 0; io->smb2.out.create_action = io2->generic.out.create_action; io->smb2.out.create_time = io2->generic.out.create_time; io->smb2.out.access_time = io2->generic.out.access_time; @@ -217,7 +217,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, io->smb2.out.alloc_size = io2->generic.out.alloc_size; io->smb2.out.size = io2->generic.out.size; io->smb2.out.file_attr = io2->generic.out.attrib; - io->smb2.out._pad = 0; + io->smb2.out.reserved2 = 0; io->smb2.out.blob = data_blob(NULL, 0); break; @@ -486,13 +486,13 @@ _PUBLIC_ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io2->generic.in.flags = 0; io2->generic.in.root_fid = 0; - io2->generic.in.access_mask = io->smb2.in.access_mask; + io2->generic.in.access_mask = io->smb2.in.desired_access; io2->generic.in.alloc_size = 0; - io2->generic.in.file_attr = io->smb2.in.file_attr; + io2->generic.in.file_attr = io->smb2.in.file_attributes; io2->generic.in.share_access = io->smb2.in.share_access; - io2->generic.in.open_disposition= io->smb2.in.open_disposition; + io2->generic.in.open_disposition= io->smb2.in.create_disposition; io2->generic.in.create_options = io->smb2.in.create_options; - io2->generic.in.impersonation = io->smb2.in.impersonation; + io2->generic.in.impersonation = io->smb2.in.impersonation_level; io2->generic.in.security_flags = 0; io2->generic.in.fname = io->smb2.in.fname; io2->generic.in.sec_desc = NULL; -- cgit From 839ab724dc2d204bfbb0693aeed64f6f83a4266b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 12:30:31 +1100 Subject: Fixed SMB2 rename operations from Vista clients We needed a flag in bufinfo to mark packets as SMB2, as it seems that SMB2 uses a different format for the RenameInformation buffer than SMB does Also handle the fact that SMB2 clients give the full path to the target file in the rename, not a relative path (This used to be commit 52d7972d95ddc19d22a4187b4d4428a6c3ed32d5) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 37 ++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 340913cd4d..2a936ad8a7 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -63,6 +63,10 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) } break; + case RAW_SFILEINFO_RENAME_INFORMATION: + needed = SEC_STD_DELETE; + break; + default: needed = SEC_FILE_WRITE_ATTRIBUTE; break; @@ -84,7 +88,8 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, char *new_name, *p; /* renames are only allowed within a directory */ - if (strchr_m(info->rename_information.in.new_name, '\\')) { + if (strchr_m(info->rename_information.in.new_name, '\\') && + (req->ctx->protocol != PROTOCOL_SMB2)) { return NT_STATUS_NOT_SUPPORTED; } @@ -100,22 +105,28 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, /* w2k3 does not appear to allow relative rename */ if (info->rename_information.in.root_fid != 0) { - return NT_STATUS_INVALID_PARAMETER; + DEBUG(1,("WARNING: got invalid root_fid in rename_information.\n")); } /* construct the fully qualified windows name for the new file name */ - new_name = talloc_strdup(req, name->original_name); - if (new_name == NULL) { - return NT_STATUS_NO_MEMORY; - } - p = strrchr_m(new_name, '\\'); - if (p == NULL) { - return NT_STATUS_OBJECT_NAME_INVALID; - } - *p = 0; + if (req->ctx->protocol == PROTOCOL_SMB2) { + /* SMB2 sends the full path of the new name */ + new_name = talloc_asprintf(req, "\\%s", info->rename_information.in.new_name); + } else { + new_name = talloc_strdup(req, name->original_name); + if (new_name == NULL) { + return NT_STATUS_NO_MEMORY; + } + p = strrchr_m(new_name, '\\'); + if (p == NULL) { + return NT_STATUS_OBJECT_NAME_INVALID; + } else { + *p = 0; + } - new_name = talloc_asprintf(req, "%s\\%s", new_name, - info->rename_information.in.new_name); + new_name = talloc_asprintf(req, "%s\\%s", new_name, + info->rename_information.in.new_name); + } if (new_name == NULL) { return NT_STATUS_NO_MEMORY; } -- cgit From 039f85835d60ae48c4176891598cf24e18d0cd0a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 12:50:11 +1100 Subject: we need to refuse a root_fid in rename on SMB but not SMB2 (This used to be commit 9a139c35b7f1326616d26ce13bbdc7d6b22cd9b5) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 2a936ad8a7..ce977873c8 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -103,9 +103,11 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_INVALID_PARAMETER; } - /* w2k3 does not appear to allow relative rename */ - if (info->rename_information.in.root_fid != 0) { - DEBUG(1,("WARNING: got invalid root_fid in rename_information.\n")); + /* w2k3 does not appear to allow relative rename. On SMB2, vista sends it sometimes, + but I suspect it is just uninitialised memory */ + if (info->rename_information.in.root_fid != 0 && + (req->ctx->protocol != PROTOCOL_SMB2)) { + return NT_STATUS_INVALID_PARAMETER; } /* construct the fully qualified windows name for the new file name */ -- cgit From 4a04a5e620a4666fc123d04cb96ef391de72c469 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 14:54:21 +1100 Subject: A better way to handle the different format of RenameInformation in SMB2 We now define a separate info level RAW_SFILEINFO_RENAME_INFORMATION_SMB2 and set that level when handling SMB2 packets. This makes the parsers clearer. (This used to be commit f6cdf3f1177f63d80be757f007eb15380839b4f5) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index ce977873c8..9c78699edb 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -64,6 +64,7 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) break; case RAW_SFILEINFO_RENAME_INFORMATION: + case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: needed = SEC_STD_DELETE; break; @@ -382,6 +383,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, break; case RAW_SFILEINFO_RENAME_INFORMATION: + case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: return pvfs_setfileinfo_rename(pvfs, req, h->name, info); @@ -579,6 +581,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; case RAW_SFILEINFO_RENAME_INFORMATION: + case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: return pvfs_setfileinfo_rename(pvfs, req, name, info); -- cgit From 602f4635da0935abffdda2a29ec302a775fdbe62 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 19:06:17 +0100 Subject: Get rid of 'INTEGRATED' build of modules - now replaced by 'MERGED_OBJ' (This used to be commit 269cbf84d8b7dbf3bc88adc04ae283dc908af5ac) --- source4/ntvfs/posix/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 6588be11ae..6879940337 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -31,7 +31,7 @@ PRIVATE_DEPENDENCIES = LIBAIO_LINUX # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] SUBSYSTEM = ntvfs -OUTPUT_TYPE = INTEGRATED +OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init PRIVATE_PROTO_HEADER = vfs_posix_proto.h OBJ_FILES = \ -- cgit From ff0315ba859421dff6aba055887e086fa68c2951 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 18 Feb 2008 20:04:18 +0100 Subject: Rename include to mkinclude to emphasize it is different from make's include. (This used to be commit 0e1d0a874ae3d22b8f97a79b81fe0af3ef53a771) --- source4/ntvfs/config.mk | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 017614b7be..dbc1a4c277 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -1,8 +1,8 @@ # NTVFS Server subsystem -include posix/config.mk -include common/config.mk -include unixuid/config.mk -include sysdep/config.mk +mkinclude posix/config.mk +mkinclude common/config.mk +mkinclude unixuid/config.mk +mkinclude sysdep/config.mk ################################################ # Start MODULE ntvfs_cifs -- cgit From d9f8232c34a695df04a5240e270dd7ffc3101c0e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 15:21:45 +0100 Subject: Remove more uses of global_loadparm. (This used to be commit 230355d2e6e27918dff40823eb238904c7a1870e) --- source4/ntvfs/posix/pvfs_rename.c | 14 ++++++++------ source4/ntvfs/posix/pvfs_resolve.c | 5 +++-- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 3b9842db7f..ea12f49333 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -89,6 +89,7 @@ NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *nam resolve a wildcard rename pattern. This works on one component of the name */ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, const char *fname, const char *pattern) { @@ -108,16 +109,16 @@ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, while (*p2) { codepoint_t c1, c2; size_t c_size1, c_size2; - c1 = next_codepoint(lp_iconv_convenience(global_loadparm), p1, &c_size1); - c2 = next_codepoint(lp_iconv_convenience(global_loadparm), p2, &c_size2); + c1 = next_codepoint(iconv_convenience, p1, &c_size1); + c2 = next_codepoint(iconv_convenience, p2, &c_size2); if (c2 == '?') { - d += push_codepoint(lp_iconv_convenience(global_loadparm), d, c1); + d += push_codepoint(iconv_convenience, d, c1); } else if (c2 == '*') { memcpy(d, p1, strlen(p1)); d += strlen(p1); break; } else { - d += push_codepoint(lp_iconv_convenience(global_loadparm), d, c2); + d += push_codepoint(iconv_convenience, d, c2); } p1 += c_size1; @@ -138,6 +139,7 @@ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, { const char *base1, *base2; const char *ext1, *ext2; + struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); char *p; /* break into base part plus extension */ @@ -165,8 +167,8 @@ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, return NULL; } - base1 = pvfs_resolve_wildcard_component(mem_ctx, base1, base2); - ext1 = pvfs_resolve_wildcard_component(mem_ctx, ext1, ext2); + base1 = pvfs_resolve_wildcard_component(mem_ctx, iconv_convenience, base1, base2); + ext1 = pvfs_resolve_wildcard_component(mem_ctx, iconv_convenience, ext1, ext2); if (base1 == NULL || ext1 == NULL) { return NULL; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 949fa131a4..cf74816391 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -336,12 +336,13 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t int i, num_components, err_count; char **components; char *p, *s, *ret; + struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); s = talloc_strdup(mem_ctx, *fname); if (s == NULL) return NT_STATUS_NO_MEMORY; for (num_components=1, p=s; *p; p += c_size) { - c = next_codepoint(lp_iconv_convenience(global_loadparm), p, &c_size); + c = next_codepoint(iconv_convenience, p, &c_size); if (c == '\\') num_components++; } @@ -353,7 +354,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t components[0] = s; for (i=0, p=s; *p; p += c_size) { - c = next_codepoint(lp_iconv_convenience(global_loadparm), p, &c_size); + c = next_codepoint(iconv_convenience, p, &c_size); if (c == '\\') { *p = 0; components[++i] = p+1; -- cgit From ede79ae482b16c3cea65d3019bc1a68f07354e89 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 15:38:35 +0100 Subject: Remove more uses of global_loadparm. (This used to be commit 58a5b1de2b093fe642eb11d76d12db0edf60c25c) --- source4/ntvfs/posix/pvfs_shortname.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_shortname.c b/source4/ntvfs/posix/pvfs_shortname.c index 083a281819..923887debd 100644 --- a/source4/ntvfs/posix/pvfs_shortname.c +++ b/source4/ntvfs/posix/pvfs_shortname.c @@ -104,6 +104,8 @@ struct pvfs_mangle_context { /* this is used to reverse the base 36 mapping */ unsigned char base_reverse[256]; + + struct smb_iconv_convenience *iconv_convenience; }; @@ -388,7 +390,7 @@ static bool is_legal_name(struct pvfs_mangle_context *ctx, const char *name) { while (*name) { size_t c_size; - codepoint_t c = next_codepoint(lp_iconv_convenience(global_loadparm), name, &c_size); + codepoint_t c = next_codepoint(ctx->iconv_convenience, name, &c_size); if (c == INVALID_CODEPOINT) { return false; } @@ -613,6 +615,8 @@ NTSTATUS pvfs_mangle_init(struct pvfs_state *pvfs) return NT_STATUS_NO_MEMORY; } + ctx->iconv_convenience = lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx); + /* by default have a max of 512 entries in the cache. */ ctx->cache_size = lp_parm_int(pvfs->ntvfs->ctx->lp_ctx, NULL, "mangle", "cachesize", 512); -- cgit From c38c2765d1059b33f044a42c6555f3d10d339911 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:17:37 +0100 Subject: Remove yet more uses of global_loadparm. (This used to be commit e01c1e87c0fe9709df7eb5b863f7ce85564174cd) --- source4/ntvfs/posix/pvfs_rename.c | 4 ++-- source4/ntvfs/posix/pvfs_resolve.c | 7 ++++--- source4/ntvfs/sysdep/inotify.c | 9 ++++----- 3 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index ea12f49333..65755e05cb 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -134,12 +134,12 @@ static const char *pvfs_resolve_wildcard_component(TALLOC_CTX *mem_ctx, resolve a wildcard rename pattern. */ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, const char *fname, const char *pattern) { const char *base1, *base2; const char *ext1, *ext2; - struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); char *p; /* break into base part plus extension */ @@ -196,7 +196,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, struct odb_lock *lck, *lck2; /* resolve the wildcard pattern for this name */ - fname2 = pvfs_resolve_wildcard(mem_ctx, fname1, fname2); + fname2 = pvfs_resolve_wildcard(mem_ctx, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), fname1, fname2); if (fname2 == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index cf74816391..2bfc47beff 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -329,14 +329,15 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, reduce a name that contains .. components or repeated \ separators return NULL if it can't be reduced */ -static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t flags) +static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, + struct smb_iconv_convenience *iconv_convenience, + const char **fname, uint_t flags) { codepoint_t c; size_t c_size, len; int i, num_components, err_count; char **components; char *p, *s, *ret; - struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(global_loadparm); s = talloc_strdup(mem_ctx, *fname); if (s == NULL) return NT_STATUS_NO_MEMORY; @@ -471,7 +472,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_SYNTAX_BAD)) { /* it might contain .. components which need to be reduced */ - status = pvfs_reduce_name(*name, &cifs_name, flags); + status = pvfs_reduce_name(*name, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), &cifs_name, flags); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 3fa710415b..093c15abab 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -244,11 +244,6 @@ static void inotify_handler(struct event_context *ev, struct fd_event *fde, static NTSTATUS inotify_setup(struct sys_notify_context *ctx) { struct inotify_private *in; - - if (!lp_parm_bool(global_loadparm, NULL, "notify", "inotify", true)) { - return NT_STATUS_INVALID_SYSTEM_SERVICE; - } - in = talloc(ctx, struct inotify_private); NT_STATUS_HAVE_NO_MEMORY(in); in->fd = inotify_init(); @@ -339,6 +334,10 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, /* maybe setup the inotify fd */ if (ctx->private_data == NULL) { NTSTATUS status; + if (!lp_parm_bool(global_loadparm, NULL, "notify", "inotify", true)) { + return NT_STATUS_INVALID_SYSTEM_SERVICE; + } + status = inotify_setup(ctx); NT_STATUS_NOT_OK_RETURN(status); } -- cgit From 10169a203019445e6d325a5c1559de3c73782237 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Feb 2008 17:54:24 +0100 Subject: Remove more global_loadparm instance.s (This used to be commit a1280252ce924df69d911e597b7f65d8038abef9) --- source4/ntvfs/common/notify.c | 10 ++++++---- source4/ntvfs/posix/pvfs_xattr.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 94d32488eb..23aa3fb668 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -45,6 +45,7 @@ struct notify_context { struct notify_array *array; int seqnum; struct sys_notify_context *sys_notify_ctx; + struct smb_iconv_convenience *iconv_convenience; }; @@ -107,6 +108,7 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, notify->messaging_ctx = messaging_ctx; notify->list = NULL; notify->array = NULL; + notify->iconv_convenience = lp_iconv_convenience(lp_ctx); notify->seqnum = tdb_get_seqnum(notify->w->tdb); talloc_set_destructor(notify, notify_destructor); @@ -171,7 +173,7 @@ static NTSTATUS notify_load(struct notify_context *notify) blob.data = dbuf.dptr; blob.length = dbuf.dsize; - ndr_err = ndr_pull_struct_blob(&blob, notify->array, lp_iconv_convenience(global_loadparm), + ndr_err = ndr_pull_struct_blob(&blob, notify->array, notify->iconv_convenience, notify->array, (ndr_pull_flags_fn_t)ndr_pull_notify_array); free(dbuf.dptr); @@ -220,7 +222,7 @@ static NTSTATUS notify_save(struct notify_context *notify) tmp_ctx = talloc_new(notify); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); - ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, lp_iconv_convenience(global_loadparm), notify->array, + ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, notify->iconv_convenience, notify->array, (ndr_push_flags_fn_t)ndr_push_notify_array); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -256,7 +258,7 @@ static void notify_handler(struct messaging_context *msg_ctx, void *private_data return; } - ndr_err = ndr_pull_struct_blob(data, tmp_ctx, lp_iconv_convenience(global_loadparm), &ev, + ndr_err = ndr_pull_struct_blob(data, tmp_ctx, notify->iconv_convenience, &ev, (ndr_pull_flags_fn_t)ndr_pull_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); @@ -555,7 +557,7 @@ static void notify_send(struct notify_context *notify, struct notify_entry *e, tmp_ctx = talloc_new(notify); - ndr_err = ndr_push_struct_blob(&data, tmp_ctx, lp_iconv_convenience(global_loadparm), &ev, (ndr_push_flags_fn_t)ndr_push_notify_event); + ndr_err = ndr_push_struct_blob(&data, tmp_ctx, notify->iconv_convenience, &ev, (ndr_push_flags_fn_t)ndr_push_notify_event); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(tmp_ctx); return; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 39090bf702..b66d252a45 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -140,7 +140,7 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, NTSTATUS status; enum ndr_err_code ndr_err; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(global_loadparm), p, (ndr_push_flags_fn_t)push_fn); + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), p, (ndr_push_flags_fn_t)push_fn); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(mem_ctx); return ndr_map_error2ntstatus(ndr_err); -- cgit From fb6f52261a4cdbc529c04e28b29f82a8cbb9640f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 08:59:21 +0100 Subject: pvfs_wait: 'private' -> 'private_data' and use talloc_get_type() metze (This used to be commit 16a7d0cc37614fc41245fdcdf3b5a4a4a421f31d) --- source4/ntvfs/posix/pvfs_wait.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 989985a033..838a801567 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -31,7 +31,7 @@ struct pvfs_wait { struct pvfs_wait *next, *prev; struct pvfs_state *pvfs; void (*handler)(void *, enum pvfs_wait_notice); - void *private; + void *private_data; int msg_type; struct messaging_context *msg_ctx; struct event_context *ev; @@ -45,20 +45,23 @@ struct pvfs_wait { previous ntvfs handlers in the chain (such as security context) */ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, void *private) + struct ntvfs_request *req, void *private_data) { - struct pvfs_wait *pwait = private; - pwait->handler(pwait->private, pwait->reason); + struct pvfs_wait *pwait = talloc_get_type(private_data, + struct pvfs_wait); + pwait->handler(pwait->private_data, pwait->reason); return NT_STATUS_OK; } /* receive a completion message for a wait */ -static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uint32_t msg_type, +static void pvfs_wait_dispatch(struct messaging_context *msg, + void *private_data, uint32_t msg_type, struct server_id src, DATA_BLOB *data) { - struct pvfs_wait *pwait = private; + struct pvfs_wait *pwait = talloc_get_type(private_data, + struct pvfs_wait); struct ntvfs_request *req; void *p = NULL; @@ -70,7 +73,7 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin pp = (void **)data->data; p = *pp; } - if (p == NULL || p != pwait->private) { + if (p == NULL || p != pwait->private_data) { return; } @@ -91,9 +94,11 @@ static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uin receive a timeout on a message wait */ static void pvfs_wait_timeout(struct event_context *ev, - struct timed_event *te, struct timeval t, void *private) + struct timed_event *te, struct timeval t, + void *private_data) { - struct pvfs_wait *pwait = talloc_get_type(private, struct pvfs_wait); + struct pvfs_wait *pwait = talloc_get_type(private_data, + struct pvfs_wait); struct ntvfs_request *req = pwait->req; pwait->reason = PVFS_WAIT_TIMEOUT; @@ -131,7 +136,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, int msg_type, struct timeval end_time, void (*fn)(void *, enum pvfs_wait_notice), - void *private) + void *private_data) { struct pvfs_wait *pwait; @@ -140,7 +145,7 @@ void *pvfs_wait_message(struct pvfs_state *pvfs, return NULL; } - pwait->private = private; + pwait->private_data = private_data; pwait->handler = fn; pwait->msg_ctx = pvfs->ntvfs->ctx->msg_ctx; pwait->ev = pvfs->ntvfs->ctx->event_ctx; -- cgit From a0a0d4a5d0c24729a26a37ff54caa665de9149a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 09:02:17 +0100 Subject: pvfs_wait: use struct pvfs_wait * instead of void * metze (This used to be commit 3b70331536d2402814db13a9f1f226a39373313a) --- source4/ntvfs/posix/pvfs_lock.c | 2 +- source4/ntvfs/posix/pvfs_notify.c | 8 +++++--- source4/ntvfs/posix/pvfs_open.c | 2 +- source4/ntvfs/posix/pvfs_wait.c | 12 ++++++------ source4/ntvfs/posix/vfs_posix.h | 2 ++ 5 files changed, 15 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index b9bb58c71d..df85b2b775 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -53,7 +53,7 @@ struct pvfs_pending_lock { struct pvfs_file *f; struct ntvfs_request *req; int pending_lock; - void *wait_handle; + struct pvfs_wait *wait_handle; struct timeval end_time; }; diff --git a/source4/ntvfs/posix/pvfs_notify.c b/source4/ntvfs/posix/pvfs_notify.c index 210f949395..06d2bc8e0c 100644 --- a/source4/ntvfs/posix/pvfs_notify.c +++ b/source4/ntvfs/posix/pvfs_notify.c @@ -268,9 +268,11 @@ NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, /* if the buffer is empty then start waiting */ if (f->notify_buffer->num_changes == 0) { - void *wait_handle = - pvfs_wait_message(pvfs, req, -1, timeval_zero(), - pvfs_notify_end, f->notify_buffer); + struct pvfs_wait *wait_handle; + wait_handle = pvfs_wait_message(pvfs, req, -1, + timeval_zero(), + pvfs_notify_end, + f->notify_buffer); NT_STATUS_HAVE_NO_MEMORY(wait_handle); talloc_steal(req, wait_handle); return NT_STATUS_OK; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 8558f0476a..3ccd239523 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -756,7 +756,7 @@ struct pvfs_open_retry { struct ntvfs_module_context *ntvfs; struct ntvfs_request *req; union smb_open *io; - void *wait_handle; + struct pvfs_wait *wait_handle; DATA_BLOB odb_locking_key; }; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 838a801567..291250befd 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -131,12 +131,12 @@ static int pvfs_wait_destructor(struct pvfs_wait *pwait) if msg_type == -1 then no message is registered, and it is assumed that the caller handles any messaging setup needed */ -void *pvfs_wait_message(struct pvfs_state *pvfs, - struct ntvfs_request *req, - int msg_type, - struct timeval end_time, - void (*fn)(void *, enum pvfs_wait_notice), - void *private_data) +struct pvfs_wait *pvfs_wait_message(struct pvfs_state *pvfs, + struct ntvfs_request *req, + int msg_type, + struct timeval end_time, + void (*fn)(void *, enum pvfs_wait_notice), + void *private_data) { struct pvfs_wait *pwait; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index a660da329a..84c456dcfe 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -28,6 +28,8 @@ #include "ntvfs/common/ntvfs_common.h" #include "dsdb/samdb/samdb.h" +struct pvfs_wait; + /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ struct pvfs_state { -- cgit From 1cd2008aa49d38792f273bb28922d33b5b9b0066 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 19:59:13 +0100 Subject: pvfs: pass NULL to pvfs_can_*() when no odb_lock is needed by the caller metze (This used to be commit e585e2306334bd919f567f53d8d08903dfdfb102) --- source4/ntvfs/posix/pvfs_rename.c | 11 ++++++----- source4/ntvfs/posix/pvfs_setfileinfo.c | 4 +--- source4/ntvfs/posix/pvfs_unlink.c | 6 ++---- 3 files changed, 9 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index ea12f49333..5693e79314 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -192,8 +192,8 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, { struct pvfs_filename *name1, *name2; TALLOC_CTX *mem_ctx = talloc_new(req); + struct odb_lock *lck = NULL; NTSTATUS status; - struct odb_lock *lck, *lck2; /* resolve the wildcard pattern for this name */ fname2 = pvfs_resolve_wildcard(mem_ctx, fname1, fname2); @@ -216,6 +216,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, status = pvfs_can_rename(pvfs, req, name1, &lck); if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); goto failed; } @@ -223,7 +224,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, status = pvfs_resolve_partial(pvfs, mem_ctx, dir_path, fname2, &name2); if (NT_STATUS_IS_OK(status)) { - status = pvfs_can_delete(pvfs, req, name2, &lck2); + status = pvfs_can_delete(pvfs, req, name2, NULL); if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -311,7 +312,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; - struct odb_lock *lck; + struct odb_lock *lck = NULL; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, @@ -354,6 +355,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, status = pvfs_can_rename(pvfs, req, name1, &lck); if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); return status; } @@ -375,7 +377,6 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; - struct odb_lock *lck; switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: @@ -421,7 +422,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_can_rename(pvfs, req, name1, &lck); + status = pvfs_can_rename(pvfs, req, name1, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 9c78699edb..fbbb8c2d4b 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -142,8 +142,6 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, /* if the destination exists, then check the rename is allowed */ if (name2->exists) { - struct odb_lock *lck; - if (strcmp(name2->full_name, name->full_name) == 0) { /* rename to same name is null-op */ return NT_STATUS_OK; @@ -153,7 +151,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_OBJECT_NAME_COLLISION; } - status = pvfs_can_delete(pvfs, req, name2, &lck); + status = pvfs_can_delete(pvfs, req, name2, NULL); if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { return NT_STATUS_ACCESS_DENIED; } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index ef56d99fb5..d6e60b59d3 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -33,7 +33,6 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, uint16_t attrib) { NTSTATUS status; - struct odb_lock *lck; if (!name->stream_exists) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -45,7 +44,7 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, return status; } - status = pvfs_can_delete(pvfs, req, name, &lck); + status = pvfs_can_delete(pvfs, req, name, NULL); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -64,7 +63,6 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, { struct pvfs_filename *name; NTSTATUS status; - struct odb_lock *lck; /* get a pvfs_filename object */ status = pvfs_resolve_partial(pvfs, req, @@ -80,7 +78,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return status; } - status = pvfs_can_delete(pvfs, req, name, &lck); + status = pvfs_can_delete(pvfs, req, name, NULL); if (!NT_STATUS_IS_OK(status)) { talloc_free(name); return status; -- cgit From f56ff422a525fc6fdf04de8e2ce5c5fa4c097629 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 20:01:25 +0100 Subject: pvfs: handle SHARING_VIOLATION and OPLOCK_NOT_GRANTED in pvfs_can_delete/rename() If the caller asks for the odb_lock return it also if we return NT_STATUS_SHARING_VIOLATION or NT_STATUS_OPLOCK_NOT_GRANTED so that the caller can add the pending notification. metze (This used to be commit daab9cb11eb540fae7ec3c024a586f5fd02cfc71) --- source4/ntvfs/posix/pvfs_open.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3ccd239523..0d97b3d629 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1447,7 +1447,19 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE); } - if (!NT_STATUS_IS_OK(status)) { + /* + * if it's a sharing violation or we got no oplock + * only keep the lock if the caller requested access + * to the lock + */ + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + if (lckp) { + *lckp = lck; + } else { + talloc_free(lck); + } + } else if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); *lckp = lck; } else if (lckp != NULL) { @@ -1487,7 +1499,19 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, 0, SEC_STD_DELETE); - if (!NT_STATUS_IS_OK(status)) { + /* + * if it's a sharing violation or we got no oplock + * only keep the lock if the caller requested access + * to the lock + */ + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + if (lckp) { + *lckp = lck; + } else { + talloc_free(lck); + } + } else if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); *lckp = lck; } else if (lckp != NULL) { -- cgit From 6f077d4017e6df9e070b1c3ea85b7afacf3437cd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 19:56:36 +0100 Subject: pvfs_open: unify talloc behavior in pvfs_can_delete/rename/stat() And also handle NULL for lckp in the error path without crashing. metze (This used to be commit 04eb1be0c67317067ee0ca70c731fef958cd513c) --- source4/ntvfs/posix/pvfs_open.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 0d97b3d629..3a8b17ab16 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1461,8 +1461,10 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, } } else if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); - *lckp = lck; - } else if (lckp != NULL) { + if (lckp) { + *lckp = NULL; + } + } else if (lckp) { *lckp = lck; } @@ -1513,8 +1515,10 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, } } else if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); - *lckp = lck; - } else if (lckp != NULL) { + if (lckp) { + *lckp = NULL; + } + } else if (lckp) { *lckp = lck; } @@ -1549,6 +1553,10 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, NTCREATEX_SHARE_ACCESS_WRITE, 0, 0); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + } + return status; } -- cgit From 63b15441f4a5f636a079fa5407b2e97a8b99b6e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 20:12:46 +0100 Subject: pvfs_unlink: pass down a struct pvfs_filename to pvfs_unlink_one() metze (This used to be commit 43ec7fa2d898ce306557ea9092b6412bcc2f97ec) --- source4/ntvfs/posix/pvfs_unlink.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index d6e60b59d3..101dd75de6 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -58,34 +58,23 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, */ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, struct ntvfs_request *req, - const char *unix_path, - const char *fname, uint32_t attrib) + struct pvfs_filename *name, + uint32_t attrib) { - struct pvfs_filename *name; NTSTATUS status; - /* get a pvfs_filename object */ - status = pvfs_resolve_partial(pvfs, req, - unix_path, fname, &name); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - /* make sure its matches the given attributes */ status = pvfs_match_attrib(pvfs, name, attrib, 0); if (!NT_STATUS_IS_OK(status)) { - talloc_free(name); return status; } status = pvfs_can_delete(pvfs, req, name, NULL); if (!NT_STATUS_IS_OK(status)) { - talloc_free(name); return status; } if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { - talloc_free(name); return NT_STATUS_FILE_IS_A_DIRECTORY; } @@ -108,8 +97,6 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, name->full_name); } - talloc_free(name); - return status; } @@ -156,6 +143,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } status = NT_STATUS_NO_SUCH_FILE; + talloc_free(name); ofs = 0; @@ -166,10 +154,20 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_OBJECT_NAME_INVALID; } - status = pvfs_unlink_one(pvfs, req, pvfs_list_unix_path(dir), fname, unl->unlink.in.attrib); + /* get a pvfs_filename object */ + status = pvfs_resolve_partial(pvfs, req, + pvfs_list_unix_path(dir), + fname, &name); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_unlink_one(pvfs, req, name, unl->unlink.in.attrib); if (NT_STATUS_IS_OK(status)) { total_deleted++; } + + talloc_free(name); } if (total_deleted > 0) { -- cgit From a56bd4fa82bcb5c586f182e8123f2fc41b12e41d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:23:53 +0100 Subject: pvfs_unlink: pass down union smb_unlink completely to sub functions metze (This used to be commit 8301189e94be850494482e8c064b2400a5d11157) --- source4/ntvfs/posix/pvfs_unlink.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 101dd75de6..8dbf9ee724 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -29,8 +29,8 @@ */ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, struct ntvfs_request *req, - struct pvfs_filename *name, - uint16_t attrib) + union smb_unlink *unl, + struct pvfs_filename *name) { NTSTATUS status; @@ -39,7 +39,8 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, } /* make sure its matches the given attributes */ - status = pvfs_match_attrib(pvfs, name, attrib, 0); + status = pvfs_match_attrib(pvfs, name, + unl->unlink.in.attrib, 0); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -58,13 +59,14 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, */ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, struct ntvfs_request *req, - struct pvfs_filename *name, - uint32_t attrib) + union smb_unlink *unl, + struct pvfs_filename *name) { NTSTATUS status; /* make sure its matches the given attributes */ - status = pvfs_match_attrib(pvfs, name, attrib, 0); + status = pvfs_match_attrib(pvfs, name, + unl->unlink.in.attrib, 0); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -133,7 +135,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (name->stream_name) { - return pvfs_unlink_stream(pvfs, req, name, unl->unlink.in.attrib); + return pvfs_unlink_stream(pvfs, req, unl, name); } /* get list of matching files */ @@ -162,7 +164,7 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_unlink_one(pvfs, req, name, unl->unlink.in.attrib); + status = pvfs_unlink_one(pvfs, req, unl, name); if (NT_STATUS_IS_OK(status)) { total_deleted++; } -- cgit From d5414cdc63b797a47fcbd1f55df98c7dd850ffa6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:28:51 +0100 Subject: pvfs_unlink: move !name->stream_exists into the caller metze (This used to be commit e01554e1617dc3c08a4ed6b4e016fd627f529ef9) --- source4/ntvfs/posix/pvfs_unlink.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 8dbf9ee724..2b96a5032c 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -34,10 +34,6 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, { NTSTATUS status; - if (!name->stream_exists) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - /* make sure its matches the given attributes */ status = pvfs_match_attrib(pvfs, name, unl->unlink.in.attrib, 0); @@ -135,6 +131,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, } if (name->stream_name) { + if (!name->stream_exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + return pvfs_unlink_stream(pvfs, req, unl, name); } -- cgit From 0634c12abb634034fcaf842647c2bc09a92bfd68 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:30:51 +0100 Subject: pvfs_unlink: add a fast path for the non wildcard case metze (This used to be commit 83e6c99f78990b6b1df520bdee14b9f931ad0420) --- source4/ntvfs/posix/pvfs_unlink.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 2b96a5032c..72649e646d 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -138,6 +138,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return pvfs_unlink_stream(pvfs, req, unl, name); } + if (!name->has_wildcard) { + return pvfs_unlink_one(pvfs, req, unl, name); + } + /* get list of matching files */ status = pvfs_list_start(pvfs, name, req, &dir); if (!NT_STATUS_IS_OK(status)) { -- cgit From 58745900d30cbfa8729ce99e7110cfc5e4a78c2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:37:22 +0100 Subject: pvfs_unlink: splitup the logic into generic and file specific functions metze (This used to be commit 7572afdc2635bdf9afbe1eda3c7498d0b5201db3) --- source4/ntvfs/posix/pvfs_unlink.c | 45 ++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 72649e646d..0763a4e48c 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -51,27 +51,13 @@ static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, /* - unlink one file + unlink a file */ -static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, - struct ntvfs_request *req, - union smb_unlink *unl, - struct pvfs_filename *name) +static NTSTATUS pvfs_unlink_file(struct pvfs_state *pvfs, + struct pvfs_filename *name) { NTSTATUS status; - /* make sure its matches the given attributes */ - status = pvfs_match_attrib(pvfs, name, - unl->unlink.in.attrib, 0); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = pvfs_can_delete(pvfs, req, name, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { return NT_STATUS_FILE_IS_A_DIRECTORY; } @@ -98,6 +84,31 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return status; } +/* + unlink one file +*/ +static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, + struct ntvfs_request *req, + union smb_unlink *unl, + struct pvfs_filename *name) +{ + NTSTATUS status; + + /* make sure its matches the given attributes */ + status = pvfs_match_attrib(pvfs, name, + unl->unlink.in.attrib, 0); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = pvfs_can_delete(pvfs, req, name, NULL); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return pvfs_unlink_file(pvfs, name); +} + /* delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) -- cgit From 599901c139e99dca26f267439c14119e6c3f2092 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 09:41:41 +0100 Subject: pvfs_unlink: move stream logic into pvfs_unlink_one() metze (This used to be commit 438032e12f3040fbb58488ca537e4d8da39b6124) --- source4/ntvfs/posix/pvfs_unlink.c | 42 ++++++++------------------------------- 1 file changed, 8 insertions(+), 34 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 0763a4e48c..bda4014bee 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -24,32 +24,6 @@ #include "system/dir.h" -/* - unlink a stream - */ -static NTSTATUS pvfs_unlink_stream(struct pvfs_state *pvfs, - struct ntvfs_request *req, - union smb_unlink *unl, - struct pvfs_filename *name) -{ - NTSTATUS status; - - /* make sure its matches the given attributes */ - status = pvfs_match_attrib(pvfs, name, - unl->unlink.in.attrib, 0); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - status = pvfs_can_delete(pvfs, req, name, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - return pvfs_stream_delete(pvfs, name, -1); -} - - /* unlink a file */ @@ -106,6 +80,14 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return status; } + if (name->stream_name) { + if (!name->stream_exists) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + return pvfs_stream_delete(pvfs, name, -1); + } + return pvfs_unlink_file(pvfs, name); } @@ -141,14 +123,6 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } - if (name->stream_name) { - if (!name->stream_exists) { - return NT_STATUS_OBJECT_NAME_NOT_FOUND; - } - - return pvfs_unlink_stream(pvfs, req, unl, name); - } - if (!name->has_wildcard) { return pvfs_unlink_one(pvfs, req, unl, name); } -- cgit From 27e322bb4d5a25a2a1ebc5df36690590d86e3afd Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 10:18:13 +0100 Subject: opendb: add odb_get_key() function to get the key back from a struct odb_lock metze (This used to be commit 11f35a2a4d383b506ced35ba06120f9531bac70c) --- source4/ntvfs/common/opendb.c | 4 ++++ source4/ntvfs/common/opendb.h | 1 + source4/ntvfs/common/opendb_tdb.c | 7 +++++++ 3 files changed, 12 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 4826ca5c26..f12f23817d 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -81,6 +81,10 @@ _PUBLIC_ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, return ops->odb_lock(mem_ctx, odb, file_key); } +_PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) +{ + return ops->odb_get_key(mem_ctx, lck); +} /* register an open file in the open files database. This implements the share_access diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 231ae3d7de..5472cea418 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -24,6 +24,7 @@ struct opendb_ops { struct ntvfs_context *ntvfs_ctx); struct odb_lock *(*odb_lock)(TALLOC_CTX *mem_ctx, struct odb_context *odb, DATA_BLOB *file_key); + DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck); NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index abd9ca708b..469cf28374 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -134,6 +134,12 @@ static struct odb_lock *odb_tdb_lock(TALLOC_CTX *mem_ctx, return lck; } +static DATA_BLOB odb_tdb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) +{ + return data_blob_talloc(mem_ctx, lck->key.dptr, lck->key.dsize); +} + + /* determine if two odb_entry structures conflict @@ -609,6 +615,7 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, static const struct opendb_ops opendb_tdb_ops = { .odb_init = odb_tdb_init, .odb_lock = odb_tdb_lock, + .odb_get_key = odb_tdb_get_key, .odb_open_file = odb_tdb_open_file, .odb_open_file_pending = odb_tdb_open_file_pending, .odb_close_file = odb_tdb_close_file, -- cgit From 6cb9c1c61d8087457420a56f5296662417a25bd4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 12:20:31 +0100 Subject: opendb: send also the oplock break level on MSG_NTVFS_OPLOCK_BREAK metze (This used to be commit 49402007f6e9e02a29792344c088e40d1a9b7acf) --- source4/ntvfs/common/opendb.h | 4 ++++ source4/ntvfs/common/opendb_tdb.c | 28 +++++++++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 5472cea418..ccf6db27a0 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -43,6 +43,10 @@ struct opendb_ops { uint32_t access_mask); }; +struct opendb_oplock_break { + void *file_handle; + uint8_t level; +}; void odb_set_ops(const struct opendb_ops *new_ops); void odb_tdb_init_ops(void); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 469cf28374..25f37f5e26 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -259,12 +259,28 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) /* send an oplock break to a client */ -static NTSTATUS odb_oplock_break_send(struct odb_context *odb, struct opendb_entry *e) +static NTSTATUS odb_oplock_break_send(struct odb_context *odb, + struct opendb_entry *e, + uint8_t level) { + NTSTATUS status; + struct opendb_oplock_break op_break; + DATA_BLOB blob; + + ZERO_STRUCT(op_break); + /* tell the server handling this open file about the need to send the client a break */ - return messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, e->server, - MSG_NTVFS_OPLOCK_BREAK, e->file_handle); + op_break.file_handle = e->file_handle; + op_break.level = level; + + blob = data_blob_const(&op_break, sizeof(op_break)); + + status = messaging_send(odb->ntvfs_ctx->msg_ctx, e->server, + MSG_NTVFS_OPLOCK_BREAK, &blob); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; } /* @@ -318,7 +334,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, break request and suspending this call until the break is acknowledged or the file is closed */ - odb_oplock_break_send(odb, &file.entries[i]); + odb_oplock_break_send(odb, &file.entries[i], + OPLOCK_BREAK_TO_LEVEL_II/*TODO*/); return NT_STATUS_OPLOCK_NOT_GRANTED; } } @@ -342,7 +359,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, exclusive oplocks afterwards. */ for (i=0;i Date: Thu, 21 Feb 2008 16:12:27 +0100 Subject: opendb: add odb_update_oplock() call metze (This used to be commit df576d69c6981a4879a0e9447069fcfacb3588db) --- source4/ntvfs/common/opendb.c | 6 ++++++ source4/ntvfs/common/opendb.h | 2 ++ source4/ntvfs/common/opendb_tdb.c | 45 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index f12f23817d..4ac10806e1 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -170,3 +170,9 @@ _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, { return ops->odb_can_open(lck, share_access, create_options, access_mask); } + +_PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle, + uint32_t oplock_level) +{ + return ops->odb_update_oplock(lck, file_handle, oplock_level); +} diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index ccf6db27a0..c34a07d6fa 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -41,6 +41,8 @@ struct opendb_ops { NTSTATUS (*odb_can_open)(struct odb_lock *lck, uint32_t share_access, uint32_t create_options, uint32_t access_mask); + NTSTATUS (*odb_update_oplock)(struct odb_lock *lck, void *file_handle, + uint32_t oplock_level); }; struct opendb_oplock_break { diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 25f37f5e26..3d4a760e2e 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. Copyright (C) Andrew Tridgell 2004 - + Copyright (C) Stefan Metzmacher 2008 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or @@ -463,6 +464,45 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle) return odb_push_record(lck, &file); } +/* + update the oplock level of the client +*/ +static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle, + uint32_t oplock_level) +{ + struct odb_context *odb = lck->odb; + struct opendb_file file; + int i; + NTSTATUS status; + + status = odb_pull_record(lck, &file); + NT_STATUS_NOT_OK_RETURN(status); + + /* find the entry, and update it */ + for (i=0;intvfs_ctx->server_id, &file.entries[i].server)) { + file.entries[i].oplock_level = oplock_level; + break; + } + } + + if (i == file.num_entries) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* send any pending notifications, removing them once sent */ + for (i=0;intvfs_ctx->msg_ctx, + file.pending[i].server, + MSG_PVFS_RETRY_OPEN, + file.pending[i].notify_ptr); + } + file.num_pending = 0; + + return odb_push_record(lck, &file); +} + /* remove a pending opendb entry @@ -641,7 +681,8 @@ static const struct opendb_ops opendb_tdb_ops = { .odb_rename = odb_tdb_rename, .odb_set_delete_on_close = odb_tdb_set_delete_on_close, .odb_get_delete_on_close = odb_tdb_get_delete_on_close, - .odb_can_open = odb_tdb_can_open + .odb_can_open = odb_tdb_can_open, + .odb_update_oplock = odb_tdb_update_oplock }; -- cgit From f94008e45a15666439766488edf84b21a86111ee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 16:30:13 +0100 Subject: opendb: add odb_break_oplocks() function This send breaks to none to all level2 holders metze (This used to be commit bd3654500b14e4ed8d4a8bb25ff9da5035a16a8b) --- source4/ntvfs/common/opendb.c | 5 +++++ source4/ntvfs/common/opendb.h | 1 + source4/ntvfs/common/opendb_tdb.c | 40 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 4ac10806e1..3f5d7210be 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -176,3 +176,8 @@ _PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle, { return ops->odb_update_oplock(lck, file_handle, oplock_level); } + +_PUBLIC_ NTSTATUS odb_break_oplocks(struct odb_lock *lck) +{ + return ops->odb_break_oplocks(lck); +} diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index c34a07d6fa..c46390446c 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -43,6 +43,7 @@ struct opendb_ops { uint32_t access_mask); NTSTATUS (*odb_update_oplock)(struct odb_lock *lck, void *file_handle, uint32_t oplock_level); + NTSTATUS (*odb_break_oplocks)(struct odb_lock *lck); }; struct opendb_oplock_break { diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 3d4a760e2e..dd2fb138d6 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -503,6 +503,43 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle, return odb_push_record(lck, &file); } +/* + send oplocks breaks to none to all level2 holders +*/ +static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck) +{ + struct odb_context *odb = lck->odb; + NTSTATUS status; + struct opendb_file file; + int i; + bool modified = true; + + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + return NT_STATUS_OK; + } + NT_STATUS_NOT_OK_RETURN(status); + + /* see if anyone has an oplock, which we need to break */ + for (i=0;i Date: Fri, 22 Feb 2008 17:26:40 +0100 Subject: opendb_tdb: grant level2 oplocks metze (This used to be commit 57f1b9d11cfcac3b5fdee1ad9e4ba81d0859c8dc) --- source4/ntvfs/common/opendb_tdb.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index dd2fb138d6..3310532406 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -367,18 +367,32 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, } /* - possibly grant an exclusive or batch oplock if this is the only client - with the file open. We don't yet grant levelII oplocks. + possibly grant an exclusive, batch or level2 oplock */ - if (oplock_granted != NULL) { - if ((oplock_level == OPLOCK_BATCH || - oplock_level == OPLOCK_EXCLUSIVE) && - file.num_entries == 0) { - (*oplock_granted) = oplock_level; + if (oplock_granted) { + if (oplock_level == OPLOCK_EXCLUSIVE) { + if (file.num_entries == 0) { + e.oplock_level = OPLOCK_EXCLUSIVE; + *oplock_granted = EXCLUSIVE_OPLOCK_RETURN; + } else { + e.oplock_level = OPLOCK_NONE; + *oplock_granted = NO_OPLOCK_RETURN; + } + } else if (oplock_level == OPLOCK_BATCH) { + if (file.num_entries == 0) { + e.oplock_level = OPLOCK_BATCH; + *oplock_granted = BATCH_OPLOCK_RETURN; + } else { + e.oplock_level = OPLOCK_LEVEL_II; + *oplock_granted = LEVEL_II_OPLOCK_RETURN; + } + } else if (oplock_level == OPLOCK_LEVEL_II) { + e.oplock_level = OPLOCK_LEVEL_II; + *oplock_granted = LEVEL_II_OPLOCK_RETURN; } else { - (*oplock_granted) = OPLOCK_NONE; + e.oplock_level = OPLOCK_NONE; + *oplock_granted = NO_OPLOCK_RETURN; } - e.oplock_level = (*oplock_granted); } /* it doesn't conflict, so add it to the end */ -- cgit From c749b66ead71af3076d4f911aa0cd65e35284ca4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 17:26:40 +0100 Subject: opendb_tdb: attribute only opens doesn't conflict with BATCH oplocks metze (This used to be commit 7872b05abe7532676c4cc25620b96ea5d59117d2) --- source4/ntvfs/common/opendb_tdb.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 3310532406..b445981b57 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -189,7 +189,7 @@ static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2) e2->share_access, NTCREATEX_SHARE_ACCESS_DELETE); CHECK_MASK(e2->access_mask, SEC_STD_DELETE, e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE); - +#undef CHECK_MASK return NT_STATUS_OK; } @@ -284,6 +284,25 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, return NT_STATUS_OK; } +static bool access_attributes_only(uint32_t access_mask, + uint32_t open_disposition) +{ + switch (open_disposition) { + case NTCREATEX_DISP_SUPERSEDE: + case NTCREATEX_DISP_OVERWRITE_IF: + case NTCREATEX_DISP_OVERWRITE: + return false; + default: + break; + } +#define CHECK_MASK(m,g) ((m) && (((m) & ~(g))==0) && (((m) & (g)) != 0)) + return CHECK_MASK(access_mask, + SEC_STD_SYNCHRONIZE | + SEC_FILE_READ_ATTRIBUTE | + SEC_FILE_WRITE_ATTRIBUTE); +#undef CHECK_MASK +} + /* register an open file in the open files database. This implements the share_access rules @@ -302,6 +321,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, int i; struct opendb_file file; NTSTATUS status; + uint32_t open_disposition = 0; + bool attrs_only = false; if (odb->oplocks == false) { oplock_level = OPLOCK_NONE; @@ -328,6 +349,15 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, /* see if anyone has an oplock, which we need to break */ for (i=0;i Date: Mon, 25 Feb 2008 16:14:23 +0100 Subject: opendb_tdb: add force break to none logic metze (This used to be commit fbfe953ba347a902297bd8eae900ca70efd2db01) --- source4/ntvfs/common/opendb_tdb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index b445981b57..656e113742 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -322,6 +322,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, struct opendb_file file; NTSTATUS status; uint32_t open_disposition = 0; + bool break_to_none = false; bool attrs_only = false; if (odb->oplocks == false) { @@ -349,6 +350,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, /* see if anyone has an oplock, which we need to break */ for (i=0;i Date: Mon, 25 Feb 2008 16:26:04 +0100 Subject: opendb_tdb: move sharemode, oplock logic into odb_tdb_open_can_internal() metze (This used to be commit 65cfe71b2617598f8e38d04537cfc9ce44a36680) --- source4/ntvfs/common/opendb_tdb.c | 191 ++++++++++++++++++++------------------ 1 file changed, 102 insertions(+), 89 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 656e113742..9c273f9617 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -146,7 +146,10 @@ static DATA_BLOB odb_tdb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) return NT_STATUS_OK on no conflict */ -static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2) +static NTSTATUS share_conflict(struct opendb_entry *e1, + uint32_t stream_id, + uint32_t share_access, + uint32_t access_mask) { /* if either open involves no read.write or delete access then it can't conflict */ @@ -157,18 +160,18 @@ static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2) SEC_STD_DELETE))) { return NT_STATUS_OK; } - if (!(e2->access_mask & (SEC_FILE_WRITE_DATA | - SEC_FILE_APPEND_DATA | - SEC_FILE_READ_DATA | - SEC_FILE_EXECUTE | - SEC_STD_DELETE))) { + if (!(access_mask & (SEC_FILE_WRITE_DATA | + SEC_FILE_APPEND_DATA | + SEC_FILE_READ_DATA | + SEC_FILE_EXECUTE | + SEC_STD_DELETE))) { return NT_STATUS_OK; } /* data IO access masks. This is skipped if the two open handles are on different streams (as in that case the masks don't interact) */ - if (e1->stream_id != e2->stream_id) { + if (e1->stream_id != stream_id) { return NT_STATUS_OK; } @@ -176,18 +179,18 @@ static NTSTATUS share_conflict(struct opendb_entry *e1, struct opendb_entry *e2) if (((am) & (right)) && !((sa) & (share))) return NT_STATUS_SHARING_VIOLATION CHECK_MASK(e1->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, - e2->share_access, NTCREATEX_SHARE_ACCESS_WRITE); - CHECK_MASK(e2->access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, + share_access, NTCREATEX_SHARE_ACCESS_WRITE); + CHECK_MASK(access_mask, SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA, e1->share_access, NTCREATEX_SHARE_ACCESS_WRITE); CHECK_MASK(e1->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, - e2->share_access, NTCREATEX_SHARE_ACCESS_READ); - CHECK_MASK(e2->access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, + share_access, NTCREATEX_SHARE_ACCESS_READ); + CHECK_MASK(access_mask, SEC_FILE_READ_DATA | SEC_FILE_EXECUTE, e1->share_access, NTCREATEX_SHARE_ACCESS_READ); CHECK_MASK(e1->access_mask, SEC_STD_DELETE, - e2->share_access, NTCREATEX_SHARE_ACCESS_DELETE); - CHECK_MASK(e2->access_mask, SEC_STD_DELETE, + share_access, NTCREATEX_SHARE_ACCESS_DELETE); + CHECK_MASK(access_mask, SEC_STD_DELETE, e1->share_access, NTCREATEX_SHARE_ACCESS_DELETE); #undef CHECK_MASK return NT_STATUS_OK; @@ -303,53 +306,20 @@ static bool access_attributes_only(uint32_t access_mask, #undef CHECK_MASK } -/* - register an open file in the open files database. This implements the share_access - rules - - Note that the path is only used by the delete on close logic, not - for comparing with other filenames -*/ -static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, - uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, bool delete_on_close, - const char *path, - uint32_t oplock_level, uint32_t *oplock_granted) +static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, + const struct opendb_file *file, + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, bool delete_on_close, + uint32_t open_disposition, bool break_to_none, + bool *_attrs_only) { - struct odb_context *odb = lck->odb; - struct opendb_entry e; - int i; - struct opendb_file file; NTSTATUS status; - uint32_t open_disposition = 0; - bool break_to_none = false; + uint32_t i; bool attrs_only = false; - if (odb->oplocks == false) { - oplock_level = OPLOCK_NONE; - } - - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - /* initialise a blank structure */ - ZERO_STRUCT(file); - file.path = path; - } else { - NT_STATUS_NOT_OK_RETURN(status); - } - - /* see if it conflicts */ - e.server = odb->ntvfs_ctx->server_id; - e.file_handle = file_handle; - e.stream_id = stream_id; - e.share_access = share_access; - e.access_mask = access_mask; - e.delete_on_close = delete_on_close; - e.oplock_level = OPLOCK_NONE; - /* see if anyone has an oplock, which we need to break */ - for (i=0;inum_entries;i++) { + if (file->entries[i].oplock_level == OPLOCK_BATCH) { bool oplock_return = OPLOCK_BREAK_TO_LEVEL_II; /* if this is an attribute only access * it doesn't conflict with a BACTCH oplock @@ -370,21 +340,22 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, if (break_to_none) { oplock_return = OPLOCK_BREAK_TO_NONE; } - odb_oplock_break_send(odb, &file.entries[i], + odb_oplock_break_send(odb, &file->entries[i], oplock_return); return NT_STATUS_OPLOCK_NOT_GRANTED; } } - if (file.delete_on_close || - (file.num_entries != 0 && delete_on_close)) { + if (file->delete_on_close || + (file->num_entries != 0 && delete_on_close)) { /* while delete on close is set, no new opens are allowed */ return NT_STATUS_DELETE_PENDING; } /* check for sharing violations */ - for (i=0;inum_entries;i++) { + status = share_conflict(&file->entries[i], stream_id, + share_access, access_mask); NT_STATUS_NOT_OK_RETURN(status); } @@ -393,14 +364,70 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, till these are broken. Note that we check for batch oplocks before checking for sharing violations, and check for exclusive oplocks afterwards. */ - for (i=0;inum_entries;i++) { + if (file->entries[i].oplock_level == OPLOCK_EXCLUSIVE) { + odb_oplock_break_send(odb, &file->entries[i], OPLOCK_BREAK_TO_NONE); return NT_STATUS_OPLOCK_NOT_GRANTED; } } + if (_attrs_only) { + *_attrs_only = attrs_only; + } + return NT_STATUS_OK; +} + +/* + register an open file in the open files database. This implements the share_access + rules + + Note that the path is only used by the delete on close logic, not + for comparing with other filenames +*/ +static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, bool delete_on_close, + const char *path, + uint32_t oplock_level, uint32_t *oplock_granted) +{ + struct odb_context *odb = lck->odb; + struct opendb_entry e; + struct opendb_file file; + NTSTATUS status; + uint32_t open_disposition = 0; + bool break_to_none = false; + bool attrs_only = false; + + if (odb->oplocks == false) { + oplock_level = OPLOCK_NONE; + } + + status = odb_pull_record(lck, &file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + /* initialise a blank structure */ + ZERO_STRUCT(file); + file.path = path; + } else { + NT_STATUS_NOT_OK_RETURN(status); + } + + /* see if it conflicts */ + status = odb_tdb_open_can_internal(odb, &file, stream_id, + share_access, access_mask, + delete_on_close, open_disposition, + break_to_none, &attrs_only); + NT_STATUS_NOT_OK_RETURN(status); + + /* see if it conflicts */ + e.server = odb->ntvfs_ctx->server_id; + e.file_handle = file_handle; + e.stream_id = stream_id; + e.share_access = share_access; + e.access_mask = access_mask; + e.delete_on_close = delete_on_close; + e.oplock_level = OPLOCK_NONE; + /* possibly grant an exclusive, batch or level2 oplock */ @@ -719,8 +746,11 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, struct odb_context *odb = lck->odb; NTSTATUS status; struct opendb_file file; - struct opendb_entry e; - int i; + uint32_t stream_id = 0; + uint32_t open_disposition = 0; + bool delete_on_close = false; + bool break_to_none = false; + bool attrs_only = false; status = odb_pull_record(lck, &file); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { @@ -728,32 +758,15 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, } NT_STATUS_NOT_OK_RETURN(status); - if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - file.num_entries != 0) { - return NT_STATUS_SHARING_VIOLATION; + if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { + delete_on_close = true; } - if (file.delete_on_close) { - return NT_STATUS_DELETE_PENDING; - } - - e.server = odb->ntvfs_ctx->server_id; - e.file_handle = NULL; - e.stream_id = 0; - e.share_access = share_access; - e.access_mask = access_mask; - - for (i=0;i Date: Mon, 25 Feb 2008 20:20:35 +0100 Subject: opendb_tdb: only file->delete_on_close == true should give DELETE_PENDING metze (This used to be commit 5b12157e0f0f1cf6ea90503a72b56ab2032cb6e5) --- source4/ntvfs/common/opendb_tdb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 9c273f9617..8b5e4850d9 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -346,12 +346,15 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, } } - if (file->delete_on_close || - (file->num_entries != 0 && delete_on_close)) { + if (file->delete_on_close) { /* while delete on close is set, no new opens are allowed */ return NT_STATUS_DELETE_PENDING; } + if (file->num_entries != 0 && delete_on_close) { + return NT_STATUS_SHARING_VIOLATION; + } + /* check for sharing violations */ for (i=0;inum_entries;i++) { status = share_conflict(&file->entries[i], stream_id, -- cgit From 69631a215b655415477ee0e71a08beca86dd5b2f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Feb 2008 09:14:54 +0100 Subject: pvfs_setfileinfo_rename: map DELETE_PENDING to ACCESS_DENIED This is needed as odb_can_open/pvfs_can_delete changed the return value. metze (This used to be commit 1ba0b9a8f1f84c7c949b3d184843462b87446707) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index fbbb8c2d4b..c6d014a72f 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -152,6 +152,9 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, } status = pvfs_can_delete(pvfs, req, name2, NULL); + if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { + return NT_STATUS_ACCESS_DENIED; + } if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { return NT_STATUS_ACCESS_DENIED; } -- cgit From facdc472c7e6dbca0553a5e0dfb100be322339ce Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 16:47:48 +0100 Subject: opendb: pass down open_disposition and break_to_none to odb_open_file() metze (This used to be commit aaaa26ae5e810495f313dfada771a8de86cedbd4) --- source4/ntvfs/common/opendb.c | 13 +++++++------ source4/ntvfs/common/opendb.h | 7 ++++--- source4/ntvfs/common/opendb_tdb.c | 7 +++---- 3 files changed, 14 insertions(+), 13 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 3f5d7210be..c380355466 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -93,15 +93,16 @@ _PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) Note that the path is only used by the delete on close logic, not for comparing with other filenames */ -_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, - uint32_t stream_id, uint32_t share_access, +_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, + void *file_handle, const char *path, + uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, - const char *path, + uint32_t open_disposition, bool break_to_none, uint32_t oplock_level, uint32_t *oplock_granted) { - return ops->odb_open_file(lck, file_handle, stream_id, share_access, - access_mask, delete_on_close, path, oplock_level, - oplock_granted); + return ops->odb_open_file(lck, file_handle, path, stream_id, share_access, + access_mask, delete_on_close, open_disposition, + break_to_none, oplock_level, oplock_granted); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index c46390446c..205d2228ea 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -25,10 +25,11 @@ struct opendb_ops { struct odb_lock *(*odb_lock)(TALLOC_CTX *mem_ctx, struct odb_context *odb, DATA_BLOB *file_key); DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck); - NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle, - uint32_t stream_id, uint32_t share_access, + NTSTATUS (*odb_open_file)(struct odb_lock *lck, + void *file_handle, const char *path, + uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, - const char *path, + uint32_t open_disposition, bool break_to_none, uint32_t oplock_level, uint32_t *oplock_granted); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 8b5e4850d9..d41a5c371e 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -388,18 +388,17 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, Note that the path is only used by the delete on close logic, not for comparing with other filenames */ -static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, +static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, + void *file_handle, const char *path, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, - const char *path, + uint32_t open_disposition, bool break_to_none, uint32_t oplock_level, uint32_t *oplock_granted) { struct odb_context *odb = lck->odb; struct opendb_entry e; struct opendb_file file; NTSTATUS status; - uint32_t open_disposition = 0; - bool break_to_none = false; bool attrs_only = false; if (odb->oplocks == false) { -- cgit From 9852e0d31582f669179c2a8c8ebdb263fef611f2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 16:49:40 +0100 Subject: pvfs_open: pass down open_disposition and break_to_none to odb_open_file() metze (This used to be commit 46500983fe2f63540a67e2e963ab264fa8a090d0) --- source4/ntvfs/posix/pvfs_open.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3a8b17ab16..1b5ea56d64 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -296,9 +296,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, f->handle, f->handle->name->stream_id, + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, - name->full_name, OPLOCK_NONE, NULL); + io->generic.in.open_disposition, + false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); @@ -349,9 +350,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_open_file(lck, f->handle, f->handle->name->stream_id, + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, - name->full_name, OPLOCK_NONE, NULL); + io->generic.in.open_disposition, + false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; @@ -669,9 +671,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, oplock_level = OPLOCK_EXCLUSIVE; } - status = odb_open_file(lck, f->handle, name->stream_id, + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, - name->full_name, oplock_level, &oplock_granted); + io->generic.in.open_disposition, + false, oplock_level, &oplock_granted); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { /* bad news, we must have hit a race - we don't delete the file @@ -1186,9 +1189,10 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, f->handle, f->handle->name->stream_id, + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, - name->full_name, oplock_level, &oplock_granted); + io->generic.in.open_disposition, + false, oplock_level, &oplock_granted); /* on a sharing violation we need to retry when the file is closed by the other user, or after 1 second */ -- cgit From 7264a8b7ca5f91120dbc30fcbe8e8402f09ae883 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 17:48:13 +0100 Subject: opendb: unify the parameters of odb_open_file() and odb_can_open() metze (This used to be commit e6b708a52b0eada3fd374b66292ded3b0f6ce217) --- source4/ntvfs/common/opendb.c | 8 +++++--- source4/ntvfs/common/opendb.h | 5 +++-- source4/ntvfs/common/opendb_tdb.c | 13 +++---------- 3 files changed, 11 insertions(+), 15 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index c380355466..36144d0406 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -166,10 +166,12 @@ _PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, create_options and access_mask */ _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, - uint32_t share_access, uint32_t create_options, - uint32_t access_mask) + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, bool delete_on_close, + uint32_t open_disposition, bool break_to_none) { - return ops->odb_can_open(lck, share_access, create_options, access_mask); + return ops->odb_can_open(lck, stream_id, share_access, access_mask, + delete_on_close, open_disposition, break_to_none); } _PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle, diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 205d2228ea..9591bcf6b9 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -40,8 +40,9 @@ struct opendb_ops { DATA_BLOB *key, bool *del_on_close, int *open_count, char **path); NTSTATUS (*odb_can_open)(struct odb_lock *lck, - uint32_t share_access, uint32_t create_options, - uint32_t access_mask); + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, bool delete_on_close, + uint32_t open_disposition, bool break_to_none); NTSTATUS (*odb_update_oplock)(struct odb_lock *lck, void *file_handle, uint32_t oplock_level); NTSTATUS (*odb_break_oplocks)(struct odb_lock *lck); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index d41a5c371e..73c04b7c4f 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -742,16 +742,13 @@ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, create_options and access_mask */ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, - uint32_t share_access, uint32_t create_options, - uint32_t access_mask) + uint32_t stream_id, uint32_t share_access, + uint32_t access_mask, bool delete_on_close, + uint32_t open_disposition, bool break_to_none) { struct odb_context *odb = lck->odb; NTSTATUS status; struct opendb_file file; - uint32_t stream_id = 0; - uint32_t open_disposition = 0; - bool delete_on_close = false; - bool break_to_none = false; bool attrs_only = false; status = odb_pull_record(lck, &file); @@ -760,10 +757,6 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, } NT_STATUS_NOT_OK_RETURN(status); - if (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) { - delete_on_close = true; - } - status = odb_tdb_open_can_internal(odb, &file, stream_id, share_access, access_mask, delete_on_close, open_disposition, -- cgit From c93cf42d9fe4f1e382a762e7c1eafef0dff122c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 17:50:22 +0100 Subject: pvfs_open: fix odb_can_open() callers after prototype change metze (This used to be commit 904159327b3cb80fbec6aa5a4feaa141190a3f3a) --- source4/ntvfs/posix/pvfs_open.c | 51 ++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1b5ea56d64..bbfe4ac733 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1428,6 +1428,9 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, NTSTATUS status; DATA_BLOB key; struct odb_lock *lck; + uint32_t share_access; + uint32_t access_mask; + bool delete_on_close; status = pvfs_locking_key(name, name, &key); if (!NT_STATUS_IS_OK(status)) { @@ -1440,15 +1443,18 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_can_open(lck, - NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE | - NTCREATEX_SHARE_ACCESS_DELETE, - NTCREATEX_OPTIONS_DELETE_ON_CLOSE, - SEC_STD_DELETE); + share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + access_mask = SEC_STD_DELETE; + delete_on_close = true; + + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, delete_on_close, + 0, false); if (NT_STATUS_IS_OK(status)) { - status = pvfs_access_check_simple(pvfs, req, name, SEC_STD_DELETE); + status = pvfs_access_check_simple(pvfs, req, name, access_mask); } /* @@ -1487,6 +1493,9 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, NTSTATUS status; DATA_BLOB key; struct odb_lock *lck; + uint32_t share_access; + uint32_t access_mask; + bool delete_on_close; status = pvfs_locking_key(name, name, &key); if (!NT_STATUS_IS_OK(status)) { @@ -1499,11 +1508,14 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_can_open(lck, - NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE, - 0, - SEC_STD_DELETE); + share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + access_mask = SEC_STD_DELETE; + delete_on_close = false; + + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, delete_on_close, + 0, false); /* * if it's a sharing violation or we got no oplock @@ -1540,6 +1552,9 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, NTSTATUS status; DATA_BLOB key; struct odb_lock *lck; + uint32_t share_access; + uint32_t access_mask; + bool delete_on_close; status = pvfs_locking_key(name, name, &key); if (!NT_STATUS_IS_OK(status)) { @@ -1552,10 +1567,14 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = odb_can_open(lck, - NTCREATEX_SHARE_ACCESS_READ | - NTCREATEX_SHARE_ACCESS_WRITE, - 0, 0); + share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE; + access_mask = 0; + delete_on_close = false; + + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, delete_on_close, + 0, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); -- cgit From d7ea52e9a3cd920f7c8a3b00f7cd28a7f605a993 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 21 Feb 2008 17:48:13 +0100 Subject: pvfs_open: make the retry logic indepdendent from open and sharing violations metze (This used to be commit 56bd63a4236ebf360d3e805c8560df86759573f7) --- source4/ntvfs/posix/pvfs_open.c | 149 ++++++++++++++++++++++++++-------------- source4/ntvfs/posix/vfs_posix.h | 5 ++ 2 files changed, 104 insertions(+), 50 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index bbfe4ac733..8e1870fa70 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -751,20 +751,25 @@ cleanup_delete: return status; } - /* - state of a pending open retry + state of a pending retry */ -struct pvfs_open_retry { +struct pvfs_odb_retry { struct ntvfs_module_context *ntvfs; struct ntvfs_request *req; - union smb_open *io; - struct pvfs_wait *wait_handle; DATA_BLOB odb_locking_key; + void *io; + void *private_data; + void (*callback)(struct pvfs_odb_retry *r, + struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *io, + void *private_data, + enum pvfs_wait_notice reason); }; -/* destroy a pending open request */ -static int pvfs_retry_destructor(struct pvfs_open_retry *r) +/* destroy a pending request */ +static int pvfs_odb_retry_destructor(struct pvfs_odb_retry *r) { struct pvfs_state *pvfs = r->ntvfs->private_data; if (r->odb_locking_key.data) { @@ -778,15 +783,92 @@ static int pvfs_retry_destructor(struct pvfs_open_retry *r) return 0; } +static void pvfs_odb_retry_callback(void *_r, enum pvfs_wait_notice reason) +{ + struct pvfs_odb_retry *r = talloc_get_type(_r, struct pvfs_odb_retry); + + if (reason == PVFS_WAIT_EVENT) { + /* + * The pending odb entry is already removed. + * We use a null locking key to indicate this + * to the destructor. + */ + data_blob_free(&r->odb_locking_key); + } + + r->callback(r, r->ntvfs, r->req, r->io, r->private_data, reason); +} + /* - retry an open + setup for a retry of a request that was rejected + by odb_open_file() or odb_can_open() */ -static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) +NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct odb_lock *lck, + struct timeval end_time, + void *io, + void *private_data, + void (*callback)(struct pvfs_odb_retry *r, + struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *io, + void *private_data, + enum pvfs_wait_notice reason)) { - struct pvfs_open_retry *r = private; - struct ntvfs_module_context *ntvfs = r->ntvfs; - struct ntvfs_request *req = r->req; - union smb_open *io = r->io; + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_odb_retry *r; + struct pvfs_wait *wait_handle; + NTSTATUS status; + + r = talloc(req, struct pvfs_odb_retry); + NT_STATUS_HAVE_NO_MEMORY(r); + + r->ntvfs = ntvfs; + r->req = req; + r->io = io; + r->private_data = private_data; + r->callback = callback; + r->odb_locking_key = odb_get_key(r, lck); + if (r->odb_locking_key.data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* setup a pending lock */ + status = odb_open_file_pending(lck, r); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + talloc_free(lck); + + talloc_set_destructor(r, pvfs_odb_retry_destructor); + + wait_handle = pvfs_wait_message(pvfs, req, + MSG_PVFS_RETRY_OPEN, end_time, + pvfs_odb_retry_callback, r); + if (wait_handle == NULL) { + return NT_STATUS_NO_MEMORY; + } + + talloc_steal(r, wait_handle); + + talloc_steal(pvfs, r); + + return NT_STATUS_OK; +} + +/* + retry an open after a sharing violation +*/ +static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r, + struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *_io, + void *private_data, + enum pvfs_wait_notice reason) +{ + union smb_open *io = talloc_get_type(_io, union smb_open); NTSTATUS status; /* w2k3 ignores SMBntcancel for outstanding open requests. It's probably @@ -795,8 +877,6 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) return; } - talloc_free(r->wait_handle); - if (reason == PVFS_WAIT_TIMEOUT) { /* if it timed out, then give the failure immediately */ @@ -806,9 +886,6 @@ static void pvfs_open_retry(void *private, enum pvfs_wait_notice reason) return; } - /* the pending odb entry is already removed. We use a null locking - key to indicate this */ - data_blob_free(&r->odb_locking_key); talloc_free(r); /* try the open again, which could trigger another retry setup @@ -925,7 +1002,6 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, struct odb_lock *lck) { struct pvfs_state *pvfs = ntvfs->private_data; - struct pvfs_open_retry *r; NTSTATUS status; struct timeval end_time; @@ -939,40 +1015,13 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, } } - r = talloc(req, struct pvfs_open_retry); - if (r == NULL) { - return NT_STATUS_NO_MEMORY; - } - - r->ntvfs = ntvfs; - r->req = req; - r->io = io; - r->odb_locking_key = data_blob_talloc(r, - f->handle->odb_locking_key.data, - f->handle->odb_locking_key.length); - - end_time = timeval_add(&req->statistics.request_time, 0, pvfs->sharing_violation_delay); - - /* setup a pending lock */ - status = odb_open_file_pending(lck, r); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - talloc_free(lck); + /* the retry should allocate a new file handle */ talloc_free(f); - talloc_set_destructor(r, pvfs_retry_destructor); - - r->wait_handle = pvfs_wait_message(pvfs, req, MSG_PVFS_RETRY_OPEN, end_time, - pvfs_open_retry, r); - if (r->wait_handle == NULL) { - return NT_STATUS_NO_MEMORY; - } - - talloc_steal(pvfs, r); + end_time = timeval_add(&req->statistics.request_time, 0, pvfs->sharing_violation_delay); - return NT_STATUS_OK; + return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL, + pvfs_retry_open_sharing); } /* diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 84c456dcfe..50875c3f9b 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -230,6 +230,11 @@ struct pvfs_dir; /* types of notification for pvfs wait events */ enum pvfs_wait_notice {PVFS_WAIT_EVENT, PVFS_WAIT_TIMEOUT, PVFS_WAIT_CANCEL}; +/* + state of a pending retry +*/ +struct pvfs_odb_retry; + #define PVFS_EADB "posix:eadb" #define PVFS_XATTR "posix:xattr" #define PVFS_FAKE_OPLOCKS "posix:fakeoplocks" -- cgit From 95fafa694cbb6f695488c750d481bb1e427da6eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 08:32:35 +0100 Subject: pvfs: add pvfs_setup_oplock() to receive oplock breaks and pass them to the client metze (This used to be commit b09a2b126723bd75afd245f549703a04e512e129) --- source4/ntvfs/posix/config.mk | 1 + source4/ntvfs/posix/pvfs_oplock.c | 136 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 source4/ntvfs/posix/pvfs_oplock.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 6879940337..88048c2af7 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -53,6 +53,7 @@ OBJ_FILES = \ pvfs_resolve.o \ pvfs_shortname.o \ pvfs_lock.o \ + pvfs_oplock.o \ pvfs_wait.o \ pvfs_seek.o \ pvfs_ioctl.o \ diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c new file mode 100644 index 0000000000..50b1478f13 --- /dev/null +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -0,0 +1,136 @@ +/* + Unix SMB/CIFS implementation. + + POSIX NTVFS backend - oplock handling + + Copyright (C) Stefan Metzmacher 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "lib/messaging/messaging.h" +#include "lib/messaging/irpc.h" +#include "vfs_posix.h" + + +struct pvfs_oplock { + struct pvfs_file_handle *handle; + struct pvfs_file *file; + uint32_t level; + struct messaging_context *msg_ctx; +}; + +/* + receive oplock breaks and forward them to the client +*/ +static void pvfs_oplock_break(struct pvfs_oplock *opl, uint8_t level) +{ + NTSTATUS status; + struct pvfs_file *f = opl->file; + struct pvfs_file_handle *h = opl->handle; + struct pvfs_state *pvfs = h->pvfs; + + DEBUG(10,("pvfs_oplock_break: sending oplock break level %d for '%s' %p\n", + level, h->name->original_name, h)); + status = ntvfs_send_oplock_break(pvfs->ntvfs, f->ntvfs, level); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("pvfs_oplock_break: sending oplock break failed: %s\n", + nt_errstr(status))); + } +} + +static void pvfs_oplock_break_dispatch(struct messaging_context *msg, + void *private_data, uint32_t msg_type, + struct server_id src, DATA_BLOB *data) +{ + struct pvfs_oplock *opl = talloc_get_type(private_data, + struct pvfs_oplock); + struct opendb_oplock_break opb; + + ZERO_STRUCT(opb); + + /* we need to check that this one is for us. See + messaging_send_ptr() for the other side of this. + */ + if (data->length == sizeof(struct opendb_oplock_break)) { + struct opendb_oplock_break *p; + p = (struct opendb_oplock_break *)data->data; + opb = *p; + } else { + DEBUG(0,("%s: ignore oplock break with length[%u]\n", + __location__, data->length)); + return; + } + if (opb.file_handle != opl->handle) { + return; + } + + /* + * maybe we should use ntvfs_setup_async() + */ + pvfs_oplock_break(opl, opb.level); +} + +static int pvfs_oplock_destructor(struct pvfs_oplock *opl) +{ + messaging_deregister(opl->msg_ctx, MSG_NTVFS_OPLOCK_BREAK, opl); + return 0; +} + +NTSTATUS pvfs_setup_oplock(struct pvfs_file *f, uint32_t oplock_granted) +{ + NTSTATUS status; + struct pvfs_oplock *opl; + uint32_t level = OPLOCK_NONE; + + f->handle->oplock = NULL; + + switch (oplock_granted) { + case EXCLUSIVE_OPLOCK_RETURN: + level = OPLOCK_EXCLUSIVE; + break; + case BATCH_OPLOCK_RETURN: + level = OPLOCK_BATCH; + break; + case LEVEL_II_OPLOCK_RETURN: + level = OPLOCK_LEVEL_II; + break; + } + + if (level == OPLOCK_NONE) { + return NT_STATUS_OK; + } + + opl = talloc(f->handle, struct pvfs_oplock); + NT_STATUS_HAVE_NO_MEMORY(opl); + + opl->handle = f->handle; + opl->file = f; + opl->level = level; + opl->msg_ctx = f->pvfs->ntvfs->ctx->msg_ctx; + + status = messaging_register(opl->msg_ctx, + opl, + MSG_NTVFS_OPLOCK_BREAK, + pvfs_oplock_break_dispatch); + NT_STATUS_NOT_OK_RETURN(status); + + /* destructor */ + talloc_set_destructor(opl, pvfs_oplock_destructor); + + f->handle->oplock = opl; + + return NT_STATUS_OK; +} -- cgit From be1ba5b63164e7dab4bf067bc1aac4ed9cece2bc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 08:39:13 +0100 Subject: pvfs_open: call pvfs_setup_oplock() if an oplock was granted This is needed to receive oplock breaks from other "processes" metze (This used to be commit dd56f55afdc0d114a0b0bceb0e4feb022919323a) --- source4/ntvfs/posix/pvfs_open.c | 22 +++++++++++++++++++--- source4/ntvfs/posix/vfs_posix.h | 8 ++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 8e1870fa70..8429c14d1b 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -268,6 +268,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; + f->handle->oplock = NULL; f->handle->sticky_write_time = false; f->handle->open_completed = false; @@ -684,9 +685,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } - if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { - oplock_granted = OPLOCK_BATCH; - } f->ntvfs = h; f->pvfs = pvfs; @@ -705,12 +703,23 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; + f->handle->oplock = NULL; f->handle->have_opendb_entry = true; f->handle->sticky_write_time = false; f->handle->open_completed = false; DLIST_ADD(pvfs->files.list, f); + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { + oplock_granted = OPLOCK_BATCH; + } else if (oplock_granted != OPLOCK_NONE) { + status = pvfs_setup_oplock(f, oplock_granted); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } + } + /* setup a destructor to avoid file descriptor leaks on abnormal termination */ talloc_set_destructor(f, pvfs_fnum_destructor); @@ -1185,6 +1194,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->seek_offset = 0; f->handle->position = 0; f->handle->mode = 0; + f->handle->oplock = NULL; f->handle->have_opendb_entry = false; f->handle->sticky_write_time = false; f->handle->open_completed = false; @@ -1257,6 +1267,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { oplock_granted = OPLOCK_BATCH; + } else if (oplock_granted != OPLOCK_NONE) { + status = pvfs_setup_oplock(f, oplock_granted); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } } f->handle->have_opendb_entry = true; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 50875c3f9b..72469505cc 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -29,6 +29,7 @@ #include "dsdb/samdb/samdb.h" struct pvfs_wait; +struct pvfs_oplock; /* this is the private structure for the posix vfs backend. It is used to hold per-connection (per tree connect) state information */ @@ -154,6 +155,13 @@ struct pvfs_file_handle { bool have_opendb_entry; + /* + * we need to wait for oplock break requests from other processes, + * and we need to remember the pvfs_file so we can correctly + * forward the oplock break to the client + */ + struct pvfs_oplock *oplock; + /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; -- cgit From 4ee328d7d26f1a86559993f6533b8a1e12a4c6a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 09:51:58 +0100 Subject: pvfs: handle oplock releases in its own function pvfs_oplock_release() metze (This used to be commit 27ec7bfc8b7f46c97e6878caf5cd694c517ce053) --- source4/ntvfs/posix/pvfs_lock.c | 11 +++---- source4/ntvfs/posix/pvfs_oplock.c | 64 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index df85b2b775..0796286b7e 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -294,6 +294,10 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return ntvfs_map_lock(ntvfs, req, lck); } + if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) { + return pvfs_oplock_release(ntvfs, req, lck); + } + f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; @@ -338,13 +342,6 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks); } - if (lck->lockx.in.mode & LOCKING_ANDX_OPLOCK_RELEASE) { - DEBUG(0,("received unexpected oplock break\n")); - talloc_free(pending); - return NT_STATUS_NOT_IMPLEMENTED; - } - - /* the unlocks happen first */ locks = lck->lockx.in.locks; diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c index 50b1478f13..eff9ae1f1d 100644 --- a/source4/ntvfs/posix/pvfs_oplock.c +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -134,3 +134,67 @@ NTSTATUS pvfs_setup_oplock(struct pvfs_file *f, uint32_t oplock_granted) return NT_STATUS_OK; } + +NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lock *lck) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + struct pvfs_file_handle *h; + struct odb_lock *olck; + uint8_t oplock_break; + NTSTATUS status; + + f = pvfs_find_fd(pvfs, req, lck->lockx.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + h = f->handle; + + if (h->fd == -1) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + + if (!h->have_opendb_entry) { + return NT_STATUS_FOOBAR; + } + + if (!h->oplock) { + return NT_STATUS_FOOBAR; + } + + olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); + if (olck == NULL) { + DEBUG(0,("Unable to lock opendb for oplock update\n")); + return NT_STATUS_FOOBAR; + } + + oplock_break = (lck->lockx.in.mode >> 8) & 0xFF; + if (oplock_break == OPLOCK_BREAK_TO_NONE) { + h->oplock->level = OPLOCK_NONE; + } else if (oplock_break == OPLOCK_BREAK_TO_LEVEL_II) { + h->oplock->level = OPLOCK_LEVEL_II; + } else { + /* fallback to level II in case of a invalid value */ + DEBUG(1,("unexpected oplock break level[0x%02X]\n", oplock_break)); + h->oplock->level = OPLOCK_LEVEL_II; + } + status = odb_update_oplock(olck, h, h->oplock->level); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to update oplock level for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + talloc_free(olck); + return status; + } + + talloc_free(olck); + + /* after a break to none, we no longer have an oplock attached */ + if (h->oplock->level == OPLOCK_NONE) { + talloc_free(h->oplock); + h->oplock = NULL; + } + + return NT_STATUS_OK; +} -- cgit From 348439e9301fa3b07f5263a6dabc61557a384179 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 16:34:50 +0100 Subject: pvfs_oplocks: add pvfs_break_level2_oplocks() metze (This used to be commit e0837238b6b09143970f03b6a78201c3fe55f3cd) --- source4/ntvfs/posix/pvfs_oplock.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c index eff9ae1f1d..cf30ddbc59 100644 --- a/source4/ntvfs/posix/pvfs_oplock.c +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -198,3 +198,42 @@ NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } + +NTSTATUS pvfs_break_level2_oplocks(struct pvfs_file *f) +{ + struct pvfs_file_handle *h = f->handle; + struct odb_lock *olck; + NTSTATUS status; + + if (h->oplock && h->oplock->level == OPLOCK_EXCLUSIVE) { + return NT_STATUS_OK; + } + + olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); + if (olck == NULL) { + DEBUG(0,("Unable to lock opendb for oplock update\n")); + return NT_STATUS_FOOBAR; + } + + if (h->oplock && h->oplock->level == OPLOCK_BATCH) { + status = odb_update_oplock(olck, h, OPLOCK_LEVEL_II); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to update oplock level for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + talloc_free(olck); + return status; + } + } + + status = odb_break_oplocks(olck); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to break level2 oplocks to none for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + talloc_free(olck); + return status; + } + + talloc_free(olck); + + return NT_STATUS_OK; +} -- cgit From 4344ac6209df4be2dad6a8b1c0766101f5972f13 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 16:34:50 +0100 Subject: pvfs: send oplock breaks to none to level2 holders on write/lock requests metze (This used to be commit b8c42a1ff8fd4131ef2a1ad92a7405a2e4d335d3) --- source4/ntvfs/posix/pvfs_lock.c | 3 +++ source4/ntvfs/posix/pvfs_write.c | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 0796286b7e..baa92880f1 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -307,6 +307,9 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_FILE_IS_A_DIRECTORY; } + status = pvfs_break_level2_oplocks(f); + NT_STATUS_NOT_OK_RETURN(status); + if (lck->lockx.in.timeout != 0 && (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { pending = talloc(f, struct pvfs_pending_lock); diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 5a11f01952..dda8c83407 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -57,7 +57,10 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, wr->writex.in.count, WRITE_LOCK); NT_STATUS_NOT_OK_RETURN(status); - + + status = pvfs_break_level2_oplocks(f); + NT_STATUS_NOT_OK_RETURN(status); + if (f->handle->name->stream_name) { ret = pvfs_stream_write(pvfs, f->handle, -- cgit From ee81b7a85e8bb749a00c85bfdcf8f1e341ad2eea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 23 Feb 2008 11:46:43 +0100 Subject: pvfs_setfileinfo: break level2 oplocks on setfileinfo() ALLOCATION_INFO and END_OF_FILE_INFO metze (This used to be commit b258f9d8d4bf3606f4884d1bff548f16dadc08aa) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index c6d014a72f..d1d8f819ef 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -355,6 +355,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: + status = pvfs_break_level2_oplocks(f); + NT_STATUS_NOT_OK_RETURN(status); + newstats.dos.alloc_size = info->allocation_info.in.alloc_size; if (newstats.dos.alloc_size < newstats.st.st_size) { newstats.st.st_size = newstats.dos.alloc_size; @@ -365,6 +368,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + status = pvfs_break_level2_oplocks(f); + NT_STATUS_NOT_OK_RETURN(status); + newstats.st.st_size = info->end_of_file_info.in.size; break; -- cgit From c0d1543a6a5fee3d767a366186dd634a395c8146 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 25 Feb 2008 19:17:45 +0100 Subject: pvfs: add posix:oplocktimeout=30 option metze (This used to be commit 5abc57ddab558c13db3864d13afc2ad3b1641d1c) --- source4/ntvfs/posix/vfs_posix.c | 4 ++++ source4/ntvfs/posix/vfs_posix.h | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index e058e6f546..ca874d1db1 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -91,6 +91,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) PVFS_SHARE_DELAY, PVFS_SHARE_DELAY_DEFAULT); + pvfs->oplock_break_timeout = share_int_option(scfg, + PVFS_OPLOCK_TIMEOUT, + PVFS_OPLOCK_TIMEOUT_DEFAULT); + pvfs->share_name = talloc_strdup(pvfs, scfg->name); pvfs->fs_attribs = diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 72469505cc..4d22a91714 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -52,9 +52,12 @@ struct pvfs_state { ntcancel */ struct pvfs_wait *wait_list; - /* the sharing violation timeout */ + /* the sharing violation timeout (nsecs) */ uint_t sharing_violation_delay; + /* the oplock break timeout (secs) */ + uint_t oplock_break_timeout; + /* filesystem attributes (see FS_ATTR_*) */ uint32_t fs_attribs; @@ -247,6 +250,7 @@ struct pvfs_odb_retry; #define PVFS_XATTR "posix:xattr" #define PVFS_FAKE_OPLOCKS "posix:fakeoplocks" #define PVFS_SHARE_DELAY "posix:sharedelay" +#define PVFS_OPLOCK_TIMEOUT "posix:oplocktimeout" #define PVFS_ALLOCATION_ROUNDING "posix:allocationrounding" #define PVFS_SEARCH_INACTIVITY "posix:searchinactivity" #define PVFS_ACL "posix:acl" @@ -254,7 +258,8 @@ struct pvfs_odb_retry; #define PVFS_XATTR_DEFAULT true #define PVFS_FAKE_OPLOCKS_DEFAULT false -#define PVFS_SHARE_DELAY_DEFAULT 1000000 +#define PVFS_SHARE_DELAY_DEFAULT 1000000 /* nsecs */ +#define PVFS_OPLOCK_TIMEOUT_DEFAULT 30 /* secs */ #define PVFS_ALLOCATION_ROUNDING_DEFAULT 512 #define PVFS_SEARCH_INACTIVITY_DEFAULT 300 -- cgit From 61e17794c394d2c070ce7df9cee6c53d846e7b75 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 22 Feb 2008 11:52:17 +0100 Subject: pvfs_unlink: retry unlink after oplock not granted metze (This used to be commit 746e89ce2e74dbd2cea8f5575c403e4c61f82cb8) --- source4/ntvfs/posix/pvfs_open.c | 26 ++++++++--- source4/ntvfs/posix/pvfs_unlink.c | 94 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 7 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 8429c14d1b..4110df292d 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1008,7 +1008,8 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io, struct pvfs_file *f, - struct odb_lock *lck) + struct odb_lock *lck, + NTSTATUS parent_status) { struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; @@ -1027,7 +1028,15 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, /* the retry should allocate a new file handle */ talloc_free(f); - end_time = timeval_add(&req->statistics.request_time, 0, pvfs->sharing_violation_delay); + if (NT_STATUS_EQUAL(parent_status, NT_STATUS_SHARING_VIOLATION)) { + end_time = timeval_add(&req->statistics.request_time, + 0, pvfs->sharing_violation_delay); + } else if (NT_STATUS_EQUAL(parent_status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + end_time = timeval_add(&req->statistics.request_time, + pvfs->oplock_break_timeout, 0); + } else { + return NT_STATUS_INTERNAL_ERROR; + } return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL, pvfs_retry_open_sharing); @@ -1253,11 +1262,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, io->generic.in.open_disposition, false, oplock_level, &oplock_granted); - /* on a sharing violation we need to retry when the file is closed by - the other user, or after 1 second */ - if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) && + /* + * on a sharing violation we need to retry when the file is closed by + * the other user, or after 1 second + * on a non granted oplock we need to retry when the file is closed by + * the other user, or after 30 seconds + */ + if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) && (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return pvfs_open_setup_retry(ntvfs, req, io, f, lck); + return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status); } if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index bda4014bee..7a2d964b9d 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -23,6 +23,84 @@ #include "vfs_posix.h" #include "system/dir.h" +/* + retry an open after a sharing violation +*/ +static void pvfs_retry_unlink(struct pvfs_odb_retry *r, + struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *_io, + void *private_data, + enum pvfs_wait_notice reason) +{ + union smb_unlink *io = talloc_get_type(_io, union smb_unlink); + NTSTATUS status = NT_STATUS_INTERNAL_ERROR; + + talloc_free(r); + + switch (reason) { + case PVFS_WAIT_CANCEL: +/*TODO*/ + status = NT_STATUS_CANCELLED; + break; + case PVFS_WAIT_TIMEOUT: + /* if it timed out, then give the failure + immediately */ +/*TODO*/ + status = NT_STATUS_SHARING_VIOLATION; + break; + case PVFS_WAIT_EVENT: + + /* try the open again, which could trigger another retry setup + if it wants to, so we have to unmark the async flag so we + will know if it does a second async reply */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC; + + status = pvfs_unlink(ntvfs, req, io); + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { + /* the 2nd try also replied async, so we don't send + the reply yet */ + return; + } + + /* re-mark it async, just in case someone up the chain does + paranoid checking */ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + break; + } + + /* send the reply up the chain */ + req->async_states->status = status; + req->async_states->send_fn(req); +} + +/* + setup for a unlink retry after a sharing violation + or a non granted oplock +*/ +static NTSTATUS pvfs_unlink_setup_retry(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_unlink *io, + struct odb_lock *lck, + NTSTATUS status) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct timeval end_time; + + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { + end_time = timeval_add(&req->statistics.request_time, + 0, pvfs->sharing_violation_delay); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + end_time = timeval_add(&req->statistics.request_time, + pvfs->oplock_break_timeout, 0); + } else { + return NT_STATUS_INTERNAL_ERROR; + } + + return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL, + pvfs_retry_unlink); +} + /* unlink a file @@ -67,6 +145,7 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, struct pvfs_filename *name) { NTSTATUS status; + struct odb_lock *lck = NULL; /* make sure its matches the given attributes */ status = pvfs_match_attrib(pvfs, name, @@ -75,7 +154,20 @@ static NTSTATUS pvfs_unlink_one(struct pvfs_state *pvfs, return status; } - status = pvfs_can_delete(pvfs, req, name, NULL); + status = pvfs_can_delete(pvfs, req, name, &lck); + + /* + * on a sharing violation we need to retry when the file is closed by + * the other user, or after 1 second + * on a non granted oplock we need to retry when the file is closed by + * the other user, or after 30 seconds + */ + if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_unlink_setup_retry(pvfs->ntvfs, req, unl, lck, status); + } + if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 4eb0fcc5173ddf50305fa5094ec0d87d53d71a33 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 23 Feb 2008 11:49:39 +0100 Subject: pvfs_open: add pvfs_can_update_file_size() TODO: this is not complete, we need more tests to trigger this metze (This used to be commit 66ad1081f2be8a0caa16fb0d614b857a5bde751c) --- source4/ntvfs/posix/pvfs_open.c | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 4110df292d..12b70c00fd 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1620,6 +1620,68 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, return status; } +/* + determine if the file size of a file can be changed, + or if it is prevented by an already open file +*/ +NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs, + struct ntvfs_request *req, + struct pvfs_filename *name, + struct odb_lock **lckp) +{ + NTSTATUS status; + DATA_BLOB key; + struct odb_lock *lck; + uint32_t share_access; + uint32_t access_mask; + bool break_to_none; + bool delete_on_close; + + status = pvfs_locking_key(name, name, &key); + if (!NT_STATUS_IS_OK(status)) { + return NT_STATUS_NO_MEMORY; + } + + lck = odb_lock(req, pvfs->odb_context, &key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for can_stat\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + /* TODO: this may needs some more flags */ + share_access = NTCREATEX_SHARE_ACCESS_WRITE; + access_mask = 0; + delete_on_close = false; + break_to_none = true; + + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, delete_on_close, + 0, break_to_none); + + /* + * if it's a sharing violation or we got no oplock + * only keep the lock if the caller requested access + * to the lock + */ + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + if (lckp) { + *lckp = lck; + } else { + talloc_free(lck); + } + } else if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + if (lckp) { + *lckp = NULL; + } + } else if (lckp) { + *lckp = lck; + } + + return status; +} + /* determine if file meta data can be accessed, or if it is prevented by an already open file -- cgit From fa2e4ba03cd65f850d8f118ce61d5c4a80f0e30a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 23 Feb 2008 11:50:19 +0100 Subject: pvfs_setpathinfo: retry setpathinfo after oplock not granted on on setpathinfo ALLOCATION_INFO and END_OF_FILE_INFO metze (This used to be commit 4e27ac8c529d5a1675fb02215191a2be7913ec97) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 107 +++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index d1d8f819ef..da1e31e639 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -472,6 +472,84 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return pvfs_dosattrib_save(pvfs, h->name, h->fd); } +/* + retry an open after a sharing violation +*/ +static void pvfs_retry_setpathinfo(struct pvfs_odb_retry *r, + struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *_info, + void *private_data, + enum pvfs_wait_notice reason) +{ + union smb_setfileinfo *info = talloc_get_type(_info, + union smb_setfileinfo); + NTSTATUS status = NT_STATUS_INTERNAL_ERROR; + + talloc_free(r); + + switch (reason) { + case PVFS_WAIT_CANCEL: +/*TODO*/ + status = NT_STATUS_CANCELLED; + break; + case PVFS_WAIT_TIMEOUT: + /* if it timed out, then give the failure + immediately */ +/*TODO*/ + status = NT_STATUS_SHARING_VIOLATION; + break; + case PVFS_WAIT_EVENT: + + /* try the open again, which could trigger another retry setup + if it wants to, so we have to unmark the async flag so we + will know if it does a second async reply */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC; + + status = pvfs_setpathinfo(ntvfs, req, info); + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { + /* the 2nd try also replied async, so we don't send + the reply yet */ + return; + } + + /* re-mark it async, just in case someone up the chain does + paranoid checking */ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + break; + } + + /* send the reply up the chain */ + req->async_states->status = status; + req->async_states->send_fn(req); +} + +/* + setup for a unlink retry after a sharing violation + or a non granted oplock +*/ +static NTSTATUS pvfs_setpathinfo_setup_retry(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *info, + struct odb_lock *lck, + NTSTATUS status) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct timeval end_time; + + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { + end_time = timeval_add(&req->statistics.request_time, + 0, pvfs->sharing_violation_delay); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + end_time = timeval_add(&req->statistics.request_time, + pvfs->oplock_break_timeout, 0); + } else { + return NT_STATUS_INTERNAL_ERROR; + } + + return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, info, NULL, + pvfs_retry_setpathinfo); +} /* set info on a pathname @@ -486,6 +564,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct utimbuf unix_times; uint32_t access_needed; uint32_t change_mask = 0; + struct odb_lock *lck = NULL; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, @@ -560,6 +639,20 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_ALLOCATION_INFO: case RAW_SFILEINFO_ALLOCATION_INFORMATION: + status = pvfs_can_update_file_size(pvfs, req, name, &lck); + /* + * on a sharing violation we need to retry when the file is closed by + * the other user, or after 1 second + * on a non granted oplock we need to retry when the file is closed by + * the other user, or after 30 seconds + */ + if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_setpathinfo_setup_retry(pvfs->ntvfs, req, info, lck, status); + } + NT_STATUS_NOT_OK_RETURN(status); + if (info->allocation_info.in.alloc_size > newstats.dos.alloc_size) { /* strange. Increasing the allocation size via setpathinfo should be silently ignored */ @@ -575,6 +668,20 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_END_OF_FILE_INFO: case RAW_SFILEINFO_END_OF_FILE_INFORMATION: + status = pvfs_can_update_file_size(pvfs, req, name, &lck); + /* + * on a sharing violation we need to retry when the file is closed by + * the other user, or after 1 second + * on a non granted oplock we need to retry when the file is closed by + * the other user, or after 30 seconds + */ + if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_setpathinfo_setup_retry(pvfs->ntvfs, req, info, lck, status); + } + NT_STATUS_NOT_OK_RETURN(status); + newstats.st.st_size = info->end_of_file_info.in.size; break; -- cgit From 9f8fc29ea418c7ed2e2f206eb4789080ec9ab3f1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Feb 2008 10:21:39 +0100 Subject: pvfs_open: pass NTCREATEX_DISP_OPEN to odb_can_open() As 0 is NTCREATEX_DISP_SUPERSEDE and that's not what we want here. metze (This used to be commit 10c42e3d4ab71a71dfe620b40841dfe98f458c1a) --- source4/ntvfs/posix/pvfs_open.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 12b70c00fd..ef05db5eac 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1530,7 +1530,7 @@ NTSTATUS pvfs_can_delete(struct pvfs_state *pvfs, status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, false); + NTCREATEX_DISP_OPEN, false); if (NT_STATUS_IS_OK(status)) { status = pvfs_access_check_simple(pvfs, req, name, access_mask); @@ -1594,7 +1594,7 @@ NTSTATUS pvfs_can_rename(struct pvfs_state *pvfs, status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, false); + NTCREATEX_DISP_OPEN, false); /* * if it's a sharing violation or we got no oplock @@ -1656,7 +1656,7 @@ NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs, status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, break_to_none); + NTCREATEX_DISP_OPEN, break_to_none); /* * if it's a sharing violation or we got no oplock @@ -1715,7 +1715,7 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, status = odb_can_open(lck, name->stream_id, share_access, access_mask, delete_on_close, - 0, false); + NTCREATEX_DISP_OPEN, false); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); -- cgit From b40be554e7775687a01704b9af0aa272cc9019d0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Feb 2008 10:28:07 +0100 Subject: pvfs_open: pass down an access mask in pvfs_can_stat() metze (This used to be commit 6c34c7bc6801e470e5ec50aa93d0a07f7ad59314) --- source4/ntvfs/posix/pvfs_open.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index ef05db5eac..0e4250d744 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1710,7 +1710,7 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE; - access_mask = 0; + access_mask = SEC_FILE_READ_ATTRIBUTE; delete_on_close = false; status = odb_can_open(lck, name->stream_id, -- cgit From c62faaa75e2bf2c82b7a905b27d29f70ae0c7591 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Feb 2008 10:29:07 +0100 Subject: pvfs_qfileinfo: down discard the return value of pvfs_can_stat() The odb_can_open() code returns DELETE_PENDING if a delete is really pending. metze (This used to be commit 066ba3c7cfff12cb0b5298fc45eabb5fc097d056) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 2f01c08fb0..8d23d707a4 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -330,7 +330,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs, status = pvfs_can_stat(pvfs, req, name); if (!NT_STATUS_IS_OK(status)) { - return NT_STATUS_DELETE_PENDING; + return status; } status = pvfs_access_check_simple(pvfs, req, name, -- cgit From 55377f0352d73fa354e8abcf3e644c63c78d0ca6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Feb 2008 10:26:33 +0100 Subject: pvfs_open: pass down an access mask to pvfs_can_update_file_size() You just need SEC_FILE_WRITE_ATTRIBUTE to change the filesize... metze (This used to be commit 27e39063a0b759c7bced1cc9d7a6cb9192820c70) --- source4/ntvfs/posix/pvfs_open.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 0e4250d744..a01352f60c 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1648,9 +1648,19 @@ NTSTATUS pvfs_can_update_file_size(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - /* TODO: this may needs some more flags */ - share_access = NTCREATEX_SHARE_ACCESS_WRITE; - access_mask = 0; + share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + /* + * I would have thought that we would need to pass + * SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA here too + * + * But you only need SEC_FILE_WRITE_ATTRIBUTE permissions + * to set the filesize. + * + * --metze + */ + access_mask = SEC_FILE_WRITE_ATTRIBUTE; delete_on_close = false; break_to_none = true; -- cgit From 2b94ffe5e7303c1d321b9a9c6a612f77f1ac58b2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 26 Feb 2008 12:52:46 +0100 Subject: opendb_tdb: with break_to_none attribute only opens also break oplocks metze (This used to be commit c475353e34154eb13e35cc8b6cf553e3986f8677) --- source4/ntvfs/common/opendb_tdb.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 73c04b7c4f..fe5a0a8864 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -288,7 +288,8 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, } static bool access_attributes_only(uint32_t access_mask, - uint32_t open_disposition) + uint32_t open_disposition, + bool break_to_none) { switch (open_disposition) { case NTCREATEX_DISP_SUPERSEDE: @@ -298,6 +299,11 @@ static bool access_attributes_only(uint32_t access_mask, default: break; } + + if (break_to_none) { + return false; + } + #define CHECK_MASK(m,g) ((m) && (((m) & ~(g))==0) && (((m) & (g)) != 0)) return CHECK_MASK(access_mask, SEC_STD_SYNCHRONIZE | @@ -326,7 +332,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, * but we'll not grant the oplock below */ attrs_only = access_attributes_only(access_mask, - open_disposition); + open_disposition, + break_to_none); if (attrs_only) { break; } -- cgit From 32061705cffc98753975952f67aaa2a43e3eafb8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 09:40:49 +0100 Subject: opendb_tdb: EXCLUSIVE oplock use the same matching logic metze (This used to be commit 48e703d5a6b8a7b273d0bf15fc6198ef25b0a7c4) --- source4/ntvfs/common/opendb_tdb.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index fe5a0a8864..a51c823a63 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -376,8 +376,26 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, exclusive oplocks afterwards. */ for (i=0;inum_entries;i++) { if (file->entries[i].oplock_level == OPLOCK_EXCLUSIVE) { + bool oplock_return = OPLOCK_BREAK_TO_LEVEL_II; + /* if this is an attribute only access + * it doesn't conflict with an EXCLUSIVE oplock + * but we'll not grant the oplock below + */ + attrs_only = access_attributes_only(access_mask, + open_disposition, + break_to_none); + if (attrs_only) { + break; + } + /* + * send an oplock break to the holder of the + * oplock and tell caller to retry later + */ + if (break_to_none) { + oplock_return = OPLOCK_BREAK_TO_NONE; + } odb_oplock_break_send(odb, &file->entries[i], - OPLOCK_BREAK_TO_NONE); + oplock_return); return NT_STATUS_OPLOCK_NOT_GRANTED; } } @@ -449,8 +467,8 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, e.oplock_level = OPLOCK_EXCLUSIVE; *oplock_granted = EXCLUSIVE_OPLOCK_RETURN; } else { - e.oplock_level = OPLOCK_NONE; - *oplock_granted = NO_OPLOCK_RETURN; + e.oplock_level = OPLOCK_LEVEL_II; + *oplock_granted = LEVEL_II_OPLOCK_RETURN; } } else if (oplock_level == OPLOCK_BATCH) { if (file.num_entries == 0) { -- cgit From eefaf470bfad4a4233990de6ba44cd4db233ab17 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 11:24:37 +0100 Subject: pvfs_rename: add retry logic after sharing violation or non granted oplock metze (This used to be commit 79e42a5dfbfd59b856bca16456295cd2c93ab0ca) --- source4/ntvfs/posix/pvfs_rename.c | 105 +++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 5693e79314..e3192370cc 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -180,6 +180,84 @@ static const char *pvfs_resolve_wildcard(TALLOC_CTX *mem_ctx, return talloc_asprintf(mem_ctx, "%s.%s", base1, ext1); } +/* + retry an rename after a sharing violation +*/ +static void pvfs_retry_rename(struct pvfs_odb_retry *r, + struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *_io, + void *private_data, + enum pvfs_wait_notice reason) +{ + union smb_rename *io = talloc_get_type(_io, union smb_rename); + NTSTATUS status = NT_STATUS_INTERNAL_ERROR; + + talloc_free(r); + + switch (reason) { + case PVFS_WAIT_CANCEL: +/*TODO*/ + status = NT_STATUS_CANCELLED; + break; + case PVFS_WAIT_TIMEOUT: + /* if it timed out, then give the failure + immediately */ +/*TODO*/ + status = NT_STATUS_SHARING_VIOLATION; + break; + case PVFS_WAIT_EVENT: + + /* try the open again, which could trigger another retry setup + if it wants to, so we have to unmark the async flag so we + will know if it does a second async reply */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_ASYNC; + + status = pvfs_rename(ntvfs, req, io); + if (req->async_states->state & NTVFS_ASYNC_STATE_ASYNC) { + /* the 2nd try also replied async, so we don't send + the reply yet */ + return; + } + + /* re-mark it async, just in case someone up the chain does + paranoid checking */ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; + break; + } + + /* send the reply up the chain */ + req->async_states->status = status; + req->async_states->send_fn(req); +} + +/* + setup for a rename retry after a sharing violation + or a non granted oplock +*/ +static NTSTATUS pvfs_rename_setup_retry(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_rename *io, + struct odb_lock *lck, + NTSTATUS status) +{ + struct pvfs_state *pvfs = ntvfs->private_data; + struct timeval end_time; + + if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) { + end_time = timeval_add(&req->statistics.request_time, + 0, pvfs->sharing_violation_delay); + } else if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) { + end_time = timeval_add(&req->statistics.request_time, + pvfs->oplock_break_timeout, 0); + } else { + return NT_STATUS_INTERNAL_ERROR; + } + + return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL, + pvfs_retry_rename); +} + /* rename one file from a wildcard set */ @@ -354,8 +432,19 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, } status = pvfs_can_rename(pvfs, req, name1, &lck); + /* + * on a sharing violation we need to retry when the file is closed by + * the other user, or after 1 second + * on a non granted oplock we need to retry when the file is closed by + * the other user, or after 30 seconds + */ + if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_rename_setup_retry(pvfs->ntvfs, req, ren, lck, status); + } + if (!NT_STATUS_IS_OK(status)) { - talloc_free(lck); return status; } @@ -377,6 +466,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct pvfs_filename *name1, *name2; + struct odb_lock *lck = NULL; switch (ren->ntrename.in.flags) { case RENAME_FLAG_RENAME: @@ -422,7 +512,18 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_can_rename(pvfs, req, name1, NULL); + status = pvfs_can_rename(pvfs, req, name1, &lck); + /* + * on a sharing violation we need to retry when the file is closed by + * the other user, or after 1 second + * on a non granted oplock we need to retry when the file is closed by + * the other user, or after 30 seconds + */ + if ((NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) || + NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_rename_setup_retry(pvfs->ntvfs, req, ren, lck, status); + } if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 8efcd871ce7195886430399c221ab0d8e641cccb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 11:25:33 +0100 Subject: pvfs_rename: we need a do a odb_rename() after pvfs_do_rename() metze (This used to be commit f4f593a1acd4a39f7be639465f0be4b3a97a9bfc) --- source4/ntvfs/posix/pvfs_rename.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index e3192370cc..3c60c00247 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -533,6 +533,9 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); NT_STATUS_NOT_OK_RETURN(status); status = pvfs_do_rename(pvfs, name1, name2->full_name); + if (NT_STATUS_IS_OK(status)) { + status = odb_rename(lck, name2->full_name); + } NT_STATUS_NOT_OK_RETURN(status); break; -- cgit From 85d58175c8d046a01da62c0107e29537862ed8a4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 21:50:51 +0100 Subject: opendb: return the path that should be deleted in odb_close_file() That means the last close returns the path name if the delete_on_close flag is set. metze (This used to be commit fc27730bad24e8dddaa2e7f754a16811e38a2f60) --- source4/ntvfs/common/opendb.c | 5 +++-- source4/ntvfs/common/opendb.h | 3 ++- source4/ntvfs/common/opendb_tdb.c | 15 +++++++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 36144d0406..0b11f9dac5 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -118,9 +118,10 @@ _PUBLIC_ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) /* remove a opendb entry */ -_PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle) +_PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle, + const char **delete_path) { - return ops->odb_close_file(lck, file_handle); + return ops->odb_close_file(lck, file_handle, delete_path); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 9591bcf6b9..c736c25a8d 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -32,7 +32,8 @@ struct opendb_ops { uint32_t open_disposition, bool break_to_none, uint32_t oplock_level, uint32_t *oplock_granted); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); - NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle); + NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle, + const char **delete_path); NTSTATUS (*odb_remove_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path); NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index a51c823a63..f0269db527 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -527,10 +527,12 @@ static NTSTATUS odb_tdb_open_file_pending(struct odb_lock *lck, void *private) /* remove a opendb entry */ -static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle) +static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle, + const char **_delete_path) { struct odb_context *odb = lck->odb; struct opendb_file file; + const char *delete_path = NULL; int i; NTSTATUS status; @@ -566,7 +568,16 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle) file.num_pending = 0; file.num_entries--; - + + if (file.num_entries == 0 && file.delete_on_close) { + delete_path = talloc_strdup(lck, file.path); + NT_STATUS_HAVE_NO_MEMORY(delete_path); + } + + if (_delete_path) { + *_delete_path = delete_path; + } + return odb_push_record(lck, &file); } -- cgit From 03660b240c74eedc7d767acac08cc2504c60515e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 21:52:52 +0100 Subject: pvfs_open: use the delete_path of odb_close_file() metze (This used to be commit c78451ce0618de92321430d2b50f9a8172d283f4) --- source4/ntvfs/posix/pvfs_open.c | 84 +++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 49 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a01352f60c..6f2f587212 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -50,29 +50,10 @@ struct pvfs_file *pvfs_find_fd(struct pvfs_state *pvfs, */ static int pvfs_dir_handle_destructor(struct pvfs_file_handle *h) { - int open_count; - char *path = NULL; - - if (h->name->stream_name == NULL && - pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && - open_count == 1) { - NTSTATUS status; - status = pvfs_xattr_unlink_hook(h->pvfs, path); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", - path, nt_errstr(status))); - } - if (rmdir(path) != 0) { - DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n", - path, strerror(errno))); - } - } - - talloc_free(path); - if (h->have_opendb_entry) { struct odb_lock *lck; NTSTATUS status; + const char *delete_path = NULL; lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); if (lck == NULL) { @@ -80,12 +61,24 @@ static int pvfs_dir_handle_destructor(struct pvfs_file_handle *h) return 0; } - status = odb_close_file(lck, h); + status = odb_close_file(lck, h, &delete_path); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", + DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", h->name->full_name, nt_errstr(status))); } + if (h->name->stream_name == NULL && delete_path) { + status = pvfs_xattr_unlink_hook(h->pvfs, delete_path); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", + delete_path, nt_errstr(status))); + } + if (rmdir(delete_path) != 0) { + DEBUG(0,("pvfs_dir_handle_destructor: failed to rmdir '%s' - %s\n", + delete_path, strerror(errno))); + } + } + talloc_free(lck); } @@ -410,9 +403,6 @@ cleanup_delete: */ static int pvfs_handle_destructor(struct pvfs_file_handle *h) { - int open_count; - char *path = NULL; - /* the write time is no longer sticky */ if (h->sticky_write_time) { NTSTATUS status; @@ -441,32 +431,10 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) h->fd = -1; } - if (h->name->stream_name == NULL && - h->open_completed && - pvfs_delete_on_close_set(h->pvfs, h, &open_count, &path) && - open_count == 1) { - NTSTATUS status; - status = pvfs_xattr_unlink_hook(h->pvfs, path); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", - path, nt_errstr(status))); - } - if (unlink(path) != 0) { - DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", - path, strerror(errno))); - } else { - notify_trigger(h->pvfs->notify_context, - NOTIFY_ACTION_REMOVED, - FILE_NOTIFY_CHANGE_FILE_NAME, - path); - } - } - - talloc_free(path); - if (h->have_opendb_entry) { struct odb_lock *lck; NTSTATUS status; + const char *delete_path = NULL; lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); if (lck == NULL) { @@ -474,12 +442,30 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) return 0; } - status = odb_close_file(lck, h); + status = odb_close_file(lck, h, &delete_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", h->name->full_name, nt_errstr(status))); } + if (h->name->stream_name == NULL && + h->open_completed && delete_path) { + status = pvfs_xattr_unlink_hook(h->pvfs, delete_path); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Warning: xattr unlink hook failed for '%s' - %s\n", + delete_path, nt_errstr(status))); + } + if (unlink(delete_path) != 0) { + DEBUG(0,("pvfs_close: failed to delete '%s' - %s\n", + delete_path, strerror(errno))); + } else { + notify_trigger(h->pvfs->notify_context, + NOTIFY_ACTION_REMOVED, + FILE_NOTIFY_CHANGE_FILE_NAME, + delete_path); + } + } + talloc_free(lck); } -- cgit From 9028ecca22713d4069e6f610b546fd8d60756b81 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 22:22:10 +0100 Subject: pvfs: remove unused args from pvfs_delete_on_close_set() metze (This used to be commit 73f12be7c6a648d4d5336328a340510ac7b1d6de) --- source4/ntvfs/posix/pvfs_open.c | 3 +-- source4/ntvfs/posix/pvfs_qfileinfo.c | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 6f2f587212..3c2fa73df8 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1724,8 +1724,7 @@ NTSTATUS pvfs_can_stat(struct pvfs_state *pvfs, /* determine if delete on close is set on */ -bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h, - int *open_count, char **path) +bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle *h) { NTSTATUS status; bool del_on_close; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 8d23d707a4..6ed729541f 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -380,7 +380,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, switch (info->generic.level) { case RAW_FILEINFO_STANDARD_INFO: case RAW_FILEINFO_STANDARD_INFORMATION: - if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { + if (pvfs_delete_on_close_set(pvfs, h)) { info->standard_info.out.delete_pending = 1; info->standard_info.out.nlink--; } @@ -388,7 +388,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, case RAW_FILEINFO_ALL_INFO: case RAW_FILEINFO_ALL_INFORMATION: - if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { + if (pvfs_delete_on_close_set(pvfs, h)) { info->all_info.out.delete_pending = 1; info->all_info.out.nlink--; } @@ -407,7 +407,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, break; case RAW_FILEINFO_SMB2_ALL_INFORMATION: - if (pvfs_delete_on_close_set(pvfs, h, NULL, NULL)) { + if (pvfs_delete_on_close_set(pvfs, h)) { info->all_info2.out.delete_pending = 1; info->all_info2.out.nlink--; } -- cgit From bc1b595555bd667755291184aa380b011ed51795 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 22:16:55 +0100 Subject: opendb: only return delete_on_close on odb_get_delete_on_close() metze (This used to be commit e699633db2d377a9077ff490208da277e250239b) --- source4/ntvfs/common/opendb.c | 5 ++--- source4/ntvfs/common/opendb.h | 3 +-- source4/ntvfs/common/opendb_tdb.c | 16 +++------------- 3 files changed, 6 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 0b11f9dac5..d8cb67686b 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -155,10 +155,9 @@ _PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_clos people still have the file open */ _PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, - DATA_BLOB *key, bool *del_on_close, - int *open_count, char **path) + DATA_BLOB *key, bool *del_on_close) { - return ops->odb_get_delete_on_close(odb, key, del_on_close, open_count, path); + return ops->odb_get_delete_on_close(odb, key, del_on_close); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index c736c25a8d..33f2e1c88d 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -38,8 +38,7 @@ struct opendb_ops { NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path); NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close); NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, - DATA_BLOB *key, bool *del_on_close, - int *open_count, char **path); + DATA_BLOB *key, bool *del_on_close); NTSTATUS (*odb_can_open)(struct odb_lock *lck, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index f0269db527..37c1c0850b 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -734,20 +734,20 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl people still have the file open */ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, - DATA_BLOB *key, bool *del_on_close, - int *open_count, char **path) + DATA_BLOB *key, bool *del_on_close) { NTSTATUS status; struct opendb_file file; struct odb_lock *lck; + (*del_on_close) = false; + lck = odb_lock(odb, odb, key); NT_STATUS_HAVE_NO_MEMORY(lck); status = odb_pull_record(lck, &file); if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { talloc_free(lck); - (*del_on_close) = false; return NT_STATUS_OK; } if (!NT_STATUS_IS_OK(status)) { @@ -756,16 +756,6 @@ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, } (*del_on_close) = file.delete_on_close; - if (open_count != NULL) { - (*open_count) = file.num_entries; - } - if (path != NULL) { - *path = talloc_strdup(odb, file.path); - NT_STATUS_HAVE_NO_MEMORY(*path); - if (file.num_entries == 1 && file.entries[0].delete_on_close) { - (*del_on_close) = true; - } - } talloc_free(lck); -- cgit From c3ce0a0b95b6051a356c72424c2d62b77a0e81df Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 27 Feb 2008 22:22:56 +0100 Subject: pvfs_open: fix callers of odb_get_delete_on_close() metze (This used to be commit 608e5cd881d64b8db9146dfc4b3a1778a93a0f8e) --- source4/ntvfs/posix/pvfs_open.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 3c2fa73df8..740a0a9d13 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -560,7 +560,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, status = pvfs_locking_key(parent, req, &locking_key); NT_STATUS_NOT_OK_RETURN(status); status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, - &del_on_close, NULL, NULL); + &del_on_close); NT_STATUS_NOT_OK_RETURN(status); if (del_on_close) { return NT_STATUS_DELETE_PENDING; @@ -1730,7 +1730,7 @@ bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle * bool del_on_close; status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, - &del_on_close, open_count, path); + &del_on_close); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("WARNING: unable to determine delete on close status for open file\n")); return false; -- cgit From 1ada7108408f567f61cfbf2b625730ba898452db Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 29 Feb 2008 14:23:38 +0100 Subject: Move public header accumulation out of the perl code. Never install generated prototype files. It's easier to break the API when using them and they're not easily readable for 3rd party users. Conflicts: source/auth/config.mk source/auth/credentials/config.mk source/auth/gensec/config.mk source/build/smb_build/config_mk.pm source/build/smb_build/main.pl source/build/smb_build/makefile.pm source/dsdb/config.mk source/lib/charset/config.mk source/lib/tdr/config.mk source/lib/util/config.mk source/libcli/config.mk source/libcli/ldap/config.mk source/librpc/config.mk source/param/config.mk source/rpc_server/config.mk source/torture/config.mk (This used to be commit 6c659689ed4081f1d7a6253c538c7f01784197ba) --- source4/ntvfs/config.mk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index dbc1a4c277..0f8e88eaa6 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -80,13 +80,14 @@ OBJ_FILES = \ ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] -PUBLIC_HEADERS = ntvfs.h PRIVATE_PROTO_HEADER = ntvfs_proto.h OBJ_FILES = \ ntvfs_base.o \ ntvfs_generic.o \ ntvfs_interface.o \ ntvfs_util.o + +PUBLIC_HEADERS += ntvfs/ntvfs.h # # End SUBSYSTEM NTVFS ################################################ -- cgit From 48270181bac1a640d085ce5f5a58329d69c7a1ac Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Feb 2008 12:18:29 +0100 Subject: pvfs_open: make pvfs_locking_key() non static metze (This used to be commit 587373b97b95a8e562c3a5a59a62abade4dfed2f) --- source4/ntvfs/posix/pvfs_open.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 740a0a9d13..adf4c1ac18 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -144,8 +144,8 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs, form the lock context used for opendb locking. Note that we must zero here to take account of possible padding on some architectures */ -static NTSTATUS pvfs_locking_key(struct pvfs_filename *name, - TALLOC_CTX *mem_ctx, DATA_BLOB *key) +NTSTATUS pvfs_locking_key(struct pvfs_filename *name, + TALLOC_CTX *mem_ctx, DATA_BLOB *key) { struct { dev_t device; -- cgit From 98dafd5eb1948bbe8a0d78814ab1cd1910477733 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Feb 2008 09:06:49 +0100 Subject: opendb: add odb_get_path() metze (This used to be commit 02071f151a22257d31f8a8b254625e2067e7b94d) --- source4/ntvfs/common/opendb.c | 8 ++++++++ source4/ntvfs/common/opendb.h | 1 + source4/ntvfs/common/opendb_tdb.c | 20 ++++++++++++++++++++ 3 files changed, 29 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index d8cb67686b..6c1a9c070a 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -142,6 +142,14 @@ _PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) return ops->odb_rename(lck, path); } +/* + get back the path of an open file +*/ +_PUBLIC_ NTSTATUS odb_get_path(struct odb_lock *lck, const char **path) +{ + return ops->odb_get_path(lck, path); +} + /* update delete on close flag on an open file */ diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 33f2e1c88d..69a7f718ba 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -36,6 +36,7 @@ struct opendb_ops { const char **delete_path); NTSTATUS (*odb_remove_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path); + NTSTATUS (*odb_get_path)(struct odb_lock *lck, const char **path); NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close); NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, DATA_BLOB *key, bool *del_on_close); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 37c1c0850b..47b35f594c 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -713,6 +713,25 @@ static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path) return odb_push_record(lck, &file); } +/* + get the path of an open file +*/ +static NTSTATUS odb_tdb_get_path(struct odb_lock *lck, const char **path) +{ + struct opendb_file file; + NTSTATUS status; + + *path = NULL; + + status = odb_pull_record(lck, &file); + /* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */ + NT_STATUS_NOT_OK_RETURN(status); + + *path = file.path; + + return NT_STATUS_OK; +} + /* update delete on close flag on an open file */ @@ -802,6 +821,7 @@ static const struct opendb_ops opendb_tdb_ops = { .odb_close_file = odb_tdb_close_file, .odb_remove_pending = odb_tdb_remove_pending, .odb_rename = odb_tdb_rename, + .odb_get_path = odb_tdb_get_path, .odb_set_delete_on_close = odb_tdb_set_delete_on_close, .odb_get_delete_on_close = odb_tdb_get_delete_on_close, .odb_can_open = odb_tdb_can_open, -- cgit From c5d961586e72b181b24fcbaf98c8da2fa27aa2d1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 29 Feb 2008 13:04:08 +0100 Subject: pvfs_resolve: fix endless loop with trailing ".." We also need to move the NULL termination. metze (This used to be commit 4fc41065a31cc8bd477ff5bf2d89f9f595002227) --- source4/ntvfs/posix/pvfs_resolve.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 2bfc47beff..c129038572 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -399,7 +399,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, if (ISDOTDOT(components[i])) { if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; memmove(&components[i-1], &components[i+1], - sizeof(char *)*(num_components-(i+1))); + sizeof(char *)*(num_components-i)); i -= 2; continue; } -- cgit From 5734a10c89b3ca90ee9463320a9be268fed38e8f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 29 Feb 2008 09:08:57 +0100 Subject: pvfs_resolve: "\\" and a trailing "\" need to be reduced metze (This used to be commit 356338b99a67bfaf09618f5ed7c8f5c4ff69fa06) --- source4/ntvfs/posix/pvfs_resolve.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index c129038572..37b182733c 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -265,8 +265,15 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name, of a name */ return NT_STATUS_ILLEGAL_CHARACTER; } - if (p > p_start && p[1] == 0) { - *p = 0; + if (p > p_start && (p[1] == '\\' || p[1] == '\0')) { + /* see if it is definately a "\\" or + * a trailing "\". If it is then fail here, + * and let the next layer up try again after + * pvfs_reduce_name() if it wants to. This is + * much more efficient on average than always + * scanning for these separately + */ + return NT_STATUS_OBJECT_PATH_SYNTAX_BAD; } else { *p = '/'; } -- cgit From f9b2d29d32197095c993d57e00ffbc09ab27184c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Feb 2008 12:14:17 +0100 Subject: pvfs_resolve: add pvfs_resolve_name_handle() metze (This used to be commit 714717253c035b31fc850df8456f8cf2b38bcb72) --- source4/ntvfs/posix/pvfs_resolve.c | 80 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 37b182733c..325bc74f8f 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -623,6 +623,86 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, return pvfs_fill_dos_info(pvfs, name, fd); } +/* + fill in the pvfs_filename info for an open file, given the current + info for a (possibly) non-open file. This is used by places that need + to update the pvfs_filename stat information, and the path + after a possible rename on a different handle. +*/ +NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs, + struct pvfs_file_handle *h) +{ + NTSTATUS status; + + if (h->have_opendb_entry) { + struct odb_lock *lck; + const char *name = NULL; + + lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("%s: failed to lock file '%s' in opendb\n", + __FUNCTION__, h->name->full_name)); + /* we were supposed to do a blocking lock, so something + is badly wrong! */ + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + status = odb_get_path(lck, &name); + if (NT_STATUS_IS_OK(status)) { + /* + * This relies an the fact that + * renames of open files are only + * allowed by setpathinfo() and setfileinfo() + * and there're only renames within the same + * directory supported + */ + if (strcmp(h->name->full_name, name) != 0) { + const char *orig_dir; + const char *new_file; + const char *new_orig; + char *delim; + + delim = strrchr(name, '/'); + if (!delim) { + talloc_free(lck); + return NT_STATUS_INTERNAL_ERROR; + } + + new_file = delim + 1; + delim = strrchr(h->name->original_name, '\\'); + if (delim) { + delim[0] = '\0'; + orig_dir = h->name->original_name; + new_orig = talloc_asprintf(h->name, "%s\\%s", + orig_dir, new_file); + if (!new_orig) { + talloc_free(lck); + return NT_STATUS_NO_MEMORY; + } + } else { + new_orig = talloc_strdup(h->name, new_file); + if (!new_orig) { + talloc_free(lck); + return NT_STATUS_NO_MEMORY; + } + } + + talloc_free(h->name->original_name); + talloc_free(h->name->full_name); + h->name->full_name = talloc_steal(h->name, name); + h->name->original_name = new_orig; + } + } + + talloc_free(lck); + } + + status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + NT_STATUS_NOT_OK_RETURN(status); + + return NT_STATUS_OK; +} + /* resolve the parent of a given name -- cgit From daa4dec695b53e0c7ea442b6ca0b012f128ed759 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Feb 2008 12:17:59 +0100 Subject: pvfs: use pvfs_resolve_name_handle() in qfileinfo and setfileinfo metze (This used to be commit 4b1a266f6fb04c8f923c48ea215ece6b45a18ea7) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 2 +- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 6ed729541f..6bc21e5e3e 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -368,7 +368,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs, } /* update the file information */ - status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + status = pvfs_resolve_name_handle(pvfs, h); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index da1e31e639..fcadbfd852 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -289,7 +289,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } /* update the file information */ - status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + status = pvfs_resolve_name_handle(pvfs, h); if (!NT_STATUS_IS_OK(status)) { return status; } -- cgit From 176e20bf2662838cbc28d42c342a4d442f6bc308 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 28 Feb 2008 12:19:18 +0100 Subject: pvfs_setfileinfo: tell the opendb about renames metze (This used to be commit 9360eda2c5606b2c73edb768af8ca0e8ba310e30) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index fcadbfd852..18647c95c5 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -82,11 +82,13 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info) static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, struct ntvfs_request *req, struct pvfs_filename *name, + DATA_BLOB *odb_locking_key, union smb_setfileinfo *info) { NTSTATUS status; struct pvfs_filename *name2; char *new_name, *p; + struct odb_lock *lck = NULL; /* renames are only allowed within a directory */ if (strchr_m(info->rename_information.in.new_name, '\\') && @@ -168,7 +170,18 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return status; } + lck = odb_lock(req, pvfs->odb_context, odb_locking_key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for can_stat\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + status = pvfs_do_rename(pvfs, name, name2->full_name); + if (NT_STATUS_IS_OK(status)) { + status = odb_rename(lck, name2->full_name); + } + talloc_free(lck); + NT_STATUS_NOT_OK_RETURN(status); if (NT_STATUS_IS_OK(status)) { name->full_name = talloc_steal(name, name2->full_name); name->original_name = talloc_steal(name, name2->original_name); @@ -391,7 +404,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_RENAME_INFORMATION: case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: - return pvfs_setfileinfo_rename(pvfs, req, h->name, + return pvfs_setfileinfo_rename(pvfs, req, h->name, + &h->odb_locking_key, info); case RAW_SFILEINFO_SEC_DESC: @@ -565,6 +579,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, uint32_t access_needed; uint32_t change_mask = 0; struct odb_lock *lck = NULL; + DATA_BLOB odb_locking_key; /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path, @@ -696,8 +711,12 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, case RAW_SFILEINFO_RENAME_INFORMATION: case RAW_SFILEINFO_RENAME_INFORMATION_SMB2: - return pvfs_setfileinfo_rename(pvfs, req, name, - info); + status = pvfs_locking_key(name, name, &odb_locking_key); + NT_STATUS_NOT_OK_RETURN(status); + status = pvfs_setfileinfo_rename(pvfs, req, name, + &odb_locking_key, info); + NT_STATUS_NOT_OK_RETURN(status); + return NT_STATUS_OK; case RAW_SFILEINFO_DISPOSITION_INFO: case RAW_SFILEINFO_DISPOSITION_INFORMATION: -- cgit From a0235410aee5edab4a2a1af432bd73b5a1980d2d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 29 Feb 2008 09:10:12 +0100 Subject: pvfs_setfileinfo: support renaming of directories metze (This used to be commit 2ecc7ec8b392cf3ec698d168bf6fb7898e1978f1) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 18647c95c5..5ac9cedc48 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -96,11 +96,6 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_NOT_SUPPORTED; } - if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { - /* don't allow this for now */ - return NT_STATUS_FILE_IS_A_DIRECTORY; - } - /* don't allow stream renames for now */ if (name->stream_name) { return NT_STATUS_INVALID_PARAMETER; -- cgit From 0de1a63c18a83fd97938816fe869c42cbe92aac9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 1 Mar 2008 10:05:25 +0100 Subject: pvfs_rename: move odb_rename() onto pvfs_do_rename() metze (This used to be commit 5a1f0c0ce995064c23e9f726bceddbd8442c4293) --- source4/ntvfs/posix/pvfs_rename.c | 25 ++++++++++++------------- source4/ntvfs/posix/pvfs_setfileinfo.c | 5 +---- 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 185e35f800..29b2d03005 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -28,16 +28,22 @@ /* do a file rename, and send any notify triggers */ -NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *name1, +NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, + struct odb_lock *lck, + const struct pvfs_filename *name1, const char *name2) { const char *r1, *r2; uint32_t mask; + NTSTATUS status; if (rename(name1->full_name, name2) == -1) { return pvfs_map_errno(pvfs, errno); } + status = odb_rename(lck, name2); + NT_STATUS_NOT_OK_RETURN(status); + if (name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { mask = FILE_NOTIFY_CHANGE_DIR_NAME; } else { @@ -315,11 +321,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - status = pvfs_do_rename(pvfs, name1, fname2); - - if (NT_STATUS_IS_OK(status)) { - status = odb_rename(lck, fname2); - } + status = pvfs_do_rename(pvfs, lck, name1, fname2); failed: talloc_free(mem_ctx); @@ -448,9 +450,9 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs, return status; } - status = pvfs_do_rename(pvfs, name1, name2->full_name); - if (NT_STATUS_IS_OK(status)) { - status = odb_rename(lck, name2->full_name); + status = pvfs_do_rename(pvfs, lck, name1, name2->full_name); + if (!NT_STATUS_IS_OK(status)) { + return status; } return NT_STATUS_OK; @@ -532,10 +534,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, case RENAME_FLAG_RENAME: status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE); NT_STATUS_NOT_OK_RETURN(status); - status = pvfs_do_rename(pvfs, name1, name2->full_name); - if (NT_STATUS_IS_OK(status)) { - status = odb_rename(lck, name2->full_name); - } + status = pvfs_do_rename(pvfs, lck, name1, name2->full_name); NT_STATUS_NOT_OK_RETURN(status); break; diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 5ac9cedc48..ad47fe90c9 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -171,10 +171,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } - status = pvfs_do_rename(pvfs, name, name2->full_name); - if (NT_STATUS_IS_OK(status)) { - status = odb_rename(lck, name2->full_name); - } + status = pvfs_do_rename(pvfs, lck, name, name2->full_name); talloc_free(lck); NT_STATUS_NOT_OK_RETURN(status); if (NT_STATUS_IS_OK(status)) { -- cgit From b29d47edcf2767d7f9e9f63332079c6e8e89946c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 3 Mar 2008 18:25:28 +0100 Subject: Move object file lists to the Makefile. (This used to be commit a7e6d2a1832db388fdafa1279f84c9a8bbfc87d6) --- source4/ntvfs/common/config.mk | 10 +++------- source4/ntvfs/config.mk | 34 +++++++++++++--------------------- source4/ntvfs/posix/config.mk | 25 ++++++++++++++----------- source4/ntvfs/sysdep/config.mk | 9 ++++----- source4/ntvfs/unixuid/config.mk | 4 ++-- 5 files changed, 36 insertions(+), 46 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 2fc0942ed4..99a8a7af45 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -2,14 +2,10 @@ # Start LIBRARY ntvfs_common [SUBSYSTEM::ntvfs_common] PRIVATE_PROTO_HEADER = proto.h -OBJ_FILES = \ - init.o \ - brlock.o \ - brlock_tdb.o \ - opendb.o \ - opendb_tdb.o \ - notify.o PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ + +NTVFS_COMMON_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) + diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 0f8e88eaa6..436fe11522 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -9,25 +9,24 @@ mkinclude sysdep/config.mk [MODULE::ntvfs_cifs] INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - cifs/vfs_cifs.o PRIVATE_DEPENDENCIES = \ LIBCLI_SMB LIBCLI_RAW # End MODULE ntvfs_cifs ################################################ +ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o + ################################################ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = simple/proto.h -OBJ_FILES = \ - simple/vfs_simple.o \ - simple/svfs_util.o # End MODULE ntvfs_simple ################################################ +ntvfs_simple_OBJ_FILES = $(addprefix ntvfs/simple/, vfs_simple.o svfs_util.o) + ################################################ # Start MODULE ntvfs_cifsposix [MODULE::ntvfs_cifsposix] @@ -35,57 +34,50 @@ OBJ_FILES = \ INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h -OBJ_FILES = \ - cifs_posix_cli/vfs_cifs_posix.o \ - cifs_posix_cli/svfs_util.o # End MODULE ntvfs_cifsposix ################################################ +ntvfs_cifsposix_OBJ_FILES = \ + $(addprefix ntvfs/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) + ################################################ # Start MODULE ntvfs_print [MODULE::ntvfs_print] INIT_FUNCTION = ntvfs_print_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - print/vfs_print.o # End MODULE ntvfs_print ################################################ +ntvfs_print_OBJ_FILES = ntvfs/print/vfs_print.o + ################################################ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_ipc_init PRIVATE_PROTO_HEADER = ipc/proto.h -OBJ_FILES = \ - ipc/vfs_ipc.o \ - ipc/ipc_rap.o \ - ipc/rap_server.o PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ +ntvfs_ipc_OBJ_FILES = $(addprefix ntvfs/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_nbench_init -OBJ_FILES = \ - nbench/vfs_nbench.o # End MODULE ntvfs_nbench ################################################ +ntvfs_nbench_OBJ_FILES = ntvfs/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] PRIVATE_PROTO_HEADER = ntvfs_proto.h -OBJ_FILES = \ - ntvfs_base.o \ - ntvfs_generic.o \ - ntvfs_interface.o \ - ntvfs_util.o + +ntvfs_OBJ_FILES = $(addprefix ntvfs/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) PUBLIC_HEADERS += ntvfs/ntvfs.h # diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 88048c2af7..249f1ba3d8 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -3,30 +3,31 @@ [MODULE::pvfs_acl_xattr] INIT_FUNCTION = pvfs_acl_xattr_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_xattr.o PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ +pvfs_acl_xattr_OBJ_FILES = ntvfs/posix/pvfs_acl_xattr.o + ################################################ # Start MODULE pvfs_acl_nfs4 [MODULE::pvfs_acl_nfs4] INIT_FUNCTION = pvfs_acl_nfs4_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_nfs4.o PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ +pvfs_acl_nfs4_OBJ_FILES = ntvfs/posix/pvfs_acl_nfs4.o + ################################################ [MODULE::pvfs_aio] SUBSYSTEM = ntvfs -OBJ_FILES = pvfs_aio.o PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ +pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -34,7 +35,12 @@ SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init PRIVATE_PROTO_HEADER = vfs_posix_proto.h -OBJ_FILES = \ +#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 +PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio +# End MODULE ntvfs_posix +################################################ + +ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ @@ -62,8 +68,5 @@ OBJ_FILES = \ pvfs_acl.o \ pvfs_notify.o \ xattr_system.o \ - xattr_tdb.o -#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 -PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio -# End MODULE ntvfs_posix -################################################ + xattr_tdb.o) + diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index dee198c9da..6cd5d88aca 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -3,16 +3,15 @@ [MODULE::sys_notify_inotify] SUBSYSTEM = sys_notify INIT_FUNCTION = sys_notify_inotify_init -OBJ_FILES = \ - inotify.o # End MODULE sys_notify_inotify ################################################ +sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o + ################################################ # Start SUBSYSTEM sys_notify [SUBSYSTEM::sys_notify] -OBJ_FILES = \ - sys_notify.o -PUBLIC_DEPENDENCIES = # End SUBSYSTEM sys_notify ################################################ + +sys_notify_OBJ_FILES = ntvfs/sysdep/sys_notify.o diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 91976c6811..968e56bde4 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -3,8 +3,8 @@ [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - vfs_unixuid.o PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER # End MODULE ntvfs_unixuid ################################################ + +ntvfs_unixuid_OBJ_FILES = ntvfs/unixuid/vfs_unixuid.o -- cgit From a69acf7cb96bf41bafce303a2cf21c31f1366328 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 4 Mar 2008 01:37:18 +0100 Subject: Deal with subsystems with no settings, several other minor fixes. (This used to be commit 10cf48591e8d6bfb750a6ff187f04ea24a1f8cd7) --- source4/ntvfs/common/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 99a8a7af45..356f6465c3 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,5 +7,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ -NTVFS_COMMON_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) +ntvfs_common_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) -- cgit From af0d863ce78a4afb1e2add837613a665d54031eb Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 4 Mar 2008 14:10:13 +0100 Subject: pvfs_oplock: move pvfs_oplock_release() parts into a helper function metze (This used to be commit 2b8934e4ab2dd9673928a6c9a291aedac1ebaa95) --- source4/ntvfs/posix/pvfs_oplock.c | 99 ++++++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 43 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c index cf30ddbc59..b830ad2adc 100644 --- a/source4/ntvfs/posix/pvfs_oplock.c +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -32,6 +32,58 @@ struct pvfs_oplock { struct messaging_context *msg_ctx; }; +static NTSTATUS pvfs_oplock_release_internal(struct pvfs_file_handle *h, + uint8_t oplock_break) +{ + struct odb_lock *olck; + NTSTATUS status; + + if (h->fd == -1) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + + if (!h->have_opendb_entry) { + return NT_STATUS_FOOBAR; + } + + if (!h->oplock) { + return NT_STATUS_FOOBAR; + } + + olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); + if (olck == NULL) { + DEBUG(0,("Unable to lock opendb for oplock update\n")); + return NT_STATUS_FOOBAR; + } + + if (oplock_break == OPLOCK_BREAK_TO_NONE) { + h->oplock->level = OPLOCK_NONE; + } else if (oplock_break == OPLOCK_BREAK_TO_LEVEL_II) { + h->oplock->level = OPLOCK_LEVEL_II; + } else { + /* fallback to level II in case of a invalid value */ + DEBUG(1,("unexpected oplock break level[0x%02X]\n", oplock_break)); + h->oplock->level = OPLOCK_LEVEL_II; + } + status = odb_update_oplock(olck, h, h->oplock->level); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to update oplock level for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + talloc_free(olck); + return status; + } + + talloc_free(olck); + + /* after a break to none, we no longer have an oplock attached */ + if (h->oplock->level == OPLOCK_NONE) { + talloc_free(h->oplock); + h->oplock = NULL; + } + + return NT_STATUS_OK; +} + /* receive oplock breaks and forward them to the client */ @@ -140,8 +192,6 @@ NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs, { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - struct pvfs_file_handle *h; - struct odb_lock *olck; uint8_t oplock_break; NTSTATUS status; @@ -150,52 +200,15 @@ NTSTATUS pvfs_oplock_release(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } - h = f->handle; - - if (h->fd == -1) { - return NT_STATUS_FILE_IS_A_DIRECTORY; - } - - if (!h->have_opendb_entry) { - return NT_STATUS_FOOBAR; - } - - if (!h->oplock) { - return NT_STATUS_FOOBAR; - } - - olck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); - if (olck == NULL) { - DEBUG(0,("Unable to lock opendb for oplock update\n")); - return NT_STATUS_FOOBAR; - } - oplock_break = (lck->lockx.in.mode >> 8) & 0xFF; - if (oplock_break == OPLOCK_BREAK_TO_NONE) { - h->oplock->level = OPLOCK_NONE; - } else if (oplock_break == OPLOCK_BREAK_TO_LEVEL_II) { - h->oplock->level = OPLOCK_LEVEL_II; - } else { - /* fallback to level II in case of a invalid value */ - DEBUG(1,("unexpected oplock break level[0x%02X]\n", oplock_break)); - h->oplock->level = OPLOCK_LEVEL_II; - } - status = odb_update_oplock(olck, h, h->oplock->level); + + status = pvfs_oplock_release_internal(f->handle, oplock_break); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Unable to update oplock level for '%s' - %s\n", - h->name->full_name, nt_errstr(status))); - talloc_free(olck); + DEBUG(0,("%s: failed to release the oplock[0x%02X]: %s\n", + __FUNCTION__, oplock_break, nt_errstr(status))); return status; } - talloc_free(olck); - - /* after a break to none, we no longer have an oplock attached */ - if (h->oplock->level == OPLOCK_NONE) { - talloc_free(h->oplock); - h->oplock = NULL; - } - return NT_STATUS_OK; } -- cgit From 1f5301c1d2182993d8f8cdaa65763408faff080d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 4 Mar 2008 14:11:53 +0100 Subject: pvfs_oplock: only a break level2 oplocks... It seems that I've tested this in the wrong way before. metze (This used to be commit 21772fa33d772a9df6ff04a0ed1b0d8f4f533295) --- source4/ntvfs/posix/pvfs_oplock.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c index b830ad2adc..3f581e5443 100644 --- a/source4/ntvfs/posix/pvfs_oplock.c +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -218,7 +218,7 @@ NTSTATUS pvfs_break_level2_oplocks(struct pvfs_file *f) struct odb_lock *olck; NTSTATUS status; - if (h->oplock && h->oplock->level == OPLOCK_EXCLUSIVE) { + if (h->oplock && h->oplock->level != OPLOCK_LEVEL_II) { return NT_STATUS_OK; } @@ -228,16 +228,6 @@ NTSTATUS pvfs_break_level2_oplocks(struct pvfs_file *f) return NT_STATUS_FOOBAR; } - if (h->oplock && h->oplock->level == OPLOCK_BATCH) { - status = odb_update_oplock(olck, h, OPLOCK_LEVEL_II); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Unable to update oplock level for '%s' - %s\n", - h->name->full_name, nt_errstr(status))); - talloc_free(olck); - return status; - } - } - status = odb_break_oplocks(olck); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Unable to break level2 oplocks to none for '%s' - %s\n", -- cgit From eb26c896a2523c8d635b5b34c21a0c43e20d10b6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 4 Mar 2008 14:16:17 +0100 Subject: pvfs_oplock: auto release oplocks after a timeout Remember that we sent an oplock break to a client and don't resend. If the filesystem layer tries to send a new break and the client has not released after a former oplock break after the timeout interval, we need to auto release the oplock. metze (This used to be commit bfb0888578677856b2b6b72471f542d0d5d7b838) --- source4/ntvfs/posix/pvfs_oplock.c | 67 +++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c index 3f581e5443..dfa3697af7 100644 --- a/source4/ntvfs/posix/pvfs_oplock.c +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -22,6 +22,7 @@ #include "includes.h" #include "lib/messaging/messaging.h" #include "lib/messaging/irpc.h" +#include "system/time.h" #include "vfs_posix.h" @@ -29,6 +30,8 @@ struct pvfs_oplock { struct pvfs_file_handle *handle; struct pvfs_file *file; uint32_t level; + struct timeval break_to_level_II; + struct timeval break_to_none; struct messaging_context *msg_ctx; }; @@ -93,13 +96,65 @@ static void pvfs_oplock_break(struct pvfs_oplock *opl, uint8_t level) struct pvfs_file *f = opl->file; struct pvfs_file_handle *h = opl->handle; struct pvfs_state *pvfs = h->pvfs; + struct timeval cur = timeval_current(); + struct timeval *last = NULL; + struct timeval end; - DEBUG(10,("pvfs_oplock_break: sending oplock break level %d for '%s' %p\n", - level, h->name->original_name, h)); - status = ntvfs_send_oplock_break(pvfs->ntvfs, f->ntvfs, level); + switch (level) { + case OPLOCK_BREAK_TO_LEVEL_II: + last = &opl->break_to_level_II; + break; + case OPLOCK_BREAK_TO_NONE: + last = &opl->break_to_none; + break; + } + + if (!last) { + DEBUG(0,("%s: got unexpected level[0x%02X]\n", + __FUNCTION__, level)); + return; + } + + if (timeval_is_zero(last)) { + /* + * this is the first break we for this level + * remember the time + */ + *last = cur; + + DEBUG(0,("%s: sending oplock break level %d for '%s' %p\n", + __FUNCTION__, level, h->name->original_name, h)); + status = ntvfs_send_oplock_break(pvfs->ntvfs, f->ntvfs, level); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("%s: sending oplock break failed: %s\n", + __FUNCTION__, nt_errstr(status))); + } + return; + } + + end = timeval_add(last, pvfs->oplock_break_timeout, 0); + + if (timeval_compare(&cur, &end) < 0) { + /* + * If it's not expired just ignore the break + * as we already sent the break request to the client + */ + DEBUG(0,("%s: do not resend oplock break level %d for '%s' %p\n", + __FUNCTION__, level, h->name->original_name, h)); + return; + } + + /* + * If the client did not send a release within the + * oplock break timeout time frame we auto release + * the oplock + */ + DEBUG(0,("%s: auto release oplock level %d for '%s' %p\n", + __FUNCTION__, level, h->name->original_name, h)); + status = pvfs_oplock_release_internal(h, level); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("pvfs_oplock_break: sending oplock break failed: %s\n", - nt_errstr(status))); + DEBUG(0,("%s: failed to auto release the oplock[0x%02X]: %s\n", + __FUNCTION__, level, nt_errstr(status))); } } @@ -165,7 +220,7 @@ NTSTATUS pvfs_setup_oplock(struct pvfs_file *f, uint32_t oplock_granted) return NT_STATUS_OK; } - opl = talloc(f->handle, struct pvfs_oplock); + opl = talloc_zero(f->handle, struct pvfs_oplock); NT_STATUS_HAVE_NO_MEMORY(opl); opl->handle = f->handle; -- cgit From 87f2925252b910f2f403bdbb3f9158202cb7a2c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Mar 2008 15:14:08 +0100 Subject: ntvfs: pass down the client capabilities into the ntvfs layer Note that we don't use any protocol specific values here. For now only NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS is defined others should be defined, when we find out that the ntvfs layer needs to know about it. metze (This used to be commit cc42cd5f6753ca582677fa6f403f0419eec5ab10) --- source4/ntvfs/ntvfs.h | 16 ++++++++++++++++ source4/ntvfs/ntvfs_base.c | 2 ++ source4/ntvfs/ntvfs_util.c | 1 + 3 files changed, 19 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index a708dbff51..7a2edc7e2c 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -181,6 +181,14 @@ struct ntvfs_context { enum protocol_types protocol; + /* + * client capabilities + * this field doesn't use protocol specific + * values! + */ +#define NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS 0x0000000000000001LLU + uint64_t client_caps; + /* * linked list of module contexts */ @@ -257,6 +265,14 @@ struct ntvfs_request { /* the smb pid is needed for locking contexts */ uint16_t smbpid; + /* + * client capabilities + * this field doesn't use protocol specific + * values! + * see NTVFS_CLIENT_CAP_* + */ + uint64_t client_caps; + /* some statictics for the management tools */ struct { /* the system time when the request arrived */ diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index f5a24f23a0..35becabcf9 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -153,6 +153,7 @@ _PUBLIC_ bool ntvfs_interface_differs(const struct ntvfs_critical_sizes *const i */ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, enum ntvfs_type type, enum protocol_types protocol, + uint64_t ntvfs_client_caps, struct event_context *ev, struct messaging_context *msg, struct loadparm_context *lp_ctx, struct server_id server_id, struct ntvfs_context **_ctx) @@ -168,6 +169,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e ctx = talloc_zero(mem_ctx, struct ntvfs_context); NT_STATUS_HAVE_NO_MEMORY(ctx); ctx->protocol = protocol; + ctx->client_caps = ntvfs_client_caps; ctx->type = type; ctx->config = talloc_steal(ctx, scfg); ctx->event_ctx = ev; diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index 7432ac2c13..ebe8008edd 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -42,6 +42,7 @@ _PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, T req->async_states = NULL; req->session_info = session_info; req->smbpid = smbpid; + req->client_caps = ctx->client_caps; req->statistics.request_time = request_time; async = talloc(req, struct ntvfs_async_state); -- cgit From 0339ae5ad82c248b43afa9431b13cda536b18fd6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Mar 2008 15:34:37 +0100 Subject: pvfs_open: fix crash/leak in case pvfs_setup_oplock() fails metze (This used to be commit 5563238782e825f64a22b5f9e0a7deb687f50b19) --- source4/ntvfs/posix/pvfs_open.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index adf4c1ac18..792e35cd14 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -696,21 +696,20 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, DLIST_ADD(pvfs->files.list, f); + /* setup a destructor to avoid file descriptor leaks on + abnormal termination */ + talloc_set_destructor(f, pvfs_fnum_destructor); + talloc_set_destructor(f->handle, pvfs_handle_destructor); + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { oplock_granted = OPLOCK_BATCH; } else if (oplock_granted != OPLOCK_NONE) { status = pvfs_setup_oplock(f, oplock_granted); if (!NT_STATUS_IS_OK(status)) { - talloc_free(lck); return status; } } - /* setup a destructor to avoid file descriptor leaks on - abnormal termination */ - talloc_set_destructor(f, pvfs_fnum_destructor); - talloc_set_destructor(f->handle, pvfs_handle_destructor); - io->generic.out.oplock_level = oplock_granted; io->generic.out.file.ntvfs = f->ntvfs; io->generic.out.create_action = NTCREATEX_ACTION_CREATED; -- cgit From b7db5f7cb57eca4bf28fd8238e5f958a6038158e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Mar 2008 15:47:27 +0100 Subject: opendb: add allow_level_II_oplock parameter to odb_open_file() Not all clients support a fallback to level II oplocks. metze (This used to be commit 146f1fe0b67ca0805f0e71358abc57da0c0579a9) --- source4/ntvfs/common/opendb.c | 4 +++- source4/ntvfs/common/opendb.h | 1 + source4/ntvfs/common/opendb_tdb.c | 32 +++++++++++++++++++++----------- 3 files changed, 25 insertions(+), 12 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 6c1a9c070a..a7e5458aaf 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -98,11 +98,13 @@ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, uint32_t open_disposition, bool break_to_none, + bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { return ops->odb_open_file(lck, file_handle, path, stream_id, share_access, access_mask, delete_on_close, open_disposition, - break_to_none, oplock_level, oplock_granted); + break_to_none, allow_level_II_oplock, + oplock_level, oplock_granted); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 69a7f718ba..1c7f815dea 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -30,6 +30,7 @@ struct opendb_ops { uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, uint32_t open_disposition, bool break_to_none, + bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 47b35f594c..0736af3d1e 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -344,7 +344,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, break request and suspending this call until the break is acknowledged or the file is closed */ - if (break_to_none) { + if (break_to_none || + !file->entries[i].allow_level_II_oplock) { oplock_return = OPLOCK_BREAK_TO_NONE; } odb_oplock_break_send(odb, &file->entries[i], @@ -391,7 +392,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, * send an oplock break to the holder of the * oplock and tell caller to retry later */ - if (break_to_none) { + if (break_to_none || + !file->entries[i].allow_level_II_oplock) { oplock_return = OPLOCK_BREAK_TO_NONE; } odb_oplock_break_send(odb, &file->entries[i], @@ -418,6 +420,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, uint32_t open_disposition, bool break_to_none, + bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { struct odb_context *odb = lck->odb; @@ -447,13 +450,14 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, NT_STATUS_NOT_OK_RETURN(status); /* see if it conflicts */ - e.server = odb->ntvfs_ctx->server_id; - e.file_handle = file_handle; - e.stream_id = stream_id; - e.share_access = share_access; - e.access_mask = access_mask; - e.delete_on_close = delete_on_close; - e.oplock_level = OPLOCK_NONE; + e.server = odb->ntvfs_ctx->server_id; + e.file_handle = file_handle; + e.stream_id = stream_id; + e.share_access = share_access; + e.access_mask = access_mask; + e.delete_on_close = delete_on_close; + e.allow_level_II_oplock = allow_level_II_oplock; + e.oplock_level = OPLOCK_NONE; /* possibly grant an exclusive, batch or level2 oplock @@ -466,17 +470,23 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, if (file.num_entries == 0) { e.oplock_level = OPLOCK_EXCLUSIVE; *oplock_granted = EXCLUSIVE_OPLOCK_RETURN; - } else { + } else if (allow_level_II_oplock) { e.oplock_level = OPLOCK_LEVEL_II; *oplock_granted = LEVEL_II_OPLOCK_RETURN; + } else { + e.oplock_level = OPLOCK_NONE; + *oplock_granted = NO_OPLOCK_RETURN; } } else if (oplock_level == OPLOCK_BATCH) { if (file.num_entries == 0) { e.oplock_level = OPLOCK_BATCH; *oplock_granted = BATCH_OPLOCK_RETURN; - } else { + } else if (allow_level_II_oplock) { e.oplock_level = OPLOCK_LEVEL_II; *oplock_granted = LEVEL_II_OPLOCK_RETURN; + } else { + e.oplock_level = OPLOCK_NONE; + *oplock_granted = NO_OPLOCK_RETURN; } } else if (oplock_level == OPLOCK_LEVEL_II) { e.oplock_level = OPLOCK_LEVEL_II; -- cgit From ef4ae2597d0c198f42a5144ccd49716f0cb5796b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 6 Mar 2008 15:48:31 +0100 Subject: pvfs_open: pass down allow_level_II_oplock to odb_open_file() metze (This used to be commit 7c9b269b0742d435055e21f7e6cc945c21c7e332) --- source4/ntvfs/posix/pvfs_open.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 792e35cd14..47b44b9634 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -293,7 +293,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, io->generic.in.open_disposition, - false, OPLOCK_NONE, NULL); + false, false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); @@ -347,7 +347,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, io->generic.in.open_disposition, - false, OPLOCK_NONE, NULL); + false, false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; @@ -544,6 +544,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, bool del_on_close; struct pvfs_filename *parent; uint32_t oplock_level = OPLOCK_NONE, oplock_granted; + bool allow_level_II_oplock = false; if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { @@ -658,10 +659,15 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, oplock_level = OPLOCK_EXCLUSIVE; } + if (req->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS) { + allow_level_II_oplock = true; + } + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, io->generic.in.open_disposition, - false, oplock_level, &oplock_granted); + false, allow_level_II_oplock, + oplock_level, &oplock_granted); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { /* bad news, we must have hit a race - we don't delete the file @@ -1047,6 +1053,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, bool del_on_close; bool stream_existed, stream_truncate=false; uint32_t oplock_level = OPLOCK_NONE, oplock_granted; + bool allow_level_II_oplock = false; /* use the generic mapping code to avoid implementing all the different open calls. */ @@ -1241,11 +1248,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, oplock_level = OPLOCK_EXCLUSIVE; } + if (req->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS) { + allow_level_II_oplock = true; + } + /* see if we are allowed to open at the same time as existing opens */ status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, io->generic.in.open_disposition, - false, oplock_level, &oplock_granted); + false, allow_level_II_oplock, + oplock_level, &oplock_granted); /* * on a sharing violation we need to retry when the file is closed by -- cgit From b655468cf6646bdcc6bb78fe87492cf34b54713f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 19:12:14 +0100 Subject: vfs_cifs: disable level2 oplocks if the frontend client doesn't support them metze (This used to be commit a63910e8e5c075aff45b8eb0d246d2823f09bb9c) --- source4/ntvfs/cifs/vfs_cifs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 901dd2cf7c..58183b5e60 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -207,7 +207,11 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.service = remote_share; io.in.service_type = "?????"; lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); - + + if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) { + io.in.options.use_level2_oplocks = false; + } + creq = smb_composite_connect_send(&io, private, lp_resolve_context(ntvfs->ctx->lp_ctx), ntvfs->ctx->event_ctx); -- cgit From 6c27daeeca9c2649896b70fba78c3c401159defe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 10:33:57 +0100 Subject: opendb_tdb: pass down struct messaging_context directly to odb_oplock_break_send() metze (This used to be commit c993b07f7d5caf290ccb9ca81961aa35a3ed1f02) --- source4/ntvfs/common/opendb_tdb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 0736af3d1e..75424e65f6 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -263,7 +263,7 @@ static NTSTATUS odb_push_record(struct odb_lock *lck, struct opendb_file *file) /* send an oplock break to a client */ -static NTSTATUS odb_oplock_break_send(struct odb_context *odb, +static NTSTATUS odb_oplock_break_send(struct messaging_context *msg_ctx, struct opendb_entry *e, uint8_t level) { @@ -280,7 +280,7 @@ static NTSTATUS odb_oplock_break_send(struct odb_context *odb, blob = data_blob_const(&op_break, sizeof(op_break)); - status = messaging_send(odb->ntvfs_ctx->msg_ctx, e->server, + status = messaging_send(msg_ctx, e->server, MSG_NTVFS_OPLOCK_BREAK, &blob); NT_STATUS_NOT_OK_RETURN(status); @@ -348,7 +348,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, !file->entries[i].allow_level_II_oplock) { oplock_return = OPLOCK_BREAK_TO_NONE; } - odb_oplock_break_send(odb, &file->entries[i], + odb_oplock_break_send(odb->ntvfs_ctx->msg_ctx, + &file->entries[i], oplock_return); return NT_STATUS_OPLOCK_NOT_GRANTED; } @@ -396,7 +397,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, !file->entries[i].allow_level_II_oplock) { oplock_return = OPLOCK_BREAK_TO_NONE; } - odb_oplock_break_send(odb, &file->entries[i], + odb_oplock_break_send(odb->ntvfs_ctx->msg_ctx, + &file->entries[i], oplock_return); return NT_STATUS_OPLOCK_NOT_GRANTED; } @@ -655,7 +657,8 @@ static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck) * and we just send a break to none to all of them * without waiting for a release */ - odb_oplock_break_send(odb, &file.entries[i], + odb_oplock_break_send(odb->ntvfs_ctx->msg_ctx, + &file.entries[i], OPLOCK_BREAK_TO_NONE); file.entries[i].oplock_level = OPLOCK_NONE; modified = true; -- cgit From 75a412a46975754e75679f5d072e6ce688fee894 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 17:50:17 +0100 Subject: pvfs_open: always call odb_can_open() before odb_open_file() odb_open_file() will later change to not redo the logic of odb_can_open(). metze (This used to be commit b09a1461ac595be1b6530221b7df5211084884cc) --- source4/ntvfs/posix/pvfs_open.c | 51 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 47b44b9634..1ed517c719 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -290,6 +290,15 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } /* see if we are allowed to open at the same time as existing opens */ + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, del_on_close, + io->generic.in.open_disposition, false); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } + + /* now really mark the file as open */ status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, io->generic.in.open_disposition, @@ -344,6 +353,14 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_INTERNAL_DB_CORRUPTION; } + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, del_on_close, + io->generic.in.open_disposition, false); + + if (!NT_STATUS_IS_OK(status)) { + goto cleanup_delete; + } + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, io->generic.in.open_disposition, @@ -663,6 +680,18 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, allow_level_II_oplock = true; } + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, del_on_close, + io->generic.in.open_disposition, false); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + /* bad news, we must have hit a race - we don't delete the file + here as the most likely scenario is that someone else created + the file at the same time */ + close(fd); + return status; + } + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, share_access, access_mask, del_on_close, io->generic.in.open_disposition, @@ -801,7 +830,7 @@ static void pvfs_odb_retry_callback(void *_r, enum pvfs_wait_notice reason) /* setup for a retry of a request that was rejected - by odb_open_file() or odb_can_open() + by odb_can_open() */ NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, @@ -1253,11 +1282,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* see if we are allowed to open at the same time as existing opens */ - status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, - share_access, access_mask, del_on_close, - io->generic.in.open_disposition, - false, allow_level_II_oplock, - oplock_level, &oplock_granted); + status = odb_can_open(lck, name->stream_id, + share_access, access_mask, del_on_close, + io->generic.in.open_disposition, false); /* * on a sharing violation we need to retry when the file is closed by @@ -1276,6 +1303,18 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + /* now really mark the file as open */ + status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, + share_access, access_mask, del_on_close, + io->generic.in.open_disposition, + false, allow_level_II_oplock, + oplock_level, &oplock_granted); + + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return status; + } + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { oplock_granted = OPLOCK_BATCH; } else if (oplock_granted != OPLOCK_NONE) { -- cgit From e5e799aeb6b57ade1dd9c1a1d2c3aab1ad08d6df Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 18:23:34 +0100 Subject: opendb: force odb_can_open() before odb_open_file() Now there's only odb_can_open() which handles the share_access rules. And odb_open_file() only adds the new opendb_entry into the database and calculates the granted oplock level. metze (This used to be commit db0853ae4fead34ef382bbfcfe2f46453ab8b73b) --- source4/ntvfs/common/opendb.c | 14 ++--- source4/ntvfs/common/opendb.h | 3 - source4/ntvfs/common/opendb_tdb.c | 120 +++++++++++++++++++++----------------- 3 files changed, 72 insertions(+), 65 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index a7e5458aaf..1cc077137c 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -87,23 +87,21 @@ _PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) } /* - register an open file in the open files database. This implements the share_access - rules + register an open file in the open files database. + The share_access rules are implemented by odb_can_open() + and it's needed to call odb_can_open() before + odb_open_file() otherwise NT_STATUS_INTERNAL_ERROR is returned Note that the path is only used by the delete on close logic, not for comparing with other filenames */ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, const char *path, - uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, bool delete_on_close, - uint32_t open_disposition, bool break_to_none, bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { - return ops->odb_open_file(lck, file_handle, path, stream_id, share_access, - access_mask, delete_on_close, open_disposition, - break_to_none, allow_level_II_oplock, + return ops->odb_open_file(lck, file_handle, path, + allow_level_II_oplock, oplock_level, oplock_granted); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 1c7f815dea..fb3223aea9 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -27,9 +27,6 @@ struct opendb_ops { DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck); NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle, const char *path, - uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, bool delete_on_close, - uint32_t open_disposition, bool break_to_none, bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 75424e65f6..f71416ec83 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -63,6 +63,11 @@ struct odb_context { struct odb_lock { struct odb_context *odb; TDB_DATA key; + + struct { + struct opendb_entry *e; + bool attrs_only; + } can_open; }; /* @@ -130,6 +135,8 @@ static struct odb_lock *odb_tdb_lock(TALLOC_CTX *mem_ctx, return NULL; } + ZERO_STRUCT(lck->can_open); + talloc_set_destructor(lck, odb_lock_destructor); return lck; @@ -411,30 +418,35 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, } /* - register an open file in the open files database. This implements the share_access - rules + register an open file in the open files database. + The share_access rules are implemented by odb_can_open() + and it's needed to call odb_can_open() before + odb_open_file() otherwise NT_STATUS_INTERNAL_ERROR is returned Note that the path is only used by the delete on close logic, not for comparing with other filenames */ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, const char *path, - uint32_t stream_id, uint32_t share_access, - uint32_t access_mask, bool delete_on_close, - uint32_t open_disposition, bool break_to_none, bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { struct odb_context *odb = lck->odb; - struct opendb_entry e; struct opendb_file file; NTSTATUS status; - bool attrs_only = false; + + if (!lck->can_open.e) { + return NT_STATUS_INTERNAL_ERROR; + } if (odb->oplocks == false) { oplock_level = OPLOCK_NONE; } + if (!oplock_granted) { + oplock_level = OPLOCK_NONE; + } + status = odb_pull_record(lck, &file); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { /* initialise a blank structure */ @@ -444,67 +456,55 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, NT_STATUS_NOT_OK_RETURN(status); } - /* see if it conflicts */ - status = odb_tdb_open_can_internal(odb, &file, stream_id, - share_access, access_mask, - delete_on_close, open_disposition, - break_to_none, &attrs_only); - NT_STATUS_NOT_OK_RETURN(status); - - /* see if it conflicts */ - e.server = odb->ntvfs_ctx->server_id; - e.file_handle = file_handle; - e.stream_id = stream_id; - e.share_access = share_access; - e.access_mask = access_mask; - e.delete_on_close = delete_on_close; - e.allow_level_II_oplock = allow_level_II_oplock; - e.oplock_level = OPLOCK_NONE; - /* possibly grant an exclusive, batch or level2 oplock */ + if (lck->can_open.attrs_only) { + oplock_level = OPLOCK_NONE; + } else if (oplock_level == OPLOCK_EXCLUSIVE) { + if (file.num_entries == 0) { + oplock_level = OPLOCK_EXCLUSIVE; + } else if (allow_level_II_oplock) { + oplock_level = OPLOCK_LEVEL_II; + } else { + oplock_level = OPLOCK_NONE; + } + } else if (oplock_level == OPLOCK_BATCH) { + if (file.num_entries == 0) { + oplock_level = OPLOCK_BATCH; + } else if (allow_level_II_oplock) { + oplock_level = OPLOCK_LEVEL_II; + } else { + oplock_level = OPLOCK_NONE; + } + } else if (oplock_level == OPLOCK_LEVEL_II) { + oplock_level = OPLOCK_LEVEL_II; + } else { + oplock_level = OPLOCK_NONE; + } + if (oplock_granted) { - if (attrs_only) { - e.oplock_level = OPLOCK_NONE; - *oplock_granted = NO_OPLOCK_RETURN; - } else if (oplock_level == OPLOCK_EXCLUSIVE) { - if (file.num_entries == 0) { - e.oplock_level = OPLOCK_EXCLUSIVE; - *oplock_granted = EXCLUSIVE_OPLOCK_RETURN; - } else if (allow_level_II_oplock) { - e.oplock_level = OPLOCK_LEVEL_II; - *oplock_granted = LEVEL_II_OPLOCK_RETURN; - } else { - e.oplock_level = OPLOCK_NONE; - *oplock_granted = NO_OPLOCK_RETURN; - } + if (oplock_level == OPLOCK_EXCLUSIVE) { + *oplock_granted = EXCLUSIVE_OPLOCK_RETURN; } else if (oplock_level == OPLOCK_BATCH) { - if (file.num_entries == 0) { - e.oplock_level = OPLOCK_BATCH; - *oplock_granted = BATCH_OPLOCK_RETURN; - } else if (allow_level_II_oplock) { - e.oplock_level = OPLOCK_LEVEL_II; - *oplock_granted = LEVEL_II_OPLOCK_RETURN; - } else { - e.oplock_level = OPLOCK_NONE; - *oplock_granted = NO_OPLOCK_RETURN; - } + *oplock_granted = BATCH_OPLOCK_RETURN; } else if (oplock_level == OPLOCK_LEVEL_II) { - e.oplock_level = OPLOCK_LEVEL_II; *oplock_granted = LEVEL_II_OPLOCK_RETURN; } else { - e.oplock_level = OPLOCK_NONE; *oplock_granted = NO_OPLOCK_RETURN; } } + lck->can_open.e->file_handle = file_handle; + lck->can_open.e->allow_level_II_oplock = allow_level_II_oplock; + lck->can_open.e->oplock_level = oplock_level; + /* it doesn't conflict, so add it to the end */ file.entries = talloc_realloc(lck, file.entries, struct opendb_entry, file.num_entries+1); NT_STATUS_HAVE_NO_MEMORY(file.entries); - file.entries[file.num_entries] = e; + file.entries[file.num_entries] = *lck->can_open.e; file.num_entries++; return odb_push_record(lck, &file); @@ -807,20 +807,32 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, struct odb_context *odb = lck->odb; NTSTATUS status; struct opendb_file file; - bool attrs_only = false; status = odb_pull_record(lck, &file); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - return NT_STATUS_OK; + goto ok; } NT_STATUS_NOT_OK_RETURN(status); status = odb_tdb_open_can_internal(odb, &file, stream_id, share_access, access_mask, delete_on_close, open_disposition, - break_to_none, &attrs_only); + break_to_none, &lck->can_open.attrs_only); NT_STATUS_NOT_OK_RETURN(status); +ok: + lck->can_open.e = talloc(lck, struct opendb_entry); + NT_STATUS_HAVE_NO_MEMORY(lck->can_open.e); + + lck->can_open.e->server = odb->ntvfs_ctx->server_id; + lck->can_open.e->file_handle = NULL; + lck->can_open.e->stream_id = stream_id; + lck->can_open.e->share_access = share_access; + lck->can_open.e->access_mask = access_mask; + lck->can_open.e->delete_on_close = delete_on_close; + lck->can_open.e->allow_level_II_oplock = false; + lck->can_open.e->oplock_level = OPLOCK_NONE; + return NT_STATUS_OK; } -- cgit From db669e1eb13effb08b1111405587c8c6dde95954 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 18:28:48 +0100 Subject: pvfs_open: fix the odb_open_file() callers metze (This used to be commit 5fdca988c687f58fe2fddd3c8eff5f461207065b) --- source4/ntvfs/posix/pvfs_open.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1ed517c719..2e757e1742 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -299,10 +299,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } /* now really mark the file as open */ - status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, - share_access, access_mask, del_on_close, - io->generic.in.open_disposition, - false, false, OPLOCK_NONE, NULL); + status = odb_open_file(lck, f->handle, name->full_name, + false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); @@ -361,10 +359,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, goto cleanup_delete; } - status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, - share_access, access_mask, del_on_close, - io->generic.in.open_disposition, - false, false, OPLOCK_NONE, NULL); + status = odb_open_file(lck, f->handle, name->full_name, + false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; @@ -692,10 +688,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } - status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, - share_access, access_mask, del_on_close, - io->generic.in.open_disposition, - false, allow_level_II_oplock, + status = odb_open_file(lck, f->handle, name->full_name, + allow_level_II_oplock, oplock_level, &oplock_granted); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { @@ -1304,10 +1298,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* now really mark the file as open */ - status = odb_open_file(lck, f->handle, name->full_name, name->stream_id, - share_access, access_mask, del_on_close, - io->generic.in.open_disposition, - false, allow_level_II_oplock, + status = odb_open_file(lck, f->handle, name->full_name, + allow_level_II_oplock, oplock_level, &oplock_granted); if (!NT_STATUS_IS_OK(status)) { -- cgit From 11fb55e8a478eed8d2496dee4b2a9cf5a3619454 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Mar 2008 08:58:41 +0100 Subject: opendb_tdb: correctly initialize modified to false Otherwise this variable would never change its value... metze (This used to be commit 5b13a564b8459c3134a43e1d4b4a791e33108b1b) --- source4/ntvfs/common/opendb_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index f71416ec83..a800cdbd7c 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -641,7 +641,7 @@ static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck) NTSTATUS status; struct opendb_file file; int i; - bool modified = true; + bool modified = false; status = odb_pull_record(lck, &file); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { -- cgit From db06d932c8f43b02d4a54d0c139310a3890160d5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Mar 2008 08:55:12 +0100 Subject: opendb_tdb: keep struct opendb_file arround for the lifetime of struct odb_lock That means we only have to parse the record once and as the tdb record is locked the in memory copy is always the same as the one in the tdb. metze (This used to be commit 0641a43cd6fd081cac0275f5bde2ad70fa6a71bb) --- source4/ntvfs/common/opendb_tdb.c | 244 +++++++++++++++++--------------------- 1 file changed, 109 insertions(+), 135 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index a800cdbd7c..17fcdfbbb4 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -64,6 +64,8 @@ struct odb_lock { struct odb_context *odb; TDB_DATA key; + struct opendb_file file; + struct { struct opendb_entry *e; bool attrs_only; @@ -108,6 +110,8 @@ static int odb_lock_destructor(struct odb_lock *lck) return 0; } +static NTSTATUS odb_pull_record(struct odb_lock *lck, struct opendb_file *file); + /* get a lock on a entry in the odb. This call returns a lock handle, which the caller should unlock using talloc_free(). @@ -116,6 +120,7 @@ static struct odb_lock *odb_tdb_lock(TALLOC_CTX *mem_ctx, struct odb_context *odb, DATA_BLOB *file_key) { struct odb_lock *lck; + NTSTATUS status; lck = talloc(mem_ctx, struct odb_lock); if (lck == NULL) { @@ -138,6 +143,15 @@ static struct odb_lock *odb_tdb_lock(TALLOC_CTX *mem_ctx, ZERO_STRUCT(lck->can_open); talloc_set_destructor(lck, odb_lock_destructor); + + status = odb_pull_record(lck, &lck->file); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + /* initialise a blank structure */ + ZERO_STRUCT(lck->file); + } else if (!NT_STATUS_IS_OK(status)) { + talloc_free(lck); + return NULL; + } return lck; } @@ -432,8 +446,6 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, uint32_t oplock_level, uint32_t *oplock_granted) { struct odb_context *odb = lck->odb; - struct opendb_file file; - NTSTATUS status; if (!lck->can_open.e) { return NT_STATUS_INTERNAL_ERROR; @@ -447,13 +459,9 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, oplock_level = OPLOCK_NONE; } - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - /* initialise a blank structure */ - ZERO_STRUCT(file); - file.path = path; - } else { - NT_STATUS_NOT_OK_RETURN(status); + if (lck->file.path == NULL) { + lck->file.path = talloc_strdup(lck, path); + NT_STATUS_HAVE_NO_MEMORY(lck->file.path); } /* @@ -462,7 +470,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, if (lck->can_open.attrs_only) { oplock_level = OPLOCK_NONE; } else if (oplock_level == OPLOCK_EXCLUSIVE) { - if (file.num_entries == 0) { + if (lck->file.num_entries == 0) { oplock_level = OPLOCK_EXCLUSIVE; } else if (allow_level_II_oplock) { oplock_level = OPLOCK_LEVEL_II; @@ -470,7 +478,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, oplock_level = OPLOCK_NONE; } } else if (oplock_level == OPLOCK_BATCH) { - if (file.num_entries == 0) { + if (lck->file.num_entries == 0) { oplock_level = OPLOCK_BATCH; } else if (allow_level_II_oplock) { oplock_level = OPLOCK_LEVEL_II; @@ -500,14 +508,18 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, lck->can_open.e->oplock_level = oplock_level; /* it doesn't conflict, so add it to the end */ - file.entries = talloc_realloc(lck, file.entries, struct opendb_entry, - file.num_entries+1); - NT_STATUS_HAVE_NO_MEMORY(file.entries); + lck->file.entries = talloc_realloc(lck, lck->file.entries, + struct opendb_entry, + lck->file.num_entries+1); + NT_STATUS_HAVE_NO_MEMORY(lck->file.entries); + + lck->file.entries[lck->file.num_entries] = *lck->can_open.e; + lck->file.num_entries++; - file.entries[file.num_entries] = *lck->can_open.e; - file.num_entries++; + talloc_free(lck->can_open.e); + lck->can_open.e = NULL; - return odb_push_record(lck, &file); + return odb_push_record(lck, &lck->file); } @@ -517,22 +529,22 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, static NTSTATUS odb_tdb_open_file_pending(struct odb_lock *lck, void *private) { struct odb_context *odb = lck->odb; - struct opendb_file file; - NTSTATUS status; - - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); - file.pending = talloc_realloc(lck, file.pending, struct opendb_pending, - file.num_pending+1); - NT_STATUS_HAVE_NO_MEMORY(file.pending); + if (lck->file.path == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } - file.pending[file.num_pending].server = odb->ntvfs_ctx->server_id; - file.pending[file.num_pending].notify_ptr = private; + lck->file.pending = talloc_realloc(lck, lck->file.pending, + struct opendb_pending, + lck->file.num_pending+1); + NT_STATUS_HAVE_NO_MEMORY(lck->file.pending); - file.num_pending++; + lck->file.pending[lck->file.num_pending].server = odb->ntvfs_ctx->server_id; + lck->file.pending[lck->file.num_pending].notify_ptr = private; - return odb_push_record(lck, &file); + lck->file.num_pending++; + + return odb_push_record(lck, &lck->file); } @@ -543,54 +555,53 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle, const char **_delete_path) { struct odb_context *odb = lck->odb; - struct opendb_file file; const char *delete_path = NULL; int i; - NTSTATUS status; - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); + if (lck->file.path == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } /* find the entry, and delete it */ - for (i=0;intvfs_ctx->server_id, &file.entries[i].server)) { - if (file.entries[i].delete_on_close) { - file.delete_on_close = true; + for (i=0;ifile.num_entries;i++) { + if (file_handle == lck->file.entries[i].file_handle && + cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.entries[i].server)) { + if (lck->file.entries[i].delete_on_close) { + lck->file.delete_on_close = true; } - if (i < file.num_entries-1) { - memmove(file.entries+i, file.entries+i+1, - (file.num_entries - (i+1)) * + if (i < lck->file.num_entries-1) { + memmove(lck->file.entries+i, lck->file.entries+i+1, + (lck->file.num_entries - (i+1)) * sizeof(struct opendb_entry)); } break; } } - if (i == file.num_entries) { + if (i == lck->file.num_entries) { return NT_STATUS_UNSUCCESSFUL; } /* send any pending notifications, removing them once sent */ - for (i=0;intvfs_ctx->msg_ctx, file.pending[i].server, - MSG_PVFS_RETRY_OPEN, - file.pending[i].notify_ptr); + for (i=0;ifile.num_pending;i++) { + messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, + lck->file.pending[i].server, + MSG_PVFS_RETRY_OPEN, + lck->file.pending[i].notify_ptr); } - file.num_pending = 0; + lck->file.num_pending = 0; - file.num_entries--; + lck->file.num_entries--; - if (file.num_entries == 0 && file.delete_on_close) { - delete_path = talloc_strdup(lck, file.path); - NT_STATUS_HAVE_NO_MEMORY(delete_path); + if (lck->file.num_entries == 0 && lck->file.delete_on_close) { + delete_path = lck->file.path; } if (_delete_path) { *_delete_path = delete_path; } - return odb_push_record(lck, &file); + return odb_push_record(lck, &lck->file); } /* @@ -600,36 +611,35 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle, uint32_t oplock_level) { struct odb_context *odb = lck->odb; - struct opendb_file file; int i; - NTSTATUS status; - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); + if (lck->file.path == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } /* find the entry, and update it */ - for (i=0;intvfs_ctx->server_id, &file.entries[i].server)) { - file.entries[i].oplock_level = oplock_level; + for (i=0;ifile.num_entries;i++) { + if (file_handle == lck->file.entries[i].file_handle && + cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.entries[i].server)) { + lck->file.entries[i].oplock_level = oplock_level; break; } } - if (i == file.num_entries) { + if (i == lck->file.num_entries) { return NT_STATUS_UNSUCCESSFUL; } /* send any pending notifications, removing them once sent */ - for (i=0;ifile.num_pending;i++) { messaging_send_ptr(odb->ntvfs_ctx->msg_ctx, - file.pending[i].server, + lck->file.pending[i].server, MSG_PVFS_RETRY_OPEN, - file.pending[i].notify_ptr); + lck->file.pending[i].notify_ptr); } - file.num_pending = 0; + lck->file.num_pending = 0; - return odb_push_record(lck, &file); + return odb_push_record(lck, &lck->file); } /* @@ -638,35 +648,27 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle, static NTSTATUS odb_tdb_break_oplocks(struct odb_lock *lck) { struct odb_context *odb = lck->odb; - NTSTATUS status; - struct opendb_file file; int i; bool modified = false; - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - return NT_STATUS_OK; - } - NT_STATUS_NOT_OK_RETURN(status); - /* see if anyone has an oplock, which we need to break */ - for (i=0;ifile.num_entries;i++) { + if (lck->file.entries[i].oplock_level == OPLOCK_LEVEL_II) { /* * there could be multiple level2 oplocks * and we just send a break to none to all of them * without waiting for a release */ odb_oplock_break_send(odb->ntvfs_ctx->msg_ctx, - &file.entries[i], + &lck->file.entries[i], OPLOCK_BREAK_TO_NONE); - file.entries[i].oplock_level = OPLOCK_NONE; + lck->file.entries[i].oplock_level = OPLOCK_NONE; modified = true; } } if (modified) { - return odb_push_record(lck, &file); + return odb_push_record(lck, &lck->file); } return NT_STATUS_OK; } @@ -678,32 +680,31 @@ static NTSTATUS odb_tdb_remove_pending(struct odb_lock *lck, void *private) { struct odb_context *odb = lck->odb; int i; - NTSTATUS status; - struct opendb_file file; - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); + if (lck->file.path == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } /* find the entry, and delete it */ - for (i=0;intvfs_ctx->server_id, &file.pending[i].server)) { - if (i < file.num_pending-1) { - memmove(file.pending+i, file.pending+i+1, - (file.num_pending - (i+1)) * + for (i=0;ifile.num_pending;i++) { + if (private == lck->file.pending[i].notify_ptr && + cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.pending[i].server)) { + if (i < lck->file.num_pending-1) { + memmove(lck->file.pending+i, lck->file.pending+i+1, + (lck->file.num_pending - (i+1)) * sizeof(struct opendb_pending)); } break; } } - if (i == file.num_pending) { + if (i == lck->file.num_pending) { return NT_STATUS_UNSUCCESSFUL; } - file.num_pending--; + lck->file.num_pending--; - return odb_push_record(lck, &file); + return odb_push_record(lck, &lck->file); } @@ -712,18 +713,15 @@ static NTSTATUS odb_tdb_remove_pending(struct odb_lock *lck, void *private) */ static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path) { - struct opendb_file file; - NTSTATUS status; - - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { + if (lck->file.path == NULL) { /* not having the record at all is OK */ return NT_STATUS_OK; } - NT_STATUS_NOT_OK_RETURN(status); - file.path = path; - return odb_push_record(lck, &file); + lck->file.path = talloc_strdup(lck, path); + NT_STATUS_HAVE_NO_MEMORY(lck->file.path); + + return odb_push_record(lck, &lck->file); } /* @@ -731,16 +729,14 @@ static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path) */ static NTSTATUS odb_tdb_get_path(struct odb_lock *lck, const char **path) { - struct opendb_file file; - NTSTATUS status; - *path = NULL; - status = odb_pull_record(lck, &file); /* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */ - NT_STATUS_NOT_OK_RETURN(status); + if (lck->file.path == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } - *path = file.path; + *path = lck->file.path; return NT_STATUS_OK; } @@ -750,15 +746,13 @@ static NTSTATUS odb_tdb_get_path(struct odb_lock *lck, const char **path) */ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_close) { - NTSTATUS status; - struct opendb_file file; - - status = odb_pull_record(lck, &file); - NT_STATUS_NOT_OK_RETURN(status); + if (lck->file.path == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } - file.delete_on_close = del_on_close; + lck->file.delete_on_close = del_on_close; - return odb_push_record(lck, &file); + return odb_push_record(lck, &lck->file); } /* @@ -768,8 +762,6 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, DATA_BLOB *key, bool *del_on_close) { - NTSTATUS status; - struct opendb_file file; struct odb_lock *lck; (*del_on_close) = false; @@ -777,17 +769,7 @@ static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, lck = odb_lock(odb, odb, key); NT_STATUS_HAVE_NO_MEMORY(lck); - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND, status)) { - talloc_free(lck); - return NT_STATUS_OK; - } - if (!NT_STATUS_IS_OK(status)) { - talloc_free(lck); - return status; - } - - (*del_on_close) = file.delete_on_close; + (*del_on_close) = lck->file.delete_on_close; talloc_free(lck); @@ -806,21 +788,13 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, { struct odb_context *odb = lck->odb; NTSTATUS status; - struct opendb_file file; - - status = odb_pull_record(lck, &file); - if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { - goto ok; - } - NT_STATUS_NOT_OK_RETURN(status); - status = odb_tdb_open_can_internal(odb, &file, stream_id, + status = odb_tdb_open_can_internal(odb, &lck->file, stream_id, share_access, access_mask, delete_on_close, open_disposition, break_to_none, &lck->can_open.attrs_only); NT_STATUS_NOT_OK_RETURN(status); -ok: lck->can_open.e = talloc(lck, struct opendb_entry); NT_STATUS_HAVE_NO_MEMORY(lck->can_open.e); -- cgit From 2bf39edc9d0abf3306bd25b9c40d88aceb029be7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Mar 2008 15:28:12 +0100 Subject: Push SOVERSION and VERSION out of perl code. (This used to be commit 0ba8ac6a14c62ff9edfe9f0bf43b8a7406b85291) --- source4/ntvfs/ntvfs_base.c | 1 - source4/ntvfs/sysdep/sys_notify.c | 1 - 2 files changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 35becabcf9..0cffdb7fa9 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -24,7 +24,6 @@ #include "includes.h" #include "lib/util/dlinklist.h" -#include "build.h" #include "ntvfs/ntvfs.h" #include "param/param.h" diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 84ba745f5b..e5d6c75f71 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -28,7 +28,6 @@ #include "lib/events/events.h" #include "lib/util/dlinklist.h" #include "param/param.h" -#include "build.h" /* list of registered backends */ static struct sys_notify_backend *backends; -- cgit From fb6fdfce37a91021c346a52bd7d55a5ee576580a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 8 Mar 2008 17:02:40 +0100 Subject: Fix the build. (This used to be commit f2e49744717eb46bbfafeea9e2eb412a38a142e7) --- source4/ntvfs/ntvfs_base.c | 10 ++++++++++ source4/ntvfs/sysdep/sys_notify.c | 1 + 2 files changed, 11 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 0cffdb7fa9..4cd6192c77 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -203,6 +203,16 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { static bool initialized = false; + extern NTSTATUS ntvfs_posix_init(void); + extern NTSTATUS ntvfs_cifs_init(void); + extern NTSTATUS ntvfs_nbench_init(void); + extern NTSTATUS ntvfs_unixuid_init(void); + extern NTSTATUS ntvfs_ipc_init(void); + extern NTSTATUS pvfs_acl_nfs4_init(void); + extern NTSTATUS pvfs_acl_xattr_init(void); + extern NTSTATUS ntvfs_print_init(void); + extern NTSTATUS ntvfs_simple_init(void); + extern NTSTATUS ntvfs_cifs_posix_init(void); init_module_fn static_init[] = { STATIC_ntvfs_MODULES }; init_module_fn *shared_init; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index e5d6c75f71..c628b9068c 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -123,6 +123,7 @@ _PUBLIC_ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) _PUBLIC_ NTSTATUS sys_notify_init(void) { static bool initialized = false; + extern NTSTATUS sys_notify_inotify_init(void); init_module_fn static_init[] = { STATIC_sys_notify_MODULES }; -- cgit From 8e70dc7e9a1c88a4766b92ec61cbe7ba6f7dcd7f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 11 Mar 2008 19:29:18 +0100 Subject: pvfs: return NT_STATUS_NOT_IMPLEMENTED on RAW_RENAME_NTTRANS metze (This used to be commit 6dc280731d071681b635a2f091be2b153a902080) --- source4/ntvfs/posix/pvfs_rename.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 29b2d03005..e94de8b28e 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -575,6 +575,9 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, case RAW_RENAME_NTRENAME: return pvfs_rename_nt(ntvfs, req, ren); + case RAW_RENAME_NTTRANS: + return NT_STATUS_NOT_IMPLEMENTED; + default: break; } -- cgit From f533d6d8a255298ba191daa1a2c41c6228c85aa4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Mar 2008 15:12:26 +0100 Subject: pvfs_rename: implement RAW_RENAME_NTTRANS as noop as w2k3 metze (This used to be commit 40563583f7ef3d8d1a3426c6c12eaecd18af215c) --- source4/ntvfs/posix/pvfs_rename.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index e94de8b28e..5c2a627084 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -568,6 +568,9 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs, NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_rename *ren) { + struct pvfs_state *pvfs = ntvfs->private_data; + struct pvfs_file *f; + switch (ren->generic.level) { case RAW_RENAME_RENAME: return pvfs_rename_mv(ntvfs, req, ren); @@ -576,7 +579,13 @@ NTSTATUS pvfs_rename(struct ntvfs_module_context *ntvfs, return pvfs_rename_nt(ntvfs, req, ren); case RAW_RENAME_NTTRANS: - return NT_STATUS_NOT_IMPLEMENTED; + f = pvfs_find_fd(pvfs, req, ren->nttrans.in.file.ntvfs); + if (!f) { + return NT_STATUS_INVALID_HANDLE; + } + + /* wk23 ignores the request */ + return NT_STATUS_OK; default: break; -- cgit From 7cdf28ebaccb41a23c2986b123624b238effcfda Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Mar 2008 17:34:16 +0100 Subject: ntvfs/cifs: fix the fnum on RAW_RENAME_NTTRANS metze (This used to be commit b43f1a53dd185cc51a3fb8a18e311abb77c2a7c9) --- source4/ntvfs/cifs/vfs_cifs.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 58183b5e60..3c090b5f5c 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -595,6 +595,13 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, SETUP_PID; + if (ren->nttrans.level == RAW_RENAME_NTTRANS) { + struct cvfs_file *f; + f = ntvfs_handle_get_backend_data(ren->nttrans.in.file.ntvfs, ntvfs); + if (!f) return NT_STATUS_INVALID_HANDLE; + ren->nttrans.in.file.fnum = f->fnum; + } + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_rename(private->tree, ren); } -- cgit From 59917521e9d811efe7b424d49f03fb972ee0a119 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Mar 2008 09:12:09 +0100 Subject: opendb: pass down a pointer to the fd in odb_open_file() This prepares kernel oplock support. metze (This used to be commit 9db9b6d85d80a8aaa8bd432afaef9bb634d7364d) --- source4/ntvfs/common/opendb.c | 4 ++-- source4/ntvfs/common/opendb.h | 2 +- source4/ntvfs/common/opendb_tdb.c | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 1cc077137c..676706e03f 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -97,11 +97,11 @@ _PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) */ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, const char *path, - bool allow_level_II_oplock, + int *fd, bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { return ops->odb_open_file(lck, file_handle, path, - allow_level_II_oplock, + fd, allow_level_II_oplock, oplock_level, oplock_granted); } diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index fb3223aea9..045476337a 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -27,7 +27,7 @@ struct opendb_ops { DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck); NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle, const char *path, - bool allow_level_II_oplock, + int *fd, bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 17fcdfbbb4..9b4a5bfa9f 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -442,7 +442,7 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, */ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, const char *path, - bool allow_level_II_oplock, + int *fd, bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { struct odb_context *odb = lck->odb; @@ -504,6 +504,7 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, } lck->can_open.e->file_handle = file_handle; + lck->can_open.e->fd = fd; lck->can_open.e->allow_level_II_oplock = allow_level_II_oplock; lck->can_open.e->oplock_level = oplock_level; @@ -800,6 +801,7 @@ static NTSTATUS odb_tdb_can_open(struct odb_lock *lck, lck->can_open.e->server = odb->ntvfs_ctx->server_id; lck->can_open.e->file_handle = NULL; + lck->can_open.e->fd = NULL; lck->can_open.e->stream_id = stream_id; lck->can_open.e->share_access = share_access; lck->can_open.e->access_mask = access_mask; -- cgit From 7ba236d78e02fb8413db8c6ac74b9e89e64e847b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 8 Mar 2008 09:20:08 +0100 Subject: pvfs_open: pass down &f->handle->fd to odb_open_file() metze (This used to be commit 80f5f9362100b971fa12ffee33705b745131770e) --- source4/ntvfs/posix/pvfs_open.c | 61 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 31 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 2e757e1742..ceda3a6da0 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -300,7 +300,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* now really mark the file as open */ status = odb_open_file(lck, f->handle, name->full_name, - false, OPLOCK_NONE, NULL); + NULL, false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); @@ -360,7 +360,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } status = odb_open_file(lck, f->handle, name->full_name, - false, OPLOCK_NONE, NULL); + NULL, false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; @@ -688,19 +688,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } - status = odb_open_file(lck, f->handle, name->full_name, - allow_level_II_oplock, - oplock_level, &oplock_granted); - talloc_free(lck); - if (!NT_STATUS_IS_OK(status)) { - /* bad news, we must have hit a race - we don't delete the file - here as the most likely scenario is that someone else created - the file at the same time */ - close(fd); - return status; - } - - f->ntvfs = h; f->pvfs = pvfs; f->pending_list = NULL; @@ -723,6 +710,18 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->sticky_write_time = false; f->handle->open_completed = false; + status = odb_open_file(lck, f->handle, name->full_name, + &f->handle->fd, allow_level_II_oplock, + oplock_level, &oplock_granted); + talloc_free(lck); + if (!NT_STATUS_IS_OK(status)) { + /* bad news, we must have hit a race - we don't delete the file + here as the most likely scenario is that someone else created + the file at the same time */ + close(fd); + return status; + } + DLIST_ADD(pvfs->files.list, f); /* setup a destructor to avoid file descriptor leaks on @@ -1297,9 +1296,24 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { + flags |= O_RDWR; + } else { + flags |= O_RDONLY; + } + + /* do the actual open */ + fd = open(f->handle->name->full_name, flags); + if (fd == -1) { + talloc_free(lck); + return pvfs_map_errno(f->pvfs, errno); + } + + f->handle->fd = fd; + /* now really mark the file as open */ status = odb_open_file(lck, f->handle, name->full_name, - allow_level_II_oplock, + &f->handle->fd, allow_level_II_oplock, oplock_level, &oplock_granted); if (!NT_STATUS_IS_OK(status)) { @@ -1319,21 +1333,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->have_opendb_entry = true; - if (access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA)) { - flags |= O_RDWR; - } else { - flags |= O_RDONLY; - } - - /* do the actual open */ - fd = open(f->handle->name->full_name, flags); - if (fd == -1) { - talloc_free(lck); - return pvfs_map_errno(f->pvfs, errno); - } - - f->handle->fd = fd; - stream_existed = name->stream_exists; /* if this was a stream create then create the stream as well */ -- cgit From c3643d0ec8c26d399c379bd15142e730027aa9f0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 12:19:06 +0100 Subject: ntvfs/sysdep: add sys_lease abstraction to later support kernel oplocks metze (This used to be commit b399f0c872f32bb791da196102a5872c20e62100) --- source4/ntvfs/sysdep/config.mk | 8 +++ source4/ntvfs/sysdep/sys_lease.c | 142 +++++++++++++++++++++++++++++++++++++++ source4/ntvfs/sysdep/sys_lease.h | 65 ++++++++++++++++++ 3 files changed, 215 insertions(+) create mode 100644 source4/ntvfs/sysdep/sys_lease.c create mode 100644 source4/ntvfs/sysdep/sys_lease.h (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index dee198c9da..753c8833a4 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -16,3 +16,11 @@ OBJ_FILES = \ PUBLIC_DEPENDENCIES = # End SUBSYSTEM sys_notify ################################################ + +################################################ +# Start SUBSYSTEM sys_lease +[SUBSYSTEM::sys_lease] +OBJ_FILES = \ + sys_lease.o +# End SUBSYSTEM sys_lease +################################################ diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c new file mode 100644 index 0000000000..28dd27a708 --- /dev/null +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -0,0 +1,142 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Stefan Metzmacher 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + abstract the various kernel interfaces to leases (oplocks) into a + single Samba friendly interface +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "ntvfs/sysdep/sys_lease.h" +#include "lib/events/events.h" +#include "lib/util/dlinklist.h" +#include "param/param.h" +#include "build.h" + +/* list of registered backends */ +static struct sys_lease_ops *backends; +static uint32_t num_backends; + +#define LEASE_BACKEND "lease:backend" + +/* + initialise a system change notify backend +*/ +_PUBLIC_ struct sys_lease_context *sys_lease_context_create(struct share_config *scfg, + TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct messaging_context *msg, + sys_lease_send_break_fn break_send) +{ + struct sys_lease_context *ctx; + const char *bname; + int i; + NTSTATUS status; + + if (num_backends == 0) { + return NULL; + } + + if (ev == NULL) { + ev = event_context_find(mem_ctx); + } + + ctx = talloc_zero(mem_ctx, struct sys_lease_context); + if (ctx == NULL) { + return NULL; + } + + ctx->event_ctx = ev; + ctx->msg_ctx = msg; + ctx->break_send = break_send; + + bname = share_string_option(scfg, LEASE_BACKEND, NULL); + if (!bname) { + talloc_free(ctx); + return NULL; + } + + for (i=0;iops = &backends[i]; + break; + } + } + + if (!ctx->ops) { + talloc_free(ctx); + return NULL; + } + + status = ctx->ops->init(ctx); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(ctx); + return NULL; + } + + return ctx; +} + +/* + register a lease backend +*/ +_PUBLIC_ NTSTATUS sys_lease_register(const struct sys_lease_ops *backend) +{ + struct sys_lease_ops *b; + b = talloc_realloc(talloc_autofree_context(), backends, + struct sys_lease_ops, num_backends+1); + NT_STATUS_HAVE_NO_MEMORY(b); + backends = b; + backends[num_backends] = *backend; + num_backends++; + return NT_STATUS_OK; +} + +_PUBLIC_ NTSTATUS sys_lease_init(void) +{ + static bool initialized = false; + + init_module_fn static_init[] = { STATIC_sys_lease_MODULES }; + + if (initialized) return NT_STATUS_OK; + initialized = true; + + run_init_functions(static_init); + + return NT_STATUS_OK; +} + +NTSTATUS sys_lease_setup(struct sys_lease_context *ctx, + struct opendb_entry *e) +{ + return ctx->ops->setup(ctx, e); +} + +NTSTATUS sys_lease_update(struct sys_lease_context *ctx, + struct opendb_entry *e) +{ + return ctx->ops->update(ctx, e); +} + +NTSTATUS sys_lease_remove(struct sys_lease_context *ctx, + struct opendb_entry *e) +{ + return ctx->ops->remove(ctx, e); +} diff --git a/source4/ntvfs/sysdep/sys_lease.h b/source4/ntvfs/sysdep/sys_lease.h new file mode 100644 index 0000000000..e53760fb1e --- /dev/null +++ b/source4/ntvfs/sysdep/sys_lease.h @@ -0,0 +1,65 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Stefan Metzmacher 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "param/share.h" + +struct sys_lease_context; +struct opendb_entry; +struct messaging_context; + +typedef NTSTATUS (*sys_lease_send_break_fn)(struct messaging_context *, + struct opendb_entry *, + uint8_t level); + +struct sys_lease_ops { + const char *name; + NTSTATUS (*init)(struct sys_lease_context *ctx); + NTSTATUS (*setup)(struct sys_lease_context *ctx, + struct opendb_entry *e); + NTSTATUS (*update)(struct sys_lease_context *ctx, + struct opendb_entry *e); + NTSTATUS (*remove)(struct sys_lease_context *ctx, + struct opendb_entry *e); +}; + +struct sys_lease_context { + struct event_context *event_ctx; + struct messaging_context *msg_ctx; + sys_lease_send_break_fn break_send; + void *private_data; /* for use of backend */ + const struct sys_lease_ops *ops; +}; + +NTSTATUS sys_lease_register(const struct sys_lease_ops *ops); +NTSTATUS sys_lease_init(void); + +struct sys_lease_context *sys_lease_context_create(struct share_config *scfg, + TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct messaging_context *msg_ctx, + sys_lease_send_break_fn break_send); + +NTSTATUS sys_lease_setup(struct sys_lease_context *ctx, + struct opendb_entry *e); + +NTSTATUS sys_lease_update(struct sys_lease_context *ctx, + struct opendb_entry *e); + +NTSTATUS sys_lease_remove(struct sys_lease_context *ctx, + struct opendb_entry *e); -- cgit From d93f2f2e800591c68798e4a38da8fc982dac6a61 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 12:19:06 +0100 Subject: ntvfs/sysdep: implement linux kernel oplocks based F_SETLEASE metze (This used to be commit 3f165d3114519c317b9e7c871bb61d4fcbb8fb09) --- source4/ntvfs/sysdep/config.m4 | 10 ++ source4/ntvfs/sysdep/config.mk | 10 ++ source4/ntvfs/sysdep/sys_lease_linux.c | 213 +++++++++++++++++++++++++++++++++ 3 files changed, 233 insertions(+) create mode 100644 source4/ntvfs/sysdep/sys_lease_linux.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/config.m4 b/source4/ntvfs/sysdep/config.m4 index f70cac5e64..6de75a4294 100644 --- a/source4/ntvfs/sysdep/config.m4 +++ b/source4/ntvfs/sysdep/config.m4 @@ -11,3 +11,13 @@ fi if test x"$ac_cv_header_linux_inotify_h" = x"yes" -a x"$ac_cv_have___NR_inotify_init_decl" = x"yes"; then SMB_ENABLE(sys_notify_inotify, YES) fi + +AC_HAVE_DECL(F_SETLEASE, [#include ]) +AC_HAVE_DECL(SA_SIGINFO, [#include ]) + +SMB_ENABLE(sys_lease_linux, NO) + +if test x"$ac_cv_have_F_SETLEASE_decl" = x"yes" \ + -a x"$ac_cv_have_SA_SIGINFO_decl" = x"yes"; then + SMB_ENABLE(sys_lease_linux, YES) +fi diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 753c8833a4..048226efad 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -17,6 +17,16 @@ PUBLIC_DEPENDENCIES = # End SUBSYSTEM sys_notify ################################################ +################################################ +# Start MODULE sys_lease_linux +[MODULE::sys_lease_linux] +SUBSYSTEM = sys_lease +INIT_FUNCTION = sys_lease_linux_init +OBJ_FILES = \ + sys_lease_linux.o +# End MODULE sys_lease_linux +################################################ + ################################################ # Start SUBSYSTEM sys_lease [SUBSYSTEM::sys_lease] diff --git a/source4/ntvfs/sysdep/sys_lease_linux.c b/source4/ntvfs/sysdep/sys_lease_linux.c new file mode 100644 index 0000000000..0727eed212 --- /dev/null +++ b/source4/ntvfs/sysdep/sys_lease_linux.c @@ -0,0 +1,213 @@ +/* + Unix SMB/CIFS implementation. + + Copyright (C) Stefan Metzmacher 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + lease (oplock) implementation using fcntl F_SETLEASE on linux +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/events/events.h" +#include "ntvfs/sysdep/sys_lease.h" +#include "ntvfs/ntvfs.h" +#include "librpc/gen_ndr/ndr_opendb.h" +#include "lib/util/dlinklist.h" +#include "cluster/cluster.h" + +#define LINUX_LEASE_RT_SIGNAL (SIGRTMIN+1) + +struct linux_lease_pending { + struct linux_lease_pending *prev, *next; + struct sys_lease_context *ctx; + struct opendb_entry e; +}; + +/* the global linked list of pending leases */ +static struct linux_lease_pending *leases; + +static void linux_lease_signal_handler(struct event_context *ev_ctx, + struct signal_event *se, + int signum, int count, + void *_info, void *private_data) +{ + struct sys_lease_context *ctx = talloc_get_type(private_data, + struct sys_lease_context); + siginfo_t *info = (siginfo_t *)_info; + struct linux_lease_pending *c; + int got_fd = info->si_fd; + + for (c = leases; c; c = c->next) { + int *fd = (int *)c->e.fd; + + if (got_fd == *fd) { + break; + } + } + + if (!c) { + return; + } + + ctx->break_send(ctx->msg_ctx, &c->e, OPLOCK_BREAK_TO_NONE); +} + +static int linux_lease_pending_destructor(struct linux_lease_pending *p) +{ + int ret; + int *fd = (int *)p->e.fd; + + DLIST_REMOVE(leases, p); + + if (*fd == -1) { + return 0; + } + + ret = fcntl(*fd, F_SETLEASE, F_UNLCK); + if (ret == -1) { + DEBUG(0,("%s: failed to remove oplock: %s\n", + __FUNCTION__, strerror(errno))); + } + + return 0; +} + +static NTSTATUS linux_lease_init(struct sys_lease_context *ctx) +{ + struct signal_event *se; + + se = event_add_signal(ctx->event_ctx, ctx, + LINUX_LEASE_RT_SIGNAL, SA_SIGINFO, + linux_lease_signal_handler, ctx); + NT_STATUS_HAVE_NO_MEMORY(se); + + return NT_STATUS_OK; +} + +static NTSTATUS linux_lease_setup(struct sys_lease_context *ctx, + struct opendb_entry *e) +{ + int ret; + int *fd = (int *)e->fd; + struct linux_lease_pending *p; + + if (e->oplock_level == OPLOCK_NONE) { + e->fd = NULL; + return NT_STATUS_OK; + } else if (e->oplock_level == OPLOCK_LEVEL_II) { + /* + * the linux kernel doesn't support level2 oplocks + * so fix up the granted oplock level + */ + e->oplock_level = OPLOCK_NONE; + e->allow_level_II_oplock = false; + e->fd = NULL; + return NT_STATUS_OK; + } + + p = talloc(ctx, struct linux_lease_pending); + NT_STATUS_HAVE_NO_MEMORY(p); + + p->ctx = ctx; + p->e = *e; + + ret = fcntl(*fd, F_SETSIG, LINUX_LEASE_RT_SIGNAL); + if (ret == -1) { + talloc_free(p); + return map_nt_error_from_unix(errno); + } + + ret = fcntl(*fd, F_SETLEASE, F_WRLCK); + if (ret == -1) { + talloc_free(p); + return map_nt_error_from_unix(errno); + } + + DLIST_ADD(leases, p); + + talloc_set_destructor(p, linux_lease_pending_destructor); + + return NT_STATUS_OK; +} + +static NTSTATUS linux_lease_remove(struct sys_lease_context *ctx, + struct opendb_entry *e); + +static NTSTATUS linux_lease_update(struct sys_lease_context *ctx, + struct opendb_entry *e) +{ + struct linux_lease_pending *c; + + for (c = leases; c; c = c->next) { + if (c->e.fd == e->fd) { + break; + } + } + + if (!c) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + /* + * set the fd pointer to NULL so that the caller + * will not call the remove function as the oplock + * is already removed + */ + e->fd = NULL; + + talloc_free(c); + + return NT_STATUS_OK; +} + +static NTSTATUS linux_lease_remove(struct sys_lease_context *ctx, + struct opendb_entry *e) +{ + struct linux_lease_pending *c; + + for (c = leases; c; c = c->next) { + if (c->e.fd == e->fd) { + break; + } + } + + if (!c) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + talloc_free(c); + + return NT_STATUS_OK; +} + +static struct sys_lease_ops linux_lease_ops = { + .name = "linux", + .init = linux_lease_init, + .setup = linux_lease_setup, + .update = linux_lease_update, + .remove = linux_lease_remove +}; + +/* + initialialise the linux lease module + */ +NTSTATUS sys_lease_linux_init(void) +{ + /* register ourselves as a system lease module */ + return sys_lease_register(&linux_lease_ops); +} -- cgit From 49c86b73bf1babf151835d4afdbfb132f2e2c34e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 7 Mar 2008 12:21:11 +0100 Subject: opendb_tdb: use sys_lease to setup kernel oplocks metze (This used to be commit e473068bddfaa9028ab8ee49291035313b35fed3) --- source4/ntvfs/common/config.mk | 5 ++++- source4/ntvfs/common/opendb_tdb.c | 46 ++++++++++++++++++++++++++++++++------- 2 files changed, 42 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 2fc0942ed4..3963ebcdee 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -9,7 +9,10 @@ OBJ_FILES = \ opendb.o \ opendb_tdb.o \ notify.o -PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify share LIBDBWRAP +PUBLIC_DEPENDENCIES = \ + NDR_OPENDB NDR_NOTIFY \ + sys_notify sys_lease \ + share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 9b4a5bfa9f..be78e09958 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -49,11 +49,13 @@ #include "ntvfs/common/ntvfs_common.h" #include "cluster/cluster.h" #include "param/param.h" +#include "ntvfs/sysdep/sys_lease.h" struct odb_context { struct tdb_wrap *w; struct ntvfs_context *ntvfs_ctx; bool oplocks; + struct sys_lease_context *lease_ctx; }; /* @@ -72,6 +74,10 @@ struct odb_lock { } can_open; }; +static NTSTATUS odb_oplock_break_send(struct messaging_context *msg_ctx, + struct opendb_entry *e, + uint8_t level); + /* Open up the openfiles.tdb database. Close it down using talloc_free(). We need the messaging_ctx to allow for pending open @@ -98,6 +104,11 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, /* leave oplocks disabled by default until the code is working */ odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", false); + odb->lease_ctx = sys_lease_context_create(ntvfs_ctx->config, odb, + ntvfs_ctx->event_ctx, + ntvfs_ctx->msg_ctx, + odb_oplock_break_send); + return odb; } @@ -491,23 +502,29 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, oplock_level = OPLOCK_NONE; } + lck->can_open.e->file_handle = file_handle; + lck->can_open.e->fd = fd; + lck->can_open.e->allow_level_II_oplock = allow_level_II_oplock; + lck->can_open.e->oplock_level = oplock_level; + + if (odb->lease_ctx && fd) { + NTSTATUS status; + status = sys_lease_setup(odb->lease_ctx, lck->can_open.e); + NT_STATUS_NOT_OK_RETURN(status); + } + if (oplock_granted) { - if (oplock_level == OPLOCK_EXCLUSIVE) { + if (lck->can_open.e->oplock_level == OPLOCK_EXCLUSIVE) { *oplock_granted = EXCLUSIVE_OPLOCK_RETURN; - } else if (oplock_level == OPLOCK_BATCH) { + } else if (lck->can_open.e->oplock_level == OPLOCK_BATCH) { *oplock_granted = BATCH_OPLOCK_RETURN; - } else if (oplock_level == OPLOCK_LEVEL_II) { + } else if (lck->can_open.e->oplock_level == OPLOCK_LEVEL_II) { *oplock_granted = LEVEL_II_OPLOCK_RETURN; } else { *oplock_granted = NO_OPLOCK_RETURN; } } - lck->can_open.e->file_handle = file_handle; - lck->can_open.e->fd = fd; - lck->can_open.e->allow_level_II_oplock = allow_level_II_oplock; - lck->can_open.e->oplock_level = oplock_level; - /* it doesn't conflict, so add it to the end */ lck->file.entries = talloc_realloc(lck, lck->file.entries, struct opendb_entry, @@ -570,6 +587,11 @@ static NTSTATUS odb_tdb_close_file(struct odb_lock *lck, void *file_handle, if (lck->file.entries[i].delete_on_close) { lck->file.delete_on_close = true; } + if (odb->lease_ctx && lck->file.entries[i].fd) { + NTSTATUS status; + status = sys_lease_remove(odb->lease_ctx, &lck->file.entries[i]); + NT_STATUS_NOT_OK_RETURN(status); + } if (i < lck->file.num_entries-1) { memmove(lck->file.entries+i, lck->file.entries+i+1, (lck->file.num_entries - (i+1)) * @@ -623,6 +645,13 @@ static NTSTATUS odb_tdb_update_oplock(struct odb_lock *lck, void *file_handle, if (file_handle == lck->file.entries[i].file_handle && cluster_id_equal(&odb->ntvfs_ctx->server_id, &lck->file.entries[i].server)) { lck->file.entries[i].oplock_level = oplock_level; + + if (odb->lease_ctx && lck->file.entries[i].fd) { + NTSTATUS status; + status = sys_lease_update(odb->lease_ctx, &lck->file.entries[i]); + NT_STATUS_NOT_OK_RETURN(status); + } + break; } } @@ -833,5 +862,6 @@ static const struct opendb_ops opendb_tdb_ops = { void odb_tdb_init_ops(void) { + sys_lease_init(); odb_set_ops(&opendb_tdb_ops); } -- cgit From 454e9bed04011bcb184f20c2dd82f37255403227 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 10 Mar 2008 12:48:02 +0100 Subject: pvfs_open: pass O_NONBLOCK to open() so that we'll not block with kernel oplocks metze (This used to be commit eeb0b8c349552517b521f1b8d7d9341e0ef630f2) --- source4/ntvfs/posix/pvfs_open.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index ceda3a6da0..8a949daa87 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -600,7 +600,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, mode = pvfs_fileperms(pvfs, attrib); /* create the file */ - fd = open(name->full_name, flags | O_CREAT | O_EXCL, mode); + fd = open(name->full_name, flags | O_CREAT | O_EXCL| O_NONBLOCK, mode); if (fd == -1) { return pvfs_map_errno(pvfs, errno); } @@ -1303,7 +1303,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* do the actual open */ - fd = open(f->handle->name->full_name, flags); + fd = open(f->handle->name->full_name, flags | O_NONBLOCK); if (fd == -1) { talloc_free(lck); return pvfs_map_errno(f->pvfs, errno); -- cgit From 50243cdbbda8a1f14e56c684281a93614aab0103 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 12 Mar 2008 14:02:11 +0100 Subject: pvfs_open: retry pvfs_open() after an EGAIN or EWOULDBLOCK from open() In case a unix application as an oplock or share mode on a file we need to retry periodicly as there's no way to get a notification from the kernel when the oplock is released. metze (This used to be commit 4d40f3a02643b4cdacee31f0b7bc9fc77cc9869a) --- source4/ntvfs/posix/pvfs_open.c | 58 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 8a949daa87..1399f120a7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -858,7 +858,13 @@ NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs, /* setup a pending lock */ status = odb_open_file_pending(lck, r); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_NOT_FOUND,status)) { + /* + * maybe only a unix application + * has the file open + */ + data_blob_free(&r->odb_locking_key); + } else if (!NT_STATUS_IS_OK(status)) { return status; } @@ -891,8 +897,14 @@ static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r, enum pvfs_wait_notice reason) { union smb_open *io = talloc_get_type(_io, union smb_open); + struct timeval *final_timeout = NULL; NTSTATUS status; + if (private_data) { + final_timeout = talloc_get_type(private_data, + struct timeval); + } + /* w2k3 ignores SMBntcancel for outstanding open requests. It's probably just a bug in their server, but we better do the same */ if (reason == PVFS_WAIT_CANCEL) { @@ -900,6 +912,16 @@ static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r, } if (reason == PVFS_WAIT_TIMEOUT) { + if (final_timeout && + !timeval_expired(final_timeout)) { + /* + * we need to retry periodictly + * after an EAGAIN as there's + * no way the kernel tell us + * an oplock is released. + */ + goto retry; + } /* if it timed out, then give the failure immediately */ talloc_free(r); @@ -908,6 +930,7 @@ static void pvfs_retry_open_sharing(struct pvfs_odb_retry *r, return; } +retry: talloc_free(r); /* try the open again, which could trigger another retry setup @@ -1027,6 +1050,7 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, struct pvfs_state *pvfs = ntvfs->private_data; NTSTATUS status; struct timeval end_time; + struct timeval *final_timeout = NULL; if (io->generic.in.create_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS | NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) { @@ -1047,12 +1071,28 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs, } else if (NT_STATUS_EQUAL(parent_status, NT_STATUS_OPLOCK_NOT_GRANTED)) { end_time = timeval_add(&req->statistics.request_time, pvfs->oplock_break_timeout, 0); + } else if (NT_STATUS_EQUAL(parent_status, STATUS_MORE_ENTRIES)) { + /* + * we got EAGAIN which means a unix application + * has an oplock or share mode + * + * we retry every 4/5 of the sharing violation delay + * to see if the unix application + * has released the oplock or share mode. + */ + final_timeout = talloc(req, struct timeval); + NT_STATUS_HAVE_NO_MEMORY(final_timeout); + *final_timeout = timeval_add(&req->statistics.request_time, + pvfs->oplock_break_timeout, + 0); + end_time = timeval_current_ofs(0, (pvfs->sharing_violation_delay*4)/5); + end_time = timeval_min(final_timeout, &end_time); } else { return NT_STATUS_INTERNAL_ERROR; } - return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, NULL, - pvfs_retry_open_sharing); + return pvfs_odb_retry_setup(ntvfs, req, lck, end_time, io, + final_timeout, pvfs_retry_open_sharing); } /* @@ -1305,8 +1345,18 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* do the actual open */ fd = open(f->handle->name->full_name, flags | O_NONBLOCK); if (fd == -1) { + status = pvfs_map_errno(f->pvfs, errno); + + /* + * STATUS_MORE_ENTRIES is EAGAIN or EWOULDBLOCK + */ + if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && + (req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return pvfs_open_setup_retry(ntvfs, req, io, f, lck, status); + } + talloc_free(lck); - return pvfs_map_errno(f->pvfs, errno); + return status; } f->handle->fd = fd; -- cgit From 1f65ddb33678e44fe6f6d10af42842f11bd10cc5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 15 Mar 2008 12:22:36 +0100 Subject: pvfs_unlink: disable async retries for wildcard deletes We would setup multiple retries per client request. metze (This used to be commit 951764e28407a53ea4dd39d34388fab1b2259785) --- source4/ntvfs/posix/pvfs_unlink.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 7a2d964b9d..4cb47a4f1f 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -219,6 +219,12 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, return pvfs_unlink_one(pvfs, req, unl, name); } + /* + * disable async requests in the wildcard case + * untill we have proper tests for this + */ + req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC; + /* get list of matching files */ status = pvfs_list_start(pvfs, name, req, &dir); if (!NT_STATUS_IS_OK(status)) { -- cgit From 74d940ca5742a021a01e8820be40a69366f67ee6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 15 Mar 2008 12:35:04 +0100 Subject: pvfs_open: the pvfs_odb_retry structs need to be children of the request Otherwise they're not cleaned up when the request is finished. metze (This used to be commit 055760f0f4aadd2079b0a4999b59ac3dbe5edf8a) --- source4/ntvfs/posix/pvfs_open.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 1399f120a7..d1cb0eb603 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -881,8 +881,6 @@ NTSTATUS pvfs_odb_retry_setup(struct ntvfs_module_context *ntvfs, talloc_steal(r, wait_handle); - talloc_steal(pvfs, r); - return NT_STATUS_OK; } -- cgit From e76c8aa097d9865f97b254be7477f2097ea86e7d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 15 Mar 2008 12:36:20 +0100 Subject: pvfs_open: set h->have_opendb_entry directly after odb_open_file() Otherwise we may not clean up in the destructor. metze (This used to be commit 218ec98a1694080748d1ac12baa90ffcda364833) --- source4/ntvfs/posix/pvfs_open.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index d1cb0eb603..6e77cb7c75 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1369,6 +1369,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + f->handle->have_opendb_entry = true; + if (pvfs->flags & PVFS_FLAG_FAKE_OPLOCKS) { oplock_granted = OPLOCK_BATCH; } else if (oplock_granted != OPLOCK_NONE) { @@ -1379,8 +1381,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } } - f->handle->have_opendb_entry = true; - stream_existed = name->stream_exists; /* if this was a stream create then create the stream as well */ -- cgit From 71e2f7d2604932805762a841318cacc54cbc0b1c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 27 Mar 2008 10:11:48 +0100 Subject: opendb_tdb: enable oplocks per default metze (This used to be commit 225a9852eeee66f22a4135a660f18b70666c1c5f) --- source4/ntvfs/common/opendb_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index be78e09958..fc05b342a8 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -102,7 +102,7 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, odb->ntvfs_ctx = ntvfs_ctx; /* leave oplocks disabled by default until the code is working */ - odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", false); + odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", true); odb->lease_ctx = sys_lease_context_create(ntvfs_ctx->config, odb, ntvfs_ctx->event_ctx, -- cgit From 4fc27c9969960dfef73ad80438d274e0f45e119e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Mar 2008 20:32:02 +1100 Subject: Make oplocks a per-share option. This even goes via the share options system (a very odd layer of indirection). Andrew Bartlett (This used to be commit f2c65f9907760b8852b70c53637388f08751ba88) --- source4/ntvfs/common/opendb_tdb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index be78e09958..40a1d27f30 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -101,8 +101,7 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, odb->ntvfs_ctx = ntvfs_ctx; - /* leave oplocks disabled by default until the code is working */ - odb->oplocks = lp_parm_bool(ntvfs_ctx->lp_ctx, NULL, "opendb", "oplocks", false); + odb->oplocks = share_bool_option(ntvfs_ctx->ctx->config, SHARE_OPLOCKS, SHARE_OPLOCKS_DEFAULT); odb->lease_ctx = sys_lease_context_create(ntvfs_ctx->config, odb, ntvfs_ctx->event_ctx, -- cgit From 7f2927528c230c9e44634d1aa4fb677596603056 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Mar 2008 20:40:40 +1100 Subject: Fix references to ntvfs share config Andrew Bartlett (This used to be commit 4e4152dfd70145a7a00bc42effcd07b607204926) --- source4/ntvfs/common/opendb_tdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 40a1d27f30..99c0a95c20 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -101,7 +101,7 @@ static struct odb_context *odb_tdb_init(TALLOC_CTX *mem_ctx, odb->ntvfs_ctx = ntvfs_ctx; - odb->oplocks = share_bool_option(ntvfs_ctx->ctx->config, SHARE_OPLOCKS, SHARE_OPLOCKS_DEFAULT); + odb->oplocks = share_bool_option(ntvfs_ctx->config, SHARE_OPLOCKS, SHARE_OPLOCKS_DEFAULT); odb->lease_ctx = sys_lease_context_create(ntvfs_ctx->config, odb, ntvfs_ctx->event_ctx, -- cgit From afe3e8172ddaa5e4aa811faceecda4f943d6e2ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 04:53:27 +0200 Subject: Install public header files again and include required prototypes. (This used to be commit 47ffbbf67435904754469544390b67d34c958343) --- source4/ntvfs/cifs/vfs_cifs.c | 1 + source4/ntvfs/common/init.c | 2 +- source4/ntvfs/common/opendb.c | 28 ++++---- source4/ntvfs/ntvfs_base.c | 8 +-- source4/ntvfs/ntvfs_generic.c | 20 +++--- source4/ntvfs/ntvfs_interface.c | 138 +++++++++++++++++++-------------------- source4/ntvfs/ntvfs_util.c | 20 +++--- source4/ntvfs/posix/pvfs_acl.c | 4 +- source4/ntvfs/posix/pvfs_xattr.c | 4 +- 9 files changed, 113 insertions(+), 112 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 3c090b5f5c..2feb1a0efe 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -26,6 +26,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" #include "libcli/smb_composite/smb_composite.h" #include "auth/auth.h" #include "auth/credentials/credentials.h" diff --git a/source4/ntvfs/common/init.c b/source4/ntvfs/common/init.c index 1889bef23d..e0f5a9d2aa 100644 --- a/source4/ntvfs/common/init.c +++ b/source4/ntvfs/common/init.c @@ -26,7 +26,7 @@ #include "includes.h" #include "ntvfs/sysdep/sys_notify.h" -_PUBLIC_ NTSTATUS ntvfs_common_init(void) +NTSTATUS ntvfs_common_init(void) { return sys_notify_init(); } diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 676706e03f..2913ea8431 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -58,7 +58,7 @@ void odb_set_ops(const struct opendb_ops *new_ops) talloc_free(). We need the messaging_ctx to allow for pending open notifications. */ -_PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, +struct odb_context *odb_init(TALLOC_CTX *mem_ctx, struct ntvfs_context *ntvfs_ctx) { if (ops == NULL) { @@ -75,13 +75,13 @@ _PUBLIC_ struct odb_context *odb_init(TALLOC_CTX *mem_ctx, get a lock on a entry in the odb. This call returns a lock handle, which the caller should unlock using talloc_free(). */ -_PUBLIC_ struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, +struct odb_lock *odb_lock(TALLOC_CTX *mem_ctx, struct odb_context *odb, DATA_BLOB *file_key) { return ops->odb_lock(mem_ctx, odb, file_key); } -_PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) +DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) { return ops->odb_get_key(mem_ctx, lck); } @@ -95,7 +95,7 @@ _PUBLIC_ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) Note that the path is only used by the delete on close logic, not for comparing with other filenames */ -_PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, +NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, const char *path, int *fd, bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) @@ -109,7 +109,7 @@ _PUBLIC_ NTSTATUS odb_open_file(struct odb_lock *lck, /* register a pending open file in the open files database */ -_PUBLIC_ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) +NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) { return ops->odb_open_file_pending(lck, private); } @@ -118,7 +118,7 @@ _PUBLIC_ NTSTATUS odb_open_file_pending(struct odb_lock *lck, void *private) /* remove a opendb entry */ -_PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle, +NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle, const char **delete_path) { return ops->odb_close_file(lck, file_handle, delete_path); @@ -128,7 +128,7 @@ _PUBLIC_ NTSTATUS odb_close_file(struct odb_lock *lck, void *file_handle, /* remove a pending opendb entry */ -_PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) +NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) { return ops->odb_remove_pending(lck, private); } @@ -137,7 +137,7 @@ _PUBLIC_ NTSTATUS odb_remove_pending(struct odb_lock *lck, void *private) /* rename the path in a open file */ -_PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) +NTSTATUS odb_rename(struct odb_lock *lck, const char *path) { return ops->odb_rename(lck, path); } @@ -145,7 +145,7 @@ _PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path) /* get back the path of an open file */ -_PUBLIC_ NTSTATUS odb_get_path(struct odb_lock *lck, const char **path) +NTSTATUS odb_get_path(struct odb_lock *lck, const char **path) { return ops->odb_get_path(lck, path); } @@ -153,7 +153,7 @@ _PUBLIC_ NTSTATUS odb_get_path(struct odb_lock *lck, const char **path) /* update delete on close flag on an open file */ -_PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_close) +NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_close) { return ops->odb_set_delete_on_close(lck, del_on_close); } @@ -162,7 +162,7 @@ _PUBLIC_ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_clos return the current value of the delete_on_close bit, and how many people still have the file open */ -_PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, +NTSTATUS odb_get_delete_on_close(struct odb_context *odb, DATA_BLOB *key, bool *del_on_close) { return ops->odb_get_delete_on_close(odb, key, del_on_close); @@ -173,7 +173,7 @@ _PUBLIC_ NTSTATUS odb_get_delete_on_close(struct odb_context *odb, determine if a file can be opened with the given share_access, create_options and access_mask */ -_PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, +NTSTATUS odb_can_open(struct odb_lock *lck, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, uint32_t open_disposition, bool break_to_none) @@ -182,13 +182,13 @@ _PUBLIC_ NTSTATUS odb_can_open(struct odb_lock *lck, delete_on_close, open_disposition, break_to_none); } -_PUBLIC_ NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle, +NTSTATUS odb_update_oplock(struct odb_lock *lck, void *file_handle, uint32_t oplock_level) { return ops->odb_update_oplock(lck, file_handle, oplock_level); } -_PUBLIC_ NTSTATUS odb_break_oplocks(struct odb_lock *lck) +NTSTATUS odb_break_oplocks(struct odb_lock *lck) { return ops->odb_break_oplocks(lck); } diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 35becabcf9..51faa44372 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -44,7 +44,7 @@ static int num_backends; The 'type' is used to specify whether this is for a disk, printer or IPC$ share */ -_PUBLIC_ NTSTATUS ntvfs_register(const struct ntvfs_ops *ops, +NTSTATUS ntvfs_register(const struct ntvfs_ops *ops, const struct ntvfs_critical_sizes *const sizes) { struct ntvfs_ops *new_ops; @@ -85,7 +85,7 @@ _PUBLIC_ NTSTATUS ntvfs_register(const struct ntvfs_ops *ops, /* return the operations structure for a named backend of the specified type */ -_PUBLIC_ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) +const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntvfs_type type) { int i; @@ -108,12 +108,12 @@ _PUBLIC_ const struct ntvfs_ops *ntvfs_backend_byname(const char *name, enum ntv static const NTVFS_CURRENT_CRITICAL_SIZES(critical_sizes); -_PUBLIC_ const struct ntvfs_critical_sizes *ntvfs_interface_version(void) +const struct ntvfs_critical_sizes *ntvfs_interface_version(void) { return &critical_sizes; } -_PUBLIC_ bool ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) +bool ntvfs_interface_differs(const struct ntvfs_critical_sizes *const iface) { /* The comparison would be easier with memcmp, but compiler-interset * alignment padding is not guaranteed to be zeroed. diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 5092e732b4..e1a86c07c0 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -361,7 +361,7 @@ static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, /* NTVFS open generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io) { @@ -512,7 +512,7 @@ done: /* NTVFS fsinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs) { @@ -641,7 +641,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_fsinfo(struct ntvfs_module_context *ntvfs, /* NTVFS fileinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, +NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, union smb_fileinfo *info, union smb_fileinfo *info2) { @@ -872,7 +872,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_fileinfo(TALLOC_CTX *mem_ctx, /* NTVFS fileinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { @@ -905,7 +905,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_qfileinfo(struct ntvfs_module_context *ntvfs, /* NTVFS pathinfo generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { @@ -939,7 +939,7 @@ _PUBLIC_ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs, /* NTVFS lock generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lock *lck) { @@ -1114,7 +1114,7 @@ static NTSTATUS ntvfs_map_write_finish(struct ntvfs_module_context *ntvfs, /* NTVFS write generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *wr) { @@ -1226,7 +1226,7 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, /* NTVFS read* to readx mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_read *rd) { @@ -1322,7 +1322,7 @@ done: /* NTVFS close generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_close *cl) { @@ -1391,7 +1391,7 @@ static NTSTATUS ntvfs_map_notify_finish(struct ntvfs_module_context *ntvfs, /* NTVFS notify generic to any mapper */ -_PUBLIC_ NTSTATUS ntvfs_map_notify(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_map_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_notify *nt) { diff --git a/source4/ntvfs/ntvfs_interface.c b/source4/ntvfs/ntvfs_interface.c index 3bd2859388..c348558fca 100644 --- a/source4/ntvfs/ntvfs_interface.c +++ b/source4/ntvfs/ntvfs_interface.c @@ -22,7 +22,7 @@ #include "ntvfs/ntvfs.h" /* connect/disconnect */ -_PUBLIC_ NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename) +NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->connect) { @@ -31,7 +31,7 @@ _PUBLIC_ NTSTATUS ntvfs_connect(struct ntvfs_request *req, const char *sharename return ntvfs->ops->connect(ntvfs, req, sharename); } -_PUBLIC_ NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx) +NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx) { struct ntvfs_module_context *ntvfs; if (ntvfs_ctx == NULL) { @@ -46,7 +46,7 @@ _PUBLIC_ NTSTATUS ntvfs_disconnect(struct ntvfs_context *ntvfs_ctx) /* async setup - called by a backend that wants to setup any state for a async request */ -_PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) +NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->async_setup) { @@ -56,7 +56,7 @@ _PUBLIC_ NTSTATUS ntvfs_async_setup(struct ntvfs_request *req, void *private) } /* filesystem operations */ -_PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) +NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->fsinfo) { @@ -66,7 +66,7 @@ _PUBLIC_ NTSTATUS ntvfs_fsinfo(struct ntvfs_request *req, union smb_fsinfo *fs) } /* path operations */ -_PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) +NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->unlink) { @@ -75,7 +75,7 @@ _PUBLIC_ NTSTATUS ntvfs_unlink(struct ntvfs_request *req, union smb_unlink *unl) return ntvfs->ops->unlink(ntvfs, req, unl); } -_PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp) +NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->chkpath) { @@ -84,7 +84,7 @@ _PUBLIC_ NTSTATUS ntvfs_chkpath(struct ntvfs_request *req, union smb_chkpath *cp return ntvfs->ops->chkpath(ntvfs, req, cp); } -_PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo *st) +NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo *st) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->qpathinfo) { @@ -93,7 +93,7 @@ _PUBLIC_ NTSTATUS ntvfs_qpathinfo(struct ntvfs_request *req, union smb_fileinfo return ntvfs->ops->qpathinfo(ntvfs, req, st); } -_PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfileinfo *st) +NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfileinfo *st) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->setpathinfo) { @@ -102,7 +102,7 @@ _PUBLIC_ NTSTATUS ntvfs_setpathinfo(struct ntvfs_request *req, union smb_setfile return ntvfs->ops->setpathinfo(ntvfs, req, st); } -_PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) +NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->open) { @@ -111,7 +111,7 @@ _PUBLIC_ NTSTATUS ntvfs_open(struct ntvfs_request *req, union smb_open *oi) return ntvfs->ops->open(ntvfs, req, oi); } -_PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) +NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->mkdir) { @@ -120,7 +120,7 @@ _PUBLIC_ NTSTATUS ntvfs_mkdir(struct ntvfs_request *req, union smb_mkdir *md) return ntvfs->ops->mkdir(ntvfs, req, md); } -_PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) +NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->rmdir) { @@ -129,7 +129,7 @@ _PUBLIC_ NTSTATUS ntvfs_rmdir(struct ntvfs_request *req, struct smb_rmdir *rd) return ntvfs->ops->rmdir(ntvfs, req, rd); } -_PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) +NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->rename) { @@ -138,7 +138,7 @@ _PUBLIC_ NTSTATUS ntvfs_rename(struct ntvfs_request *req, union smb_rename *ren) return ntvfs->ops->rename(ntvfs, req, ren); } -_PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) +NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->copy) { @@ -148,7 +148,7 @@ _PUBLIC_ NTSTATUS ntvfs_copy(struct ntvfs_request *req, struct smb_copy *cp) } /* directory search */ -_PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private, +NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search_first *io, void *private, bool ntvfs_callback(void *private, const union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->ctx->modules; @@ -158,7 +158,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_first(struct ntvfs_request *req, union smb_search return ntvfs->ops->search_first(ntvfs, req, io, private, ntvfs_callback); } -_PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private, +NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_next *io, void *private, bool ntvfs_callback(void *private, const union smb_search_data *file)) { struct ntvfs_module_context *ntvfs = req->ctx->modules; @@ -168,7 +168,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_next(struct ntvfs_request *req, union smb_search_ return ntvfs->ops->search_next(ntvfs, req, io, private, ntvfs_callback); } -_PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search_close *io) +NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search_close *io) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->search_close) { @@ -178,7 +178,7 @@ _PUBLIC_ NTSTATUS ntvfs_search_close(struct ntvfs_request *req, union smb_search } /* operations on open files */ -_PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) +NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->ioctl) { @@ -187,7 +187,7 @@ _PUBLIC_ NTSTATUS ntvfs_ioctl(struct ntvfs_request *req, union smb_ioctl *io) return ntvfs->ops->ioctl(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) +NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->read) { @@ -196,7 +196,7 @@ _PUBLIC_ NTSTATUS ntvfs_read(struct ntvfs_request *req, union smb_read *io) return ntvfs->ops->read(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) +NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->write) { @@ -205,7 +205,7 @@ _PUBLIC_ NTSTATUS ntvfs_write(struct ntvfs_request *req, union smb_write *io) return ntvfs->ops->write(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) +NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->seek) { @@ -214,7 +214,7 @@ _PUBLIC_ NTSTATUS ntvfs_seek(struct ntvfs_request *req, union smb_seek *io) return ntvfs->ops->seek(ntvfs, req, io); } -_PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, +NTSTATUS ntvfs_flush(struct ntvfs_request *req, union smb_flush *flush) { struct ntvfs_module_context *ntvfs = req->ctx->modules; @@ -224,7 +224,7 @@ _PUBLIC_ NTSTATUS ntvfs_flush(struct ntvfs_request *req, return ntvfs->ops->flush(ntvfs, req, flush); } -_PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) +NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->lock) { @@ -233,7 +233,7 @@ _PUBLIC_ NTSTATUS ntvfs_lock(struct ntvfs_request *req, union smb_lock *lck) return ntvfs->ops->lock(ntvfs, req, lck); } -_PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo *info) +NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo *info) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->qfileinfo) { @@ -242,7 +242,7 @@ _PUBLIC_ NTSTATUS ntvfs_qfileinfo(struct ntvfs_request *req, union smb_fileinfo return ntvfs->ops->qfileinfo(ntvfs, req, info); } -_PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfileinfo *info) +NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfileinfo *info) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->setfileinfo) { @@ -251,7 +251,7 @@ _PUBLIC_ NTSTATUS ntvfs_setfileinfo(struct ntvfs_request *req, union smb_setfile return ntvfs->ops->setfileinfo(ntvfs, req, info); } -_PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) +NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->close) { @@ -261,7 +261,7 @@ _PUBLIC_ NTSTATUS ntvfs_close(struct ntvfs_request *req, union smb_close *io) } /* trans interface - used by IPC backend for pipes and RAP calls */ -_PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *trans) +NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *trans) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->trans) { @@ -271,7 +271,7 @@ _PUBLIC_ NTSTATUS ntvfs_trans(struct ntvfs_request *req, struct smb_trans2 *tran } /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ -_PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *trans2) +NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *trans2) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->trans2) { @@ -281,7 +281,7 @@ _PUBLIC_ NTSTATUS ntvfs_trans2(struct ntvfs_request *req, struct smb_trans2 *tra } /* printing specific operations */ -_PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) +NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->lpq) { @@ -291,7 +291,7 @@ _PUBLIC_ NTSTATUS ntvfs_lpq(struct ntvfs_request *req, union smb_lpq *lpq) } /* logoff - called when a vuid is closed */ -_PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req) +NTSTATUS ntvfs_logoff(struct ntvfs_request *req) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->logoff) { @@ -300,7 +300,7 @@ _PUBLIC_ NTSTATUS ntvfs_logoff(struct ntvfs_request *req) return ntvfs->ops->logoff(ntvfs, req); } -_PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) +NTSTATUS ntvfs_exit(struct ntvfs_request *req) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->exit) { @@ -312,7 +312,7 @@ _PUBLIC_ NTSTATUS ntvfs_exit(struct ntvfs_request *req) /* change notify request */ -_PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) +NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->notify) { @@ -324,7 +324,7 @@ _PUBLIC_ NTSTATUS ntvfs_notify(struct ntvfs_request *req, union smb_notify *info /* cancel an outstanding async request */ -_PUBLIC_ NTSTATUS ntvfs_cancel(struct ntvfs_request *req) +NTSTATUS ntvfs_cancel(struct ntvfs_request *req) { struct ntvfs_module_context *ntvfs = req->ctx->modules; if (!ntvfs->ops->cancel) { @@ -334,7 +334,7 @@ _PUBLIC_ NTSTATUS ntvfs_cancel(struct ntvfs_request *req) } /* initial setup */ -_PUBLIC_ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const char *sharename) { if (!ntvfs->next || !ntvfs->next->ops->connect) { @@ -343,7 +343,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_connect(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->connect(ntvfs->next, req, sharename); } -_PUBLIC_ NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs) +NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs) { if (!ntvfs->next || !ntvfs->next->ops->disconnect) { return NT_STATUS_NOT_IMPLEMENTED; @@ -352,7 +352,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_disconnect(struct ntvfs_module_context *ntvfs) } /* async_setup - called when setting up for a async request */ -_PUBLIC_ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, void *private) { @@ -363,7 +363,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_async_setup(struct ntvfs_module_context *ntvfs, } /* filesystem operations */ -_PUBLIC_ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs) { @@ -374,7 +374,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_fsinfo(struct ntvfs_module_context *ntvfs, } /* path operations */ -_PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_unlink *unl) { @@ -384,7 +384,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_unlink(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->unlink(ntvfs->next, req, unl); } -_PUBLIC_ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_chkpath *cp) { @@ -394,7 +394,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_chkpath(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->chkpath(ntvfs->next, req, cp); } -_PUBLIC_ NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *st) { @@ -404,7 +404,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_qpathinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->qpathinfo(ntvfs->next, req, st); } -_PUBLIC_ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *st) { @@ -414,7 +414,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_setpathinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->setpathinfo(ntvfs->next, req, st); } -_PUBLIC_ NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_mkdir *md) { @@ -424,7 +424,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_mkdir(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->mkdir(ntvfs->next, req, md); } -_PUBLIC_ NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_rmdir *rd) { @@ -434,7 +434,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_rmdir(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->rmdir(ntvfs->next, req, rd); } -_PUBLIC_ NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_rename *ren) { @@ -444,7 +444,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_rename(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->rename(ntvfs->next, req, ren); } -_PUBLIC_ NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_copy *cp) { @@ -454,7 +454,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_copy(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->copy(ntvfs->next, req, cp); } -_PUBLIC_ NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *oi) { @@ -466,7 +466,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_open(struct ntvfs_module_context *ntvfs, /* directory search */ -_PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_first *io, void *private, bool (*callback)(void *private, const union smb_search_data *file)) @@ -477,7 +477,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_first(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->search_first(ntvfs->next, req, io, private, callback); } -_PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_next *io, void *private, bool (*callback)(void *private, const union smb_search_data *file)) @@ -488,7 +488,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_next(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->search_next(ntvfs->next, req, io, private, callback); } -_PUBLIC_ NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io) { @@ -499,7 +499,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_search_close(struct ntvfs_module_context *ntvfs, } /* operations on open files */ -_PUBLIC_ NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_ioctl *io) { @@ -509,7 +509,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_ioctl(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->ioctl(ntvfs->next, req, io); } -_PUBLIC_ NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_read *io) { @@ -519,7 +519,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_read(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->read(ntvfs->next, req, io); } -_PUBLIC_ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *io) { @@ -529,7 +529,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_write(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->write(ntvfs->next, req, io); } -_PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_seek *io) { @@ -539,7 +539,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_seek(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->seek(ntvfs->next, req, io); } -_PUBLIC_ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_flush *flush) { @@ -549,7 +549,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_flush(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->flush(ntvfs->next, req, flush); } -_PUBLIC_ NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lock *lck) { @@ -559,7 +559,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_lock(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->lock(ntvfs->next, req, lck); } -_PUBLIC_ NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { @@ -569,7 +569,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_qfileinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->qfileinfo(ntvfs->next, req, info); } -_PUBLIC_ NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *info) { @@ -579,7 +579,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_setfileinfo(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->setfileinfo(ntvfs->next, req, info); } -_PUBLIC_ NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_close *io) { @@ -590,7 +590,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_close(struct ntvfs_module_context *ntvfs, } /* trans interface - used by IPC backend for pipes and RAP calls */ -_PUBLIC_ NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_trans2 *trans) { @@ -601,7 +601,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_trans(struct ntvfs_module_context *ntvfs, } /* trans2 interface - only used by CIFS backend to prover complete passthru for testing */ -_PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_trans2 *trans2) { @@ -614,7 +614,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_trans2(struct ntvfs_module_context *ntvfs, /* change notify request */ -_PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_notify *info) { @@ -625,7 +625,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_notify(struct ntvfs_module_context *ntvfs, } /* cancel - called to cancel an outstanding async request */ -_PUBLIC_ NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { if (!ntvfs->next || !ntvfs->next->ops->cancel) { @@ -635,7 +635,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_cancel(struct ntvfs_module_context *ntvfs, } /* printing specific operations */ -_PUBLIC_ NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lpq *lpq) { @@ -647,7 +647,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_lpq(struct ntvfs_module_context *ntvfs, /* logoff - called when a vuid is closed */ -_PUBLIC_ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { if (!ntvfs->next || !ntvfs->next->ops->logoff) { @@ -656,7 +656,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_logoff(struct ntvfs_module_context *ntvfs, return ntvfs->next->ops->logoff(ntvfs->next, req); } -_PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { if (!ntvfs->next || !ntvfs->next->ops->exit) { @@ -666,7 +666,7 @@ _PUBLIC_ NTSTATUS ntvfs_next_exit(struct ntvfs_module_context *ntvfs, } /* oplock helpers */ -_PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs, +NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs, NTSTATUS (*handler)(void *private_data, struct ntvfs_handle *handle, uint8_t level), void *private_data) { @@ -675,7 +675,7 @@ _PUBLIC_ NTSTATUS ntvfs_set_oplock_handler(struct ntvfs_context *ntvfs, return NT_STATUS_OK; } -_PUBLIC_ NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs, struct ntvfs_handle *handle, uint8_t level) { if (!ntvfs->ctx->oplock.handler) { @@ -686,7 +686,7 @@ _PUBLIC_ NTSTATUS ntvfs_send_oplock_break(struct ntvfs_module_context *ntvfs, } /* client connection callback */ -_PUBLIC_ NTSTATUS ntvfs_set_addr_callbacks(struct ntvfs_context *ntvfs, +NTSTATUS ntvfs_set_addr_callbacks(struct ntvfs_context *ntvfs, struct socket_address *(*my_addr)(void *private_data, TALLOC_CTX *mem_ctx), struct socket_address *(*peer_addr)(void *private_data, TALLOC_CTX *mem_ctx), void *private_data) @@ -697,7 +697,7 @@ _PUBLIC_ NTSTATUS ntvfs_set_addr_callbacks(struct ntvfs_context *ntvfs, return NT_STATUS_OK; } -_PUBLIC_ struct socket_address *ntvfs_get_my_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx) +struct socket_address *ntvfs_get_my_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx) { if (!ntvfs->ctx->client.get_my_addr) { return NULL; @@ -706,7 +706,7 @@ _PUBLIC_ struct socket_address *ntvfs_get_my_addr(struct ntvfs_module_context *n return ntvfs->ctx->client.get_my_addr(ntvfs->ctx->client.private_data, mem_ctx); } -_PUBLIC_ struct socket_address *ntvfs_get_peer_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx) +struct socket_address *ntvfs_get_peer_addr(struct ntvfs_module_context *ntvfs, TALLOC_CTX *mem_ctx) { if (!ntvfs->ctx->client.get_peer_addr) { return NULL; diff --git a/source4/ntvfs/ntvfs_util.c b/source4/ntvfs/ntvfs_util.c index ebe8008edd..fadbe2b80a 100644 --- a/source4/ntvfs/ntvfs_util.c +++ b/source4/ntvfs/ntvfs_util.c @@ -25,7 +25,7 @@ #include "ntvfs/ntvfs.h" -_PUBLIC_ struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx, +struct ntvfs_request *ntvfs_request_create(struct ntvfs_context *ctx, TALLOC_CTX *mem_ctx, struct auth_session_info *session_info, uint16_t smbpid, struct timeval request_time, @@ -62,7 +62,7 @@ failed: return NULL; } -_PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, void *private_data, void (*send_fn)(struct ntvfs_request *)) @@ -84,7 +84,7 @@ _PUBLIC_ NTSTATUS ntvfs_async_state_push(struct ntvfs_module_context *ntvfs, return NT_STATUS_OK; } -_PUBLIC_ void ntvfs_async_state_pop(struct ntvfs_request *req) +void ntvfs_async_state_pop(struct ntvfs_request *req) { struct ntvfs_async_state *async; @@ -98,7 +98,7 @@ _PUBLIC_ void ntvfs_async_state_pop(struct ntvfs_request *req) talloc_free(async); } -_PUBLIC_ NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs, +NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct ntvfs_handle **h) { @@ -108,7 +108,7 @@ _PUBLIC_ NTSTATUS ntvfs_handle_new(struct ntvfs_module_context *ntvfs, return ntvfs->ctx->handles.create_new(ntvfs->ctx->handles.private_data, req, h); } -_PUBLIC_ NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h, +NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h, struct ntvfs_module_context *ntvfs, TALLOC_CTX *private_data) { @@ -137,7 +137,7 @@ _PUBLIC_ NTSTATUS ntvfs_handle_set_backend_data(struct ntvfs_handle *h, return NT_STATUS_OK; } -_PUBLIC_ void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h, +void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h, struct ntvfs_module_context *ntvfs) { struct ntvfs_handle_data *d; @@ -150,7 +150,7 @@ _PUBLIC_ void *ntvfs_handle_get_backend_data(struct ntvfs_handle *h, return NULL; } -_PUBLIC_ void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h, +void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h, struct ntvfs_module_context *ntvfs) { struct ntvfs_handle_data *d,*n; @@ -169,7 +169,7 @@ _PUBLIC_ void ntvfs_handle_remove_backend_data(struct ntvfs_handle *h, h->ctx->handles.destroy(h->ctx->handles.private_data, h); } -_PUBLIC_ struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs, +struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, const DATA_BLOB *key) { @@ -179,12 +179,12 @@ _PUBLIC_ struct ntvfs_handle *ntvfs_handle_search_by_wire_key(struct ntvfs_modul return ntvfs->ctx->handles.search_by_wire_key(ntvfs->ctx->handles.private_data, req, key); } -_PUBLIC_ DATA_BLOB ntvfs_handle_get_wire_key(struct ntvfs_handle *h, TALLOC_CTX *mem_ctx) +DATA_BLOB ntvfs_handle_get_wire_key(struct ntvfs_handle *h, TALLOC_CTX *mem_ctx) { return h->ctx->handles.get_wire_key(h->ctx->handles.private_data, h, mem_ctx); } -_PUBLIC_ NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs, +NTSTATUS ntvfs_set_handle_callbacks(struct ntvfs_context *ntvfs, NTSTATUS (*create_new)(void *private_data, struct ntvfs_request *req, struct ntvfs_handle **h), NTSTATUS (*make_valid)(void *private_data, struct ntvfs_handle *h), void (*destroy)(void *private_data, struct ntvfs_handle *h), diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index f19dc1f41f..5070f6852d 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -38,7 +38,7 @@ static int num_backends; The 'name' can be later used by other backends to find the operations structure for this backend. */ -_PUBLIC_ NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops) +NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops) { struct pvfs_acl_ops *new_ops; @@ -66,7 +66,7 @@ _PUBLIC_ NTSTATUS pvfs_acl_register(const struct pvfs_acl_ops *ops) /* return the operations structure for a named backend */ -_PUBLIC_ const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name) +const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name) { int i; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index b66d252a45..3043b80538 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -101,7 +101,7 @@ NTSTATUS pvfs_xattr_unlink_hook(struct pvfs_state *pvfs, const char *fname) /* load a NDR structure from a xattr */ -_PUBLIC_ NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, +NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, const char *fname, int fd, const char *attr_name, void *p, void *pull_fn) @@ -131,7 +131,7 @@ _PUBLIC_ NTSTATUS pvfs_xattr_ndr_load(struct pvfs_state *pvfs, /* save a NDR structure into a xattr */ -_PUBLIC_ NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, +NTSTATUS pvfs_xattr_ndr_save(struct pvfs_state *pvfs, const char *fname, int fd, const char *attr_name, void *p, void *push_fn) { -- cgit From 236fc02913adafd80921d4e30aa6ee1e414bef44 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2008 13:41:10 +0200 Subject: Reduce the number of installed headers. (This used to be commit 2243e24024f09ff9c9c7d0eb735c3b39c9d84424) --- source4/ntvfs/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 0f8e88eaa6..2f57c787ef 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -87,7 +87,7 @@ OBJ_FILES = \ ntvfs_interface.o \ ntvfs_util.o -PUBLIC_HEADERS += ntvfs/ntvfs.h +# PUBLIC_HEADERS += ntvfs/ntvfs.h # # End SUBSYSTEM NTVFS ################################################ -- cgit From a71f36e2b8f58cb2929b1e031e85083737c93145 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 28 Mar 2008 11:00:52 +0100 Subject: ntvfs: Use wbclient in vsf_unixuid, not sidmap (This used to be commit 2908a77fa5c32e92665775a5785345f704202f0a) --- source4/ntvfs/unixuid/vfs_unixuid.c | 72 +++++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 22 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/unixuid/vfs_unixuid.c b/source4/ntvfs/unixuid/vfs_unixuid.c index 63889c6677..66c2cfaf4c 100644 --- a/source4/ntvfs/unixuid/vfs_unixuid.c +++ b/source4/ntvfs/unixuid/vfs_unixuid.c @@ -25,11 +25,11 @@ #include "system/passwd.h" #include "auth/auth.h" #include "ntvfs/ntvfs.h" -#include "dsdb/samdb/samdb.h" +#include "libcli/wbclient/wbclient.h" #include "param/param.h" struct unixuid_private { - struct sidmap_context *sidmap; + struct wbc_context *wbc_ctx; struct unix_sec_ctx *last_sec_ctx; struct security_token *last_token; }; @@ -100,9 +100,11 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, struct security_token *token, struct unix_sec_ctx **sec) { - struct unixuid_private *private = ntvfs->private_data; + struct unixuid_private *priv = ntvfs->private_data; int i; NTSTATUS status; + struct id_mapping *ids; + struct composite_context *ctx; *sec = talloc(req, struct unix_sec_ctx); /* we can't do unix security without a user and group */ @@ -110,29 +112,53 @@ static NTSTATUS nt_token_to_unix_security(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } - status = sidmap_sid_to_unixuid(private->sidmap, - token->user_sid, &(*sec)->uid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ids = talloc_array(req, struct id_mapping, token->num_sids); + NT_STATUS_HAVE_NO_MEMORY(ids); - status = sidmap_sid_to_unixgid(private->sidmap, - token->group_sid, &(*sec)->gid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ids[0].unixid = NULL; + ids[0].sid = token->user_sid; + ids[0].status = NT_STATUS_NONE_MAPPED; + + ids[1].unixid = NULL; + ids[1].sid = token->group_sid; + ids[1].status = NT_STATUS_NONE_MAPPED; (*sec)->ngroups = token->num_sids - 2; (*sec)->groups = talloc_array(*sec, gid_t, (*sec)->ngroups); - if ((*sec)->groups == NULL) { - return NT_STATUS_NO_MEMORY; + NT_STATUS_HAVE_NO_MEMORY((*sec)->groups); + + for (i=0;i<(*sec)->ngroups;i++) { + ids[i+2].unixid = NULL; + ids[i+2].sid = token->sids[i+2]; + ids[i+2].status = NT_STATUS_NONE_MAPPED; + } + + ctx = wbc_sids_to_xids_send(priv->wbc_ctx, ids, token->num_sids, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + status = wbc_sids_to_xids_recv(ctx, &ids); + NT_STATUS_NOT_OK_RETURN(status); + + if (ids[0].unixid->type == ID_TYPE_BOTH || + ids[0].unixid->type == ID_TYPE_UID) { + (*sec)->uid = ids[0].unixid->id; + } else { + return NT_STATUS_INVALID_SID; + } + + if (ids[1].unixid->type == ID_TYPE_BOTH || + ids[1].unixid->type == ID_TYPE_GID) { + (*sec)->gid = ids[1].unixid->id; + } else { + return NT_STATUS_INVALID_SID; } for (i=0;i<(*sec)->ngroups;i++) { - status = sidmap_sid_to_unixgid(private->sidmap, - token->sids[i+2], &(*sec)->groups[i]); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (ids[i+2].unixid->type == ID_TYPE_BOTH || + ids[i+2].unixid->type == ID_TYPE_GID) { + (*sec)->groups[i] = ids[i+2].unixid->id; + } else { + return NT_STATUS_INVALID_SID; } } @@ -216,9 +242,11 @@ static NTSTATUS unixuid_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } - private->sidmap = sidmap_open(private, ntvfs->ctx->lp_ctx); - if (private->sidmap == NULL) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; + private->wbc_ctx = wbc_init(private, ntvfs->ctx->msg_ctx, + ntvfs->ctx->event_ctx); + if (private->wbc_ctx == NULL) { + talloc_free(private); + return NT_STATUS_INTERNAL_ERROR; } ntvfs->private_data = private; -- cgit From 4133bd85e9f5860712cf392ccac36f30f9e423de Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Fri, 28 Mar 2008 23:29:01 +0100 Subject: ntvfs: Use wbclient for pvfs_acl and pvfs_acl_nfs4 (This used to be commit ac5e5fee1db2999053dee82d1fcf97ca8799c9b5) --- source4/ntvfs/posix/pvfs_acl.c | 100 ++++++++++++++++++++++++++++------ source4/ntvfs/posix/pvfs_acl_nfs4.c | 106 ++++++++++++++++++++++++++---------- source4/ntvfs/posix/vfs_posix.c | 6 +- source4/ntvfs/posix/vfs_posix.h | 3 +- 4 files changed, 166 insertions(+), 49 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 5070f6852d..2393a2e7a3 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -126,6 +126,8 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, NTSTATUS status; struct security_ace ace; mode_t mode; + struct id_mapping *ids; + struct composite_context *ctx; *psd = security_descriptor_initialise(req); if (*psd == NULL) { @@ -133,15 +135,33 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, } sd = *psd; - status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ids = talloc_array(sd, struct id_mapping, 2); + NT_STATUS_HAVE_NO_MEMORY(ids); + + ids[0].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid); + + ids[0].unixid->id = name->st.st_uid; + ids[0].unixid->type = ID_TYPE_UID; + ids[0].sid = NULL; + ids[1].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid); + + ids[1].unixid->id = name->st.st_gid; + ids[1].unixid->type = ID_TYPE_GID; + ids[1].sid = NULL; + + ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + status = wbc_xids_to_sids_recv(ctx, &ids); + NT_STATUS_NOT_OK_RETURN(status); + + sd->owner_sid = talloc_steal(sd, ids[0].sid); + sd->group_sid = talloc_steal(sd, ids[1].sid); + + talloc_free(ids); sd->type |= SEC_DESC_DACL_PRESENT; mode = name->st.st_mode; @@ -248,6 +268,8 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, gid_t old_gid = -1; uid_t new_uid = -1; gid_t new_gid = -1; + struct id_mapping *ids; + struct composite_context *ctx; if (pvfs->acl_ops != NULL) { status = pvfs->acl_ops->acl_load(pvfs, name, fd, req, &sd); @@ -259,6 +281,12 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, return status; } + ids = talloc(req, struct id_mapping); + NT_STATUS_HAVE_NO_MEMORY(ids); + ids->unixid = NULL; + ids->sid = NULL; + ids->status = NT_STATUS_NONE_MAPPED; + new_sd = info->set_secdesc.in.sd; orig_sd = *sd; @@ -271,8 +299,16 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, return NT_STATUS_ACCESS_DENIED; } if (!dom_sid_equal(sd->owner_sid, new_sd->owner_sid)) { - status = sidmap_sid_to_unixuid(pvfs->sidmap, new_sd->owner_sid, &new_uid); + ids->sid = new_sd->owner_sid; + ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + status = wbc_sids_to_xids_recv(ctx, &ids); NT_STATUS_NOT_OK_RETURN(status); + + if (ids->unixid->type == ID_TYPE_BOTH || + ids->unixid->type == ID_TYPE_UID) { + new_uid = ids->unixid->id; + } } sd->owner_sid = new_sd->owner_sid; } @@ -281,8 +317,17 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, return NT_STATUS_ACCESS_DENIED; } if (!dom_sid_equal(sd->group_sid, new_sd->group_sid)) { - status = sidmap_sid_to_unixgid(pvfs->sidmap, new_sd->group_sid, &new_gid); + ids->sid = new_sd->group_sid; + ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx, ids, 1, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + status = wbc_sids_to_xids_recv(ctx, &ids); NT_STATUS_NOT_OK_RETURN(status); + + if (ids->unixid->type == ID_TYPE_BOTH || + ids->unixid->type == ID_TYPE_GID) { + new_gid = ids->unixid->id; + } + } sd->group_sid = new_sd->group_sid; } @@ -664,6 +709,8 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, struct pvfs_filename *parent; struct security_descriptor *parent_sd, *sd; bool container; + struct id_mapping *ids; + struct composite_context *ctx; /* form the parents path */ status = pvfs_resolve_parent(pvfs, req, name, &parent); @@ -705,14 +752,31 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, return NT_STATUS_NO_MEMORY; } - status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ids = talloc_array(sd, struct id_mapping, 2); + NT_STATUS_HAVE_NO_MEMORY(ids); + + ids[0].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid); + ids[0].unixid->id = name->st.st_uid; + ids[0].unixid->type = ID_TYPE_UID; + ids[0].sid = NULL; + ids[0].status = NT_STATUS_NONE_MAPPED; + + ids[1].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid); + ids[1].unixid->id = name->st.st_gid; + ids[1].unixid->type = ID_TYPE_GID; + ids[1].sid = NULL; + ids[1].status = NT_STATUS_NONE_MAPPED; + + ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, ids, 2, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + status = wbc_xids_to_sids_recv(ctx, &ids); + NT_STATUS_NOT_OK_RETURN(status); + + sd->owner_sid = talloc_steal(sd, ids[0].sid); + sd->group_sid = talloc_steal(sd, ids[1].sid); sd->type |= SEC_DESC_DACL_PRESENT; diff --git a/source4/ntvfs/posix/pvfs_acl_nfs4.c b/source4/ntvfs/posix/pvfs_acl_nfs4.c index 2abb1482a4..fa855555b2 100644 --- a/source4/ntvfs/posix/pvfs_acl_nfs4.c +++ b/source4/ntvfs/posix/pvfs_acl_nfs4.c @@ -38,7 +38,9 @@ static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename NTSTATUS status; struct nfs4acl *acl; struct security_descriptor *sd; - int i; + int i, num_ids; + struct id_mapping *ids; + struct composite_context *ctx; acl = talloc_zero(mem_ctx, struct nfs4acl); NT_STATUS_HAVE_NO_MEMORY(acl); @@ -57,25 +59,57 @@ static NTSTATUS pvfs_acl_load_nfs4(struct pvfs_state *pvfs, struct pvfs_filename sd = *psd; sd->type |= acl->a_flags; - status = sidmap_uid_to_sid(pvfs->sidmap, sd, name->st.st_uid, &sd->owner_sid); - NT_STATUS_NOT_OK_RETURN(status); - status = sidmap_gid_to_sid(pvfs->sidmap, sd, name->st.st_gid, &sd->group_sid); + + /* the number of ids to map is the acl count plus uid and gid */ + num_ids = acl->a_count +2; + ids = talloc_array(sd, struct id_mapping, num_ids); + NT_STATUS_HAVE_NO_MEMORY(ids); + + ids[0].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[0].unixid); + ids[0].unixid->id = name->st.st_uid; + ids[0].unixid->type = ID_TYPE_UID; + ids[0].sid = NULL; + ids[0].status = NT_STATUS_NONE_MAPPED; + + ids[1].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[1].unixid); + ids[1].unixid->id = name->st.st_gid; + ids[1].unixid->type = ID_TYPE_GID; + ids[1].sid = NULL; + ids[1].status = NT_STATUS_NONE_MAPPED; + + for (i=0;ia_count;i++) { + struct nfs4ace *a = &acl->ace[i]; + ids[i+2].unixid = talloc(ids, struct unixid); + NT_STATUS_HAVE_NO_MEMORY(ids[i+2].unixid); + ids[i+2].unixid->id = a->e_id; + if (a->e_flags & ACE4_IDENTIFIER_GROUP) { + ids[i+2].unixid->type = ID_TYPE_GID; + } else { + ids[i+2].unixid->type = ID_TYPE_UID; + } + ids[i+2].sid = NULL; + ids[i+2].status = NT_STATUS_NONE_MAPPED; + } + + /* Allocate memory for the sids from the security descriptor to be on + * the safe side. */ + ctx = wbc_xids_to_sids_send(pvfs->wbc_ctx, sd, num_ids, ids); + NT_STATUS_HAVE_NO_MEMORY(ctx); + status = wbc_xids_to_sids_recv(ctx, &ids); NT_STATUS_NOT_OK_RETURN(status); + sd->owner_sid = talloc_steal(sd, ids[0].sid); + sd->group_sid = talloc_steal(sd, ids[1].sid); + for (i=0;ia_count;i++) { struct nfs4ace *a = &acl->ace[i]; struct security_ace ace; - struct dom_sid *sid; ace.type = a->e_type; ace.flags = a->e_flags; ace.access_mask = a->e_mask; - if (a->e_flags & ACE4_IDENTIFIER_GROUP) { - status = sidmap_gid_to_sid(pvfs->sidmap, sd, a->e_id, &sid); - } else { - status = sidmap_uid_to_sid(pvfs->sidmap, sd, a->e_id, &sid); - } - NT_STATUS_NOT_OK_RETURN(status); - ace.trustee = *sid; + ace.trustee = *ids[i+2].sid; security_descriptor_dacl_add(sd, &ace); } @@ -93,6 +127,8 @@ static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename struct nfs4acl acl; int i; TALLOC_CTX *tmp_ctx; + struct id_mapping *ids; + struct composite_context *ctx; tmp_ctx = talloc_new(pvfs); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); @@ -110,30 +146,44 @@ static NTSTATUS pvfs_acl_save_nfs4(struct pvfs_state *pvfs, struct pvfs_filename return NT_STATUS_NO_MEMORY; } + ids = talloc_array(tmp_ctx, struct id_mapping, acl.a_count); + if (ids == NULL) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + + for (i=0;idacl->aces[i]; + ids[i].unixid = NULL; + ids[i].sid = dom_sid_dup(ids, &ace->trustee); + if (ids[i].sid == NULL) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + ids[i].status = NT_STATUS_NONE_MAPPED; + } + + ctx = wbc_sids_to_xids_send(pvfs->wbc_ctx,ids, acl.a_count, ids); + if (ctx == NULL) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = wbc_sids_to_xids_recv(ctx, &ids); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); + return status; + } + for (i=0;idacl->aces[i]; a->e_type = ace->type; a->e_flags = ace->flags; a->e_mask = ace->access_mask; - if (sidmap_sid_is_group(pvfs->sidmap, &ace->trustee)) { - gid_t gid; + if (ids[i].unixid->type != ID_TYPE_UID) { a->e_flags |= ACE4_IDENTIFIER_GROUP; - status = sidmap_sid_to_unixgid(pvfs->sidmap, &ace->trustee, &gid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - a->e_id = gid; - } else { - uid_t uid; - status = sidmap_sid_to_unixuid(pvfs->sidmap, &ace->trustee, &uid); - if (!NT_STATUS_IS_OK(status)) { - talloc_free(tmp_ctx); - return status; - } - a->e_id = uid; } + a->e_id = ids[i].unixid->id; a->e_who = ""; } diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ca874d1db1..ebc2d88e70 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -222,8 +222,10 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, event_context_find(pvfs), pvfs->ntvfs->ctx->config); - pvfs->sidmap = sidmap_open(pvfs, pvfs->ntvfs->ctx->lp_ctx); - if (pvfs->sidmap == NULL) { + pvfs->wbc_ctx = wbc_init(pvfs, + pvfs->ntvfs->ctx->msg_ctx, + pvfs->ntvfs->ctx->event_ctx); + if (pvfs->wbc_ctx == NULL) { return NT_STATUS_INTERNAL_DB_CORRUPTION; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 4d22a91714..441424142f 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -26,6 +26,7 @@ #include "system/filesys.h" #include "ntvfs/ntvfs.h" #include "ntvfs/common/ntvfs_common.h" +#include "libcli/wbclient/wbclient.h" #include "dsdb/samdb/samdb.h" struct pvfs_wait; @@ -46,7 +47,7 @@ struct pvfs_state { struct brl_context *brl_context; struct odb_context *odb_context; struct notify_context *notify_context; - struct sidmap_context *sidmap; + struct wbc_context *wbc_ctx; /* a list of pending async requests. Needed to support ntcancel */ -- cgit From 275f32ae2df333c089343dd20fc4efee1bed2b7b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Apr 2008 11:31:17 +0200 Subject: fill in unknown fields in SMB2 READ call (This used to be commit 9b686c138037f613da15168d0722786e00f023e5) --- source4/ntvfs/ntvfs_generic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index e1a86c07c0..fee3269eaf 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1214,7 +1214,8 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, break; case RAW_READ_SMB2: rd->smb2.out.data.length= rd2->generic.out.nread; - rd->smb2.out.unknown1 = 0; + rd->smb2.out.remaining = 0; + rd->smb2.out.reserved = 0; break; default: return NT_STATUS_INVALID_LEVEL; -- cgit From f78bc8c489b02b521e9ecbdbdc72d160c6911b6b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 11:54:50 +0200 Subject: Remove prototypes from build.h in preparation of removing build.h altogether. (This used to be commit dbeab2a9cdee4e5f69afeb2603ba29cbed56debd) --- source4/ntvfs/ntvfs_base.c | 10 ++++++++++ source4/ntvfs/sysdep/sys_lease.c | 1 + source4/ntvfs/sysdep/sys_notify.c | 1 + 3 files changed, 12 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 51faa44372..8f574fa96b 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -204,6 +204,16 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) { static bool initialized = false; + extern NTSTATUS ntvfs_posix_init(void); + extern NTSTATUS ntvfs_cifs_init(void); + extern NTSTATUS ntvfs_nbench_init(void); + extern NTSTATUS ntvfs_unixuid_init(void); + extern NTSTATUS ntvfs_ipc_init(void); + extern NTSTATUS pvfs_acl_nfs4_init(void); + extern NTSTATUS pvfs_acl_xattr_init(void); + extern NTSTATUS ntvfs_print_init(void); + extern NTSTATUS ntvfs_simple_init(void); + extern NTSTATUS ntvfs_cifs_posix_init(void); init_module_fn static_init[] = { STATIC_ntvfs_MODULES }; init_module_fn *shared_init; diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c index 28dd27a708..b8a165aa51 100644 --- a/source4/ntvfs/sysdep/sys_lease.c +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -112,6 +112,7 @@ _PUBLIC_ NTSTATUS sys_lease_register(const struct sys_lease_ops *backend) _PUBLIC_ NTSTATUS sys_lease_init(void) { static bool initialized = false; + extern NTSTATUS sys_lease_linux_init(void); init_module_fn static_init[] = { STATIC_sys_lease_MODULES }; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index 84ba745f5b..eb5cc3793f 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -124,6 +124,7 @@ _PUBLIC_ NTSTATUS sys_notify_register(struct sys_notify_backend *backend) _PUBLIC_ NTSTATUS sys_notify_init(void) { static bool initialized = false; + extern NTSTATUS sys_notify_inotify_init(void); init_module_fn static_init[] = { STATIC_sys_notify_MODULES }; -- cgit From e9017ba418202b4b191c5a9ad4a96857558ce606 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 14 Apr 2008 17:22:58 +0200 Subject: Use _OBJ_FILES variables in a couple more places. (This used to be commit 92856d5054106894b65cd1a1b5119c0facfc4cff) --- source4/ntvfs/common/config.mk | 15 ++++----------- source4/ntvfs/config.mk | 34 +++++++++++++--------------------- source4/ntvfs/posix/config.mk | 26 +++++++++++++++----------- source4/ntvfs/sysdep/config.mk | 26 ++++++++------------------ source4/ntvfs/unixuid/config.mk | 4 ++-- 5 files changed, 42 insertions(+), 63 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 3963ebcdee..c66257b73f 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -2,17 +2,10 @@ # Start LIBRARY ntvfs_common [SUBSYSTEM::ntvfs_common] PRIVATE_PROTO_HEADER = proto.h -OBJ_FILES = \ - init.o \ - brlock.o \ - brlock_tdb.o \ - opendb.o \ - opendb_tdb.o \ - notify.o -PUBLIC_DEPENDENCIES = \ - NDR_OPENDB NDR_NOTIFY \ - sys_notify sys_lease \ - share LIBDBWRAP +PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify sys_lease share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ + +ntvfs_common_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) + diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 2f57c787ef..93cbf64d8f 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -9,25 +9,24 @@ mkinclude sysdep/config.mk [MODULE::ntvfs_cifs] INIT_FUNCTION = ntvfs_cifs_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - cifs/vfs_cifs.o PRIVATE_DEPENDENCIES = \ LIBCLI_SMB LIBCLI_RAW # End MODULE ntvfs_cifs ################################################ +ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o + ################################################ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = simple/proto.h -OBJ_FILES = \ - simple/vfs_simple.o \ - simple/svfs_util.o # End MODULE ntvfs_simple ################################################ +ntvfs_simple_OBJ_FILES = $(addprefix ntvfs/simple/, vfs_simple.o svfs_util.o) + ################################################ # Start MODULE ntvfs_cifsposix [MODULE::ntvfs_cifsposix] @@ -35,57 +34,50 @@ OBJ_FILES = \ INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h -OBJ_FILES = \ - cifs_posix_cli/vfs_cifs_posix.o \ - cifs_posix_cli/svfs_util.o # End MODULE ntvfs_cifsposix ################################################ +ntvfs_cifsposix_OBJ_FILES = \ + $(addprefix ntvfs/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) + ################################################ # Start MODULE ntvfs_print [MODULE::ntvfs_print] INIT_FUNCTION = ntvfs_print_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - print/vfs_print.o # End MODULE ntvfs_print ################################################ +ntvfs_print_OBJ_FILES = ntvfs/print/vfs_print.o + ################################################ # Start MODULE ntvfs_ipc [MODULE::ntvfs_ipc] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_ipc_init PRIVATE_PROTO_HEADER = ipc/proto.h -OBJ_FILES = \ - ipc/vfs_ipc.o \ - ipc/ipc_rap.o \ - ipc/rap_server.o PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ +ntvfs_ipc_OBJ_FILES = $(addprefix ntvfs/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_nbench_init -OBJ_FILES = \ - nbench/vfs_nbench.o # End MODULE ntvfs_nbench ################################################ +ntvfs_nbench_OBJ_FILES = ntvfs/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] PRIVATE_PROTO_HEADER = ntvfs_proto.h -OBJ_FILES = \ - ntvfs_base.o \ - ntvfs_generic.o \ - ntvfs_interface.o \ - ntvfs_util.o + +ntvfs_OBJ_FILES = $(addprefix ntvfs/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) # PUBLIC_HEADERS += ntvfs/ntvfs.h # diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 88048c2af7..865a0ffd4a 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -3,30 +3,31 @@ [MODULE::pvfs_acl_xattr] INIT_FUNCTION = pvfs_acl_xattr_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_xattr.o PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ +pvfs_acl_xattr_OBJ_FILES = ntvfs/posix/pvfs_acl_xattr.o + ################################################ # Start MODULE pvfs_acl_nfs4 [MODULE::pvfs_acl_nfs4] INIT_FUNCTION = pvfs_acl_nfs4_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - pvfs_acl_nfs4.o PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ +pvfs_acl_nfs4_OBJ_FILES = ntvfs/posix/pvfs_acl_nfs4.o + ################################################ [MODULE::pvfs_aio] SUBSYSTEM = ntvfs -OBJ_FILES = pvfs_aio.o PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ +pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o + ################################################ # Start MODULE ntvfs_posix [MODULE::ntvfs_posix] @@ -34,7 +35,13 @@ SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init PRIVATE_PROTO_HEADER = vfs_posix_proto.h -OBJ_FILES = \ +#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 +PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio \ + LIBWBCLIENT +# End MODULE ntvfs_posix +################################################ + +ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ @@ -62,8 +69,5 @@ OBJ_FILES = \ pvfs_acl.o \ pvfs_notify.o \ xattr_system.o \ - xattr_tdb.o -#PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 -PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio -# End MODULE ntvfs_posix -################################################ + xattr_tdb.o) + diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 048226efad..de445bff7b 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -3,34 +3,24 @@ [MODULE::sys_notify_inotify] SUBSYSTEM = sys_notify INIT_FUNCTION = sys_notify_inotify_init -OBJ_FILES = \ - inotify.o # End MODULE sys_notify_inotify ################################################ +sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o + ################################################ # Start SUBSYSTEM sys_notify [SUBSYSTEM::sys_notify] -OBJ_FILES = \ - sys_notify.o -PUBLIC_DEPENDENCIES = # End SUBSYSTEM sys_notify ################################################ -################################################ -# Start MODULE sys_lease_linux +sys_notify_OBJ_FILES = ntvfs/sysdep/sys_notify.o + [MODULE::sys_lease_linux] SUBSYSTEM = sys_lease -INIT_FUNCTION = sys_lease_linux_init -OBJ_FILES = \ - sys_lease_linux.o -# End MODULE sys_lease_linux -################################################ -################################################ -# Start SUBSYSTEM sys_lease +sys_lease_linux_OBJ_FILES = ntvfs/sysdep/sys_lease_linux.o + [SUBSYSTEM::sys_lease] -OBJ_FILES = \ - sys_lease.o -# End SUBSYSTEM sys_lease -################################################ + +sys_lease_OBJ_FILES = ntvfs/sysdep/sys_lease.o diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 91976c6811..968e56bde4 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -3,8 +3,8 @@ [MODULE::ntvfs_unixuid] INIT_FUNCTION = ntvfs_unixuid_init SUBSYSTEM = ntvfs -OBJ_FILES = \ - vfs_unixuid.o PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER # End MODULE ntvfs_unixuid ################################################ + +ntvfs_unixuid_OBJ_FILES = ntvfs/unixuid/vfs_unixuid.o -- cgit From 292ed5d04f9b7442bf878c36be24a46fc0373d9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Apr 2008 18:44:43 +0200 Subject: fixed an unitialised write warning in valgrind the 'reserved' field was not being initialised before being pushed to the wire (This used to be commit dfe4b5009885c4eeca24569f35b9fc85bfe6346b) --- source4/ntvfs/ntvfs_generic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index fee3269eaf..01c3a16433 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -209,6 +209,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; io->smb2.out.oplock_level = 0; + io->smb2.out.reserved = 0; io->smb2.out.create_action = io2->generic.out.create_action; io->smb2.out.create_time = io2->generic.out.create_time; io->smb2.out.access_time = io2->generic.out.access_time; -- cgit From 79af7ff2f7f6fabe8a2a48386088228096e218b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 14 Apr 2008 18:59:40 +0200 Subject: fixed a valgrind error in id mapping the status field is sent on both call and reply, but was only being initialised on reply (This used to be commit 2ebd7b80998775168959d511fbc987f8b5b7bd34) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 2393a2e7a3..f1e469f790 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -135,7 +135,7 @@ static NTSTATUS pvfs_default_acl(struct pvfs_state *pvfs, } sd = *psd; - ids = talloc_array(sd, struct id_mapping, 2); + ids = talloc_zero_array(sd, struct id_mapping, 2); NT_STATUS_HAVE_NO_MEMORY(ids); ids[0].unixid = talloc(ids, struct unixid); -- cgit From a195cd9d8f3d0c0185fbf82388bd1efaa63e7bd5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 16 Apr 2008 22:52:07 +0200 Subject: Use readily available event context. (This used to be commit 2823fca23a4cacc996c808f22cba50b4482b5921) --- source4/ntvfs/posix/vfs_posix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index ebc2d88e70..14b5210fd0 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -219,7 +219,7 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, pvfs->ntvfs->ctx->server_id, pvfs->ntvfs->ctx->msg_ctx, pvfs->ntvfs->ctx->lp_ctx, - event_context_find(pvfs), + pvfs->ntvfs->ctx->event_ctx, pvfs->ntvfs->ctx->config); pvfs->wbc_ctx = wbc_init(pvfs, -- cgit From 1efbd5fbf6b0f606ed29a763e2adfa6f99c6beac Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 01:03:18 +0200 Subject: Remove event context tracking from the credentials struct. (This used to be commit 4d7fc946b2ec50e774689c9036423b6feef99b8e) --- source4/ntvfs/cifs/vfs_cifs.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2feb1a0efe..2b61268733 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -171,7 +171,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, if (!credentials) { return NT_STATUS_NO_MEMORY; } - cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { @@ -181,7 +180,6 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, } else if (machine_account) { DEBUG(5, ("CIFS backend: Using machine account\n")); credentials = cli_credentials_init(private); - cli_credentials_set_event_context(credentials, ntvfs->ctx->event_ctx); cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); -- cgit From c15ffa27cb3a1cadbbf06d564146c1ab8dec952b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 01:19:53 +0200 Subject: Explicitly require event context to be specified. (This used to be commit a95a71fe45ef6a578569931a7c38061783d07db3) --- source4/ntvfs/common/notify.c | 4 ++++ source4/ntvfs/sysdep/sys_notify.c | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/notify.c b/source4/ntvfs/common/notify.c index 23aa3fb668..9055d6ece3 100644 --- a/source4/ntvfs/common/notify.c +++ b/source4/ntvfs/common/notify.c @@ -93,6 +93,10 @@ struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server, return NULL; } + if (ev == NULL) { + return NULL; + } + notify = talloc(mem_ctx, struct notify_context); if (notify == NULL) { return NULL; diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index eb5cc3793f..22b72c4d63 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -52,7 +52,7 @@ _PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_confi } if (ev == NULL) { - ev = event_context_find(mem_ctx); + return NULL; } ctx = talloc_zero(mem_ctx, struct sys_notify_context); -- cgit From 14023e502b7a1043afe0dde7f1c60a4b29a76646 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 01:22:39 +0200 Subject: Require explicit event context rather than looking if it is not specified. (This used to be commit 1da0063bd5fd18ad3ac7a07c985ec6be380486e2) --- source4/ntvfs/sysdep/sys_lease.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c index b8a165aa51..e6b11c450a 100644 --- a/source4/ntvfs/sysdep/sys_lease.c +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -55,7 +55,7 @@ _PUBLIC_ struct sys_lease_context *sys_lease_context_create(struct share_config } if (ev == NULL) { - ev = event_context_find(mem_ctx); + return NULL; } ctx = talloc_zero(mem_ctx, struct sys_lease_context); -- cgit From baad7a7e56e2b0f24885e01672cd9bdc6667a6a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 17 Apr 2008 03:54:26 +0200 Subject: ntvfs_generic: map SMB2 oplock levels to the generic ones metze (This used to be commit 9013748273378f88bfc66d3583814f0fee67c40f) --- source4/ntvfs/ntvfs_generic.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index fee3269eaf..5d4bbf388c 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -208,7 +208,21 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; - io->smb2.out.oplock_level = 0; + switch (io2->generic.out.oplock_level) { + case OPLOCK_BATCH: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_BATCH; + break; + case OPLOCK_EXCLUSIVE: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; + break; + case OPLOCK_LEVEL_II: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_II; + break; + default: + io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_NONE; + break; + } + io->smb2.out.reserved = 0; io->smb2.out.create_action = io2->generic.out.create_action; io->smb2.out.create_time = io2->generic.out.create_time; io->smb2.out.access_time = io2->generic.out.access_time; @@ -484,7 +498,18 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, status = ntvfs->ops->open(ntvfs, req, io2); break; case RAW_OPEN_SMB2: - io2->generic.in.flags = 0; + switch (io->smb2.in.oplock_level) { + case SMB2_OPLOCK_LEVEL_BATCH: + io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK | + NTCREATEX_FLAGS_REQUEST_OPLOCK; + break; + case SMB2_OPLOCK_LEVEL_EXCLUSIVE: + io2->generic.in.flags = NTCREATEX_FLAGS_REQUEST_OPLOCK; + break; + default: + io2->generic.in.flags = 0; + break; + } io2->generic.in.root_fid = 0; io2->generic.in.access_mask = io->smb2.in.desired_access; io2->generic.in.alloc_size = 0; -- cgit From 21fc7673780aa1d7c0caab7b17ff9171238913ba Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 12:23:44 +0200 Subject: Specify event_context to ldb_wrap_connect explicitly. (This used to be commit b4e1ae07a284c044704322446c94351c2decff91) --- source4/ntvfs/ipc/ipc_rap.c | 11 ++++++++--- source4/ntvfs/ipc/rap_server.c | 3 ++- source4/ntvfs/ipc/vfs_ipc.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/ipc_rap.c b/source4/ntvfs/ipc/ipc_rap.c index faf48705c4..4969f1a791 100644 --- a/source4/ntvfs/ipc/ipc_rap.c +++ b/source4/ntvfs/ipc/ipc_rap.c @@ -21,6 +21,7 @@ #include "includes.h" #include "libcli/raw/interfaces.h" #include "libcli/rap/rap.h" +#include "events/events.h" #include "ntvfs/ipc/proto.h" #include "librpc/ndr/libndr.h" #include "param/param.h" @@ -100,11 +101,14 @@ struct rap_call { struct ndr_pull *ndr_pull_param; struct ndr_pull *ndr_pull_data; + + struct event_context *event_ctx; }; #define RAPNDR_FLAGS (LIBNDR_FLAG_NOALIGN|LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, + struct event_context *ev_ctx, struct loadparm_context *lp_ctx, struct smb_trans2 *trans) { @@ -118,6 +122,7 @@ static struct rap_call *new_rap_srv_call(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(call); call->lp_ctx = talloc_reference(call, lp_ctx); + call->event_ctx = ev_ctx; call->mem_ctx = mem_ctx; @@ -271,7 +276,7 @@ static NTSTATUS _rap_netshareenum(struct rap_call *call) break; } - result = rap_netshareenum(call, call->lp_ctx, &r); + result = rap_netshareenum(call, call->event_ctx, call->lp_ctx, &r); if (!NT_STATUS_IS_OK(result)) return result; @@ -430,7 +435,7 @@ static const struct {NULL, -1, api_Unsupported} }; -NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, +NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct loadparm_context *lp_ctx, struct smb_trans2 *trans) { int i; @@ -440,7 +445,7 @@ NTSTATUS ipc_rap_call(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ndr_push *final_param; struct ndr_push *final_data; - call = new_rap_srv_call(mem_ctx, lp_ctx, trans); + call = new_rap_srv_call(mem_ctx, event_ctx, lp_ctx, trans); if (call == NULL) return NT_STATUS_NO_MEMORY; diff --git a/source4/ntvfs/ipc/rap_server.c b/source4/ntvfs/ipc/rap_server.c index 633f0bf36e..d9fb7e21b2 100644 --- a/source4/ntvfs/ipc/rap_server.c +++ b/source4/ntvfs/ipc/rap_server.c @@ -29,6 +29,7 @@ * idea. */ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, + struct event_context *event_ctx, struct loadparm_context *lp_ctx, struct rap_NetShareEnum *r) { @@ -42,7 +43,7 @@ NTSTATUS rap_netshareenum(TALLOC_CTX *mem_ctx, r->out.available = 0; r->out.info = NULL; - nterr = share_get_context_by_name(mem_ctx, lp_share_backend(lp_ctx), lp_ctx, &sctx); + nterr = share_get_context_by_name(mem_ctx, lp_share_backend(lp_ctx), event_ctx, lp_ctx, &sctx); if (!NT_STATUS_IS_OK(nterr)) { return nterr; } diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index 92f0eadae1..ea7b54ae6a 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -805,7 +805,7 @@ static NTSTATUS ipc_trans(struct ntvfs_module_context *ntvfs, NTSTATUS status; if (strequal(trans->in.trans_name, "\\PIPE\\LANMAN")) - return ipc_rap_call(req, ntvfs->ctx->lp_ctx, trans); + return ipc_rap_call(req, ntvfs->ctx->event_ctx, ntvfs->ctx->lp_ctx, trans); if (trans->in.setup_count != 2) { return NT_STATUS_INVALID_PARAMETER; -- cgit From b2f2c1486e9c6bd6fdba3dc321f9df0d29d7def2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 19 Apr 2008 00:14:52 +0200 Subject: ntvfs_generic: fix mapping the granted oplocks for SMB2 metze (This used to be commit 60c4a4fc1afe88716ac63d3ea430e07fea7b9991) --- source4/ntvfs/ntvfs_generic.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 5d4bbf388c..debcfc3f8a 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -209,13 +209,13 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, case RAW_OPEN_SMB2: io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; switch (io2->generic.out.oplock_level) { - case OPLOCK_BATCH: + case BATCH_OPLOCK_RETURN: io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_BATCH; break; - case OPLOCK_EXCLUSIVE: + case EXCLUSIVE_OPLOCK_RETURN: io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_EXCLUSIVE; break; - case OPLOCK_LEVEL_II: + case LEVEL_II_OPLOCK_RETURN: io->smb2.out.oplock_level = SMB2_OPLOCK_LEVEL_II; break; default: -- cgit From 39d23027218c02dc3055d8a0cc28dcc169e8b064 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 18 Apr 2008 22:32:25 +0200 Subject: ntvfs_generic: map RAW_LOCK_SMB2_BREAK to RAW_LOCK_GENERIC metze (This used to be commit b781bb733c9a563457f87c94abe8c91b426c07ee) --- source4/ntvfs/ntvfs_generic.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index debcfc3f8a..3653ad82c1 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1043,6 +1043,23 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, /* initialize output value */ lck->smb2.out.unknown1 = 0; break; + + case RAW_LOCK_SMB2_BREAK: + lck2->generic.level = RAW_LOCK_GENERIC; + lck2->generic.in.file.ntvfs = lck->smb2_break.in.file.ntvfs; + lck2->generic.in.mode = LOCKING_ANDX_OPLOCK_RELEASE | + ((lck->smb2_break.in.oplock_level << 8) & 0xFF00); + lck2->generic.in.timeout = 0; + lck2->generic.in.ulock_cnt = 0; + lck2->generic.in.lock_cnt = 0; + lck2->generic.in.locks = NULL; + + /* initialize output value */ + lck->smb2_break.out.oplock_level= lck->smb2_break.in.oplock_level; + lck->smb2_break.out.reserved = lck->smb2_break.in.reserved; + lck->smb2_break.out.reserved2 = lck->smb2_break.in.reserved2; + lck->smb2_break.out.file = lck->smb2_break.in.file; + break; } /* -- cgit From 3e80085fb09a89957991780f79f5726029b8a26f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 7 May 2008 15:46:22 +0200 Subject: pvfs: remove XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME code I'll fix this more correctly very soon, so that we'll pass the BASE-DELAYWRITE test. metze (This used to be commit b09dd6b65d533832a025a51509dcc84f84b048aa) --- source4/ntvfs/posix/pvfs_open.c | 17 ----------------- source4/ntvfs/posix/pvfs_setfileinfo.c | 2 -- source4/ntvfs/posix/pvfs_xattr.c | 32 +++++++++++++++----------------- source4/ntvfs/posix/vfs_posix.h | 3 --- 4 files changed, 15 insertions(+), 39 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 6e77cb7c75..c9c1c56f14 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -262,7 +262,6 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->position = 0; f->handle->mode = 0; f->handle->oplock = NULL; - f->handle->sticky_write_time = false; f->handle->open_completed = false; if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && @@ -416,16 +415,6 @@ cleanup_delete: */ static int pvfs_handle_destructor(struct pvfs_file_handle *h) { - /* the write time is no longer sticky */ - if (h->sticky_write_time) { - NTSTATUS status; - status = pvfs_dosattrib_load(h->pvfs, h->name, h->fd); - if (NT_STATUS_IS_OK(status)) { - h->name->dos.flags &= ~XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; - pvfs_dosattrib_save(h->pvfs, h->name, h->fd); - } - } - if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && h->name->stream_name) { NTSTATUS status; @@ -707,7 +696,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = true; - f->handle->sticky_write_time = false; f->handle->open_completed = false; status = odb_open_file(lck, f->handle, name->full_name, @@ -1257,7 +1245,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = false; - f->handle->sticky_write_time = false; f->handle->open_completed = false; /* form the lock context used for byte range locking and @@ -1479,10 +1466,6 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, unix_times.actime = 0; unix_times.modtime = io->close.in.write_time; utime(f->handle->name->full_name, &unix_times); - } else if (f->handle->sticky_write_time) { - unix_times.actime = 0; - unix_times.modtime = nt_time_to_unix(f->handle->name->dos.write_time); - utime(f->handle->name->full_name, &unix_times); } talloc_free(f); diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index ad47fe90c9..0beca75ead 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -342,8 +342,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } if (!null_nttime(info->basic_info.in.write_time)) { newstats.dos.write_time = info->basic_info.in.write_time; - newstats.dos.flags |= XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME; - h->sticky_write_time = true; } if (!null_nttime(info->basic_info.in.change_time)) { newstats.dos.change_time = info->basic_info.in.change_time; diff --git a/source4/ntvfs/posix/pvfs_xattr.c b/source4/ntvfs/posix/pvfs_xattr.c index 3043b80538..3cbbcbe92f 100644 --- a/source4/ntvfs/posix/pvfs_xattr.c +++ b/source4/ntvfs/posix/pvfs_xattr.c @@ -162,7 +162,7 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name struct xattr_DosAttrib attrib; TALLOC_CTX *mem_ctx = talloc_new(name); struct xattr_DosInfo1 *info1; - struct xattr_DosInfo2 *info2; + struct xattr_DosInfo2Old *info2; if (name->stream_name != NULL) { name->stream_exists = false; @@ -210,7 +210,11 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name break; case 2: - info2 = &attrib.info.info2; + /* + * Note: This is only used to parse existing values from disk + * We use xattr_DosInfo1 again for storing new values + */ + info2 = &attrib.info.oldinfo2; name->dos.attrib = pvfs_attrib_normalise(info2->attrib, name->st.st_mode); name->dos.ea_size = info2->ea_size; @@ -225,9 +229,6 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name name->dos.change_time = info2->change_time; } name->dos.flags = info2->flags; - if (name->dos.flags & XATTR_ATTRIB_FLAG_STICKY_WRITE_TIME) { - name->dos.write_time = info2->write_time; - } break; default: @@ -250,26 +251,23 @@ NTSTATUS pvfs_dosattrib_load(struct pvfs_state *pvfs, struct pvfs_filename *name NTSTATUS pvfs_dosattrib_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) { struct xattr_DosAttrib attrib; - struct xattr_DosInfo2 *info2; + struct xattr_DosInfo1 *info1; if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) { return NT_STATUS_OK; } - attrib.version = 2; - info2 = &attrib.info.info2; + attrib.version = 1; + info1 = &attrib.info.info1; name->dos.attrib = pvfs_attrib_normalise(name->dos.attrib, name->st.st_mode); - info2->attrib = name->dos.attrib; - info2->ea_size = name->dos.ea_size; - info2->size = name->st.st_size; - info2->alloc_size = name->dos.alloc_size; - info2->create_time = name->dos.create_time; - info2->change_time = name->dos.change_time; - info2->write_time = name->dos.write_time; - info2->flags = name->dos.flags; - info2->name = ""; + info1->attrib = name->dos.attrib; + info1->ea_size = name->dos.ea_size; + info1->size = name->st.st_size; + info1->alloc_size = name->dos.alloc_size; + info1->create_time = name->dos.create_time; + info1->change_time = name->dos.change_time; return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSATTRIB_NAME, &attrib, diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 441424142f..c194698b64 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -169,9 +169,6 @@ struct pvfs_file_handle { /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; - /* have we set a sticky write time that we should remove on close */ - bool sticky_write_time; - /* the open went through to completion */ bool open_completed; }; -- cgit From 7c7de11f20c5330c40c24d341056fb92806bbf37 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 01:53:11 +0200 Subject: Fix LDB module initialization when using external ldb. (This used to be commit b7b4aff8b52742d69526dc0ef5da2fe3c05e3af8) --- source4/ntvfs/sysdep/sys_lease.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/sysdep/sys_lease.c b/source4/ntvfs/sysdep/sys_lease.c index e6b11c450a..a0322bbcc1 100644 --- a/source4/ntvfs/sysdep/sys_lease.c +++ b/source4/ntvfs/sysdep/sys_lease.c @@ -28,7 +28,6 @@ #include "lib/events/events.h" #include "lib/util/dlinklist.h" #include "param/param.h" -#include "build.h" /* list of registered backends */ static struct sys_lease_ops *backends; @@ -109,6 +108,10 @@ _PUBLIC_ NTSTATUS sys_lease_register(const struct sys_lease_ops *backend) return NT_STATUS_OK; } +#ifndef STATIC_sys_lease_MODULES +#define STATIC_sys_lease_MODULES NULL +#endif + _PUBLIC_ NTSTATUS sys_lease_init(void) { static bool initialized = false; -- cgit From ca3257b286ed2e1b87a7d56ba290d01cd2078023 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 May 2008 10:57:22 +1000 Subject: started new vfs_smb2 module This new module is based on the vfs_cifs module. The idea is to create a backend which maps SMB requests to a SMB2 server. This will allow existing test suites for SMB to be run against our SMB2 client and server code. It will also help validate our SMB2 client library, probably leading to some API changes to make it flexible enough (This used to be commit 6ea8295a64ff5425def11b0d1cd988ef000320be) --- source4/ntvfs/config.mk | 14 + source4/ntvfs/ntvfs_base.c | 1 + source4/ntvfs/smb2/vfs_smb2.c | 1137 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1152 insertions(+) create mode 100644 source4/ntvfs/smb2/vfs_smb2.c (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 93cbf64d8f..ceb952d25c 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -16,6 +16,20 @@ PRIVATE_DEPENDENCIES = \ ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o + +################################################ +# Start MODULE ntvfs_smb2 +[MODULE::ntvfs_smb2] +INIT_FUNCTION = ntvfs_smb2_init +SUBSYSTEM = ntvfs +PRIVATE_DEPENDENCIES = \ + LIBCLI_SMB LIBCLI_RAW +# End MODULE ntvfs_smb2 +################################################ + +ntvfs_smb2_OBJ_FILES = ntvfs/smb2/vfs_smb2.o + + ################################################ # Start MODULE ntvfs_simple [MODULE::ntvfs_simple] diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 3706cd172c..6de13e4a0a 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -205,6 +205,7 @@ NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) static bool initialized = false; extern NTSTATUS ntvfs_posix_init(void); extern NTSTATUS ntvfs_cifs_init(void); + extern NTSTATUS ntvfs_smb2_init(void); extern NTSTATUS ntvfs_nbench_init(void); extern NTSTATUS ntvfs_unixuid_init(void); extern NTSTATUS ntvfs_ipc_init(void); diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c new file mode 100644 index 0000000000..f253fcecaf --- /dev/null +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -0,0 +1,1137 @@ +/* + Unix SMB/CIFS implementation. + + CIFS-to-SMB2 NTVFS filesystem backend + + Copyright (C) Andrew Tridgell 2008 + + largely based on vfs_cifs.c which was + Copyright (C) Andrew Tridgell 2003 + Copyright (C) James J Myers 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ +/* + this implements a CIFS->CIFS NTVFS filesystem backend. + +*/ + +#include "includes.h" +#include "libcli/raw/libcliraw.h" +#include "libcli/raw/raw_proto.h" +#include "libcli/smb_composite/smb_composite.h" +#include "auth/auth.h" +#include "auth/credentials/credentials.h" +#include "ntvfs/ntvfs.h" +#include "lib/util/dlinklist.h" +#include "param/param.h" +#include "libcli/resolve/resolve.h" + +struct cvfs_file { + struct cvfs_file *prev, *next; + uint16_t fnum; + struct ntvfs_handle *h; +}; + +/* this is stored in ntvfs_private */ +struct cvfs_private { + struct smbcli_tree *tree; + struct smbcli_transport *transport; + struct ntvfs_module_context *ntvfs; + struct async_info *pending; + struct cvfs_file *files; + bool map_generic; + bool map_trans2; +}; + + +/* a structure used to pass information to an async handler */ +struct async_info { + struct async_info *next, *prev; + struct cvfs_private *cvfs; + struct ntvfs_request *req; + struct smbcli_request *c_req; + struct cvfs_file *f; + void *parms; +}; + +#define SETUP_PID private->tree->session->pid = req->smbpid + +#define SETUP_FILE_HERE(f) do { \ + f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \ + if (!f) return NT_STATUS_INVALID_HANDLE; \ + io->generic.in.file.fnum = f->fnum; \ +} while (0) + +#define SETUP_FILE do { \ + struct cvfs_file *f; \ + SETUP_FILE_HERE(f); \ +} while (0) + +#define SETUP_PID_AND_FILE do { \ + SETUP_PID; \ + SETUP_FILE; \ +} while (0) + +#define CIFS_SERVER "cifs:server" +#define CIFS_USER "cifs:user" +#define CIFS_PASSWORD "cifs:password" +#define CIFS_DOMAIN "cifs:domain" +#define CIFS_SHARE "cifs:share" +#define CIFS_USE_MACHINE_ACCT "cifs:use-machine-account" +#define CIFS_MAP_GENERIC "cifs:map-generic" +#define CIFS_MAP_TRANS2 "cifs:map-trans2" + +#define CIFS_USE_MACHINE_ACCT_DEFAULT false +#define CIFS_MAP_GENERIC_DEFAULT false +#define CIFS_MAP_TRANS2_DEFAULT true + +/* + a handler for oplock break events from the server - these need to be passed + along to the client + */ +static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, uint16_t fnum, uint8_t level, void *p_private) +{ + struct cvfs_private *private = p_private; + NTSTATUS status; + struct ntvfs_handle *h = NULL; + struct cvfs_file *f; + + for (f=private->files; f; f=f->next) { + if (f->fnum != fnum) continue; + h = f->h; + break; + } + + if (!h) { + DEBUG(5,("vfs_cifs: ignoring oplock break level %d for fnum %d\n", level, fnum)); + return true; + } + + DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); + status = ntvfs_send_oplock_break(private->ntvfs, h, level); + if (!NT_STATUS_IS_OK(status)) return false; + return true; +} + +/* + connect to a share - used when a tree_connect operation comes in. +*/ +static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, const char *sharename) +{ + NTSTATUS status; + struct cvfs_private *private; + const char *host, *user, *pass, *domain, *remote_share; + struct smb_composite_connect io; + struct composite_context *creq; + struct share_config *scfg = ntvfs->ctx->config; + + struct cli_credentials *credentials; + bool machine_account; + + /* Here we need to determine which server to connect to. + * For now we use parametric options, type cifs. + * Later we will use security=server and auth_server.c. + */ + host = share_string_option(scfg, CIFS_SERVER, NULL); + user = share_string_option(scfg, CIFS_USER, NULL); + pass = share_string_option(scfg, CIFS_PASSWORD, NULL); + domain = share_string_option(scfg, CIFS_DOMAIN, NULL); + remote_share = share_string_option(scfg, CIFS_SHARE, NULL); + if (!remote_share) { + remote_share = sharename; + } + + machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); + + private = talloc_zero(ntvfs, struct cvfs_private); + if (!private) { + return NT_STATUS_NO_MEMORY; + } + + ntvfs->private_data = private; + + if (!host) { + DEBUG(1,("CIFS backend: You must supply server\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (user && pass) { + DEBUG(5, ("CIFS backend: Using specified password\n")); + credentials = cli_credentials_init(private); + if (!credentials) { + return NT_STATUS_NO_MEMORY; + } + cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); + cli_credentials_set_username(credentials, user, CRED_SPECIFIED); + if (domain) { + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + } + cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); + } else if (machine_account) { + DEBUG(5, ("CIFS backend: Using machine account\n")); + credentials = cli_credentials_init(private); + cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); + if (domain) { + cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); + } + status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } else if (req->session_info->credentials) { + DEBUG(5, ("CIFS backend: Using delegated credentials\n")); + credentials = req->session_info->credentials; + } else { + DEBUG(1,("CIFS backend: NO delegated credentials found: You must supply server, user and password or the client must supply delegated credentials\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + /* connect to the server, using the smbd event context */ + io.in.dest_host = host; + io.in.dest_ports = lp_smb_ports(ntvfs->ctx->lp_ctx); + io.in.called_name = host; + io.in.credentials = credentials; + io.in.fallback_to_anonymous = false; + io.in.workgroup = lp_workgroup(ntvfs->ctx->lp_ctx); + io.in.service = remote_share; + io.in.service_type = "?????"; + lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); + + if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) { + io.in.options.use_level2_oplocks = false; + } + + creq = smb_composite_connect_send(&io, private, + lp_resolve_context(ntvfs->ctx->lp_ctx), + ntvfs->ctx->event_ctx); + status = smb_composite_connect_recv(creq, private); + NT_STATUS_NOT_OK_RETURN(status); + + private->tree = io.out.tree; + + private->transport = private->tree->session->transport; + SETUP_PID; + private->ntvfs = ntvfs; + + ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); + ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); + NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); + + /* we need to receive oplock break requests from the server */ + smbcli_oplock_handler(private->transport, oplock_handler, private); + + private->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT); + + private->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT); + + return NT_STATUS_OK; +} + +/* + disconnect from a share +*/ +static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) +{ + struct cvfs_private *private = ntvfs->private_data; + struct async_info *a, *an; + + /* first cleanup pending requests */ + for (a=private->pending; a; a = an) { + an = a->next; + smbcli_request_destroy(a->c_req); + talloc_free(a); + } + + talloc_free(private); + ntvfs->private_data = NULL; + + return NT_STATUS_OK; +} + +/* + destroy an async info structure +*/ +static int async_info_destructor(struct async_info *async) +{ + DLIST_REMOVE(async->cvfs->pending, async); + return 0; +} + +/* + a handler for simple async replies + this handler can only be used for functions that don't return any + parameters (those that just return a status code) + */ +static void async_simple(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smbcli_request_simple_recv(c_req); + talloc_free(async); + req->async_states->send_fn(req); +} + + +/* save some typing for the simple functions */ +#define ASYNC_RECV_TAIL_F(io, async_fn, file) do { \ + if (!c_req) return NT_STATUS_UNSUCCESSFUL; \ + { \ + struct async_info *async; \ + async = talloc(req, struct async_info); \ + if (!async) return NT_STATUS_NO_MEMORY; \ + async->parms = io; \ + async->req = req; \ + async->f = file; \ + async->cvfs = private; \ + async->c_req = c_req; \ + DLIST_ADD(private->pending, async); \ + c_req->async.private = async; \ + talloc_set_destructor(async, async_info_destructor); \ + } \ + c_req->async.fn = async_fn; \ + req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC; \ + return NT_STATUS_OK; \ +} while (0) + +#define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL) + +#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) + +/* + delete a file - the dirtype specifies the file types to include in the search. + The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) +*/ +static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_unlink *unl) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + /* see if the front end will allow us to perform this + function asynchronously. */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_unlink(private->tree, unl); + } + + c_req = smb_raw_unlink_send(private->tree, unl); + + SIMPLE_ASYNC_TAIL; +} + +/* + a handler for async ioctl replies + */ +static void async_ioctl(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + ioctl interface +*/ +static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_ioctl *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + /* see if the front end will allow us to perform this + function asynchronously. */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_ioctl(private->tree, req, io); + } + + c_req = smb_raw_ioctl_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_ioctl); +} + +/* + check if a directory exists +*/ +static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_chkpath *cp) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_chkpath(private->tree, cp); + } + + c_req = smb_raw_chkpath_send(private->tree, cp); + + SIMPLE_ASYNC_TAIL; +} + +/* + a handler for async qpathinfo replies + */ +static void async_qpathinfo(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + return info on a pathname +*/ +static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *info) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_pathinfo(private->tree, req, info); + } + + c_req = smb_raw_pathinfo_send(private->tree, info); + + ASYNC_RECV_TAIL(info, async_qpathinfo); +} + +/* + a handler for async qfileinfo replies + */ +static void async_qfileinfo(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + query info on a open file +*/ +static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fileinfo *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_fileinfo(private->tree, req, io); + } + + c_req = smb_raw_fileinfo_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_qfileinfo); +} + + +/* + set info on a pathname +*/ +static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_setfileinfo *st) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_setpathinfo(private->tree, st); + } + + c_req = smb_raw_setpathinfo_send(private->tree, st); + + SIMPLE_ASYNC_TAIL; +} + + +/* + a handler for async open replies + */ +static void async_open(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct cvfs_private *cvfs = async->cvfs; + struct ntvfs_request *req = async->req; + struct cvfs_file *f = async->f; + union smb_open *io = async->parms; + union smb_handle *file; + talloc_free(async); + req->async_states->status = smb_raw_open_recv(c_req, req, io); + SMB_OPEN_OUT_FILE(io, file); + f->fnum = file->fnum; + file->ntvfs = NULL; + if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; + req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f); + if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; + file->ntvfs = f->h; + DLIST_ADD(cvfs->files, f); +failed: + req->async_states->send_fn(req); +} + +/* + open a file +*/ +static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_open *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + struct ntvfs_handle *h; + struct cvfs_file *f; + NTSTATUS status; + + SETUP_PID; + + if (io->generic.level != RAW_OPEN_GENERIC && + private->map_generic) { + return ntvfs_map_open(ntvfs, req, io); + } + + status = ntvfs_handle_new(ntvfs, req, &h); + NT_STATUS_NOT_OK_RETURN(status); + + f = talloc_zero(h, struct cvfs_file); + NT_STATUS_HAVE_NO_MEMORY(f); + f->h = h; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + union smb_handle *file; + + status = smb_raw_open(private->tree, req, io); + NT_STATUS_NOT_OK_RETURN(status); + + SMB_OPEN_OUT_FILE(io, file); + f->fnum = file->fnum; + file->ntvfs = NULL; + status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f); + NT_STATUS_NOT_OK_RETURN(status); + file->ntvfs = f->h; + DLIST_ADD(private->files, f); + + return NT_STATUS_OK; + } + + c_req = smb_raw_open_send(private->tree, io); + + ASYNC_RECV_TAIL_F(io, async_open, f); +} + +/* + create a directory +*/ +static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_mkdir *md) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_mkdir(private->tree, md); + } + + c_req = smb_raw_mkdir_send(private->tree, md); + + SIMPLE_ASYNC_TAIL; +} + +/* + remove a directory +*/ +static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_rmdir *rd) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_rmdir(private->tree, rd); + } + c_req = smb_raw_rmdir_send(private->tree, rd); + + SIMPLE_ASYNC_TAIL; +} + +/* + rename a set of files +*/ +static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_rename *ren) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (ren->nttrans.level == RAW_RENAME_NTTRANS) { + struct cvfs_file *f; + f = ntvfs_handle_get_backend_data(ren->nttrans.in.file.ntvfs, ntvfs); + if (!f) return NT_STATUS_INVALID_HANDLE; + ren->nttrans.in.file.fnum = f->fnum; + } + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_rename(private->tree, ren); + } + + c_req = smb_raw_rename_send(private->tree, ren); + + SIMPLE_ASYNC_TAIL; +} + +/* + copy a set of files +*/ +static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, struct smb_copy *cp) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + a handler for async read replies + */ +static void async_read(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_read_recv(c_req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + read from a file +*/ +static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_read *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (io->generic.level != RAW_READ_GENERIC && + private->map_generic) { + return ntvfs_map_read(ntvfs, req, io); + } + + SETUP_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_read(private->tree, io); + } + + c_req = smb_raw_read_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_read); +} + +/* + a handler for async write replies + */ +static void async_write(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_write_recv(c_req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + write to a file +*/ +static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_write *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (io->generic.level != RAW_WRITE_GENERIC && + private->map_generic) { + return ntvfs_map_write(ntvfs, req, io); + } + SETUP_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_write(private->tree, io); + } + + c_req = smb_raw_write_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_write); +} + +/* + a handler for async seek replies + */ +static void async_seek(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_seek_recv(c_req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + seek in a file +*/ +static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_seek *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_seek(private->tree, io); + } + + c_req = smb_raw_seek_send(private->tree, io); + + ASYNC_RECV_TAIL(io, async_seek); +} + +/* + flush a file +*/ +static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_flush *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + switch (io->generic.level) { + case RAW_FLUSH_FLUSH: + SETUP_FILE; + break; + case RAW_FLUSH_ALL: + io->generic.in.file.fnum = 0xFFFF; + break; + case RAW_FLUSH_SMB2: + return NT_STATUS_INVALID_LEVEL; + } + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_flush(private->tree, io); + } + + c_req = smb_raw_flush_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; +} + +/* + close a file +*/ +static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_close *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + struct cvfs_file *f; + + SETUP_PID; + + if (io->generic.level != RAW_CLOSE_GENERIC && + private->map_generic) { + return ntvfs_map_close(ntvfs, req, io); + } + SETUP_FILE_HERE(f); + /* Note, we aren't free-ing f, or it's h here. Should we? + even if file-close fails, we'll remove it from the list, + what else would we do? Maybe we should not remove until + after the proxied call completes? */ + DLIST_REMOVE(private->files, f); + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_close(private->tree, io); + } + + c_req = smb_raw_close_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; +} + +/* + exit - closing files open by the pid +*/ +static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + 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 ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + /* we can't do this right in the cifs backend .... */ + return NT_STATUS_OK; +} + +/* + setup for an async call - nothing to do yet +*/ +static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + void *private) +{ + return NT_STATUS_OK; +} + +/* + cancel an async call +*/ +static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req) +{ + struct cvfs_private *private = ntvfs->private_data; + struct async_info *a; + + /* find the matching request */ + for (a=private->pending;a;a=a->next) { + if (a->req == req) { + break; + } + } + + if (a == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + return smb_raw_ntcancel(a->c_req); +} + +/* + lock a byte range +*/ +static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lock *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (io->generic.level != RAW_LOCK_GENERIC && + private->map_generic) { + return ntvfs_map_lock(ntvfs, req, io); + } + SETUP_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_lock(private->tree, io); + } + + c_req = smb_raw_lock_send(private->tree, io); + SIMPLE_ASYNC_TAIL; +} + +/* + set info on a open file +*/ +static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_setfileinfo *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID_AND_FILE; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_setfileinfo(private->tree, io); + } + c_req = smb_raw_setfileinfo_send(private->tree, io); + + SIMPLE_ASYNC_TAIL; +} + + +/* + a handler for async fsinfo replies + */ +static void async_fsinfo(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* + return filesystem space info +*/ +static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_fsinfo *fs) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_fsinfo(private->tree, req, fs); + } + + c_req = smb_raw_fsinfo_send(private->tree, req, fs); + + ASYNC_RECV_TAIL(fs, async_fsinfo); +} + +/* + return print queue info +*/ +static NTSTATUS cvfs_lpq(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_lpq *lpq) +{ + return NT_STATUS_NOT_SUPPORTED; +} + +/* + list files in a directory matching a wildcard pattern +*/ +static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_first *io, + void *search_private, + bool (*callback)(void *, const union smb_search_data *)) +{ + struct cvfs_private *private = ntvfs->private_data; + + SETUP_PID; + + return smb_raw_search_first(private->tree, req, io, search_private, callback); +} + +/* continue a search */ +static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_next *io, + void *search_private, + bool (*callback)(void *, const union smb_search_data *)) +{ + struct cvfs_private *private = ntvfs->private_data; + + SETUP_PID; + + return smb_raw_search_next(private->tree, req, io, search_private, callback); +} + +/* close a search */ +static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, union smb_search_close *io) +{ + struct cvfs_private *private = ntvfs->private_data; + + SETUP_PID; + + return smb_raw_search_close(private->tree, io); +} + +/* + a handler for async trans2 replies + */ +static void async_trans2(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* raw trans2 */ +static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_trans2 *trans2) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + + if (private->map_trans2) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + SETUP_PID; + + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return smb_raw_trans2(private->tree, req, trans2); + } + + c_req = smb_raw_trans2_send(private->tree, trans2); + + ASYNC_RECV_TAIL(trans2, async_trans2); +} + + +/* SMBtrans - not used on file shares */ +static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + struct smb_trans2 *trans2) +{ + return NT_STATUS_ACCESS_DENIED; +} + +/* + a handler for async change notify replies + */ +static void async_changenotify(struct smbcli_request *c_req) +{ + struct async_info *async = c_req->async.private; + struct ntvfs_request *req = async->req; + req->async_states->status = smb_raw_changenotify_recv(c_req, req, async->parms); + talloc_free(async); + req->async_states->send_fn(req); +} + +/* change notify request - always async */ +static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_notify *io) +{ + struct cvfs_private *private = ntvfs->private_data; + struct smbcli_request *c_req; + int saved_timeout = private->transport->options.request_timeout; + struct cvfs_file *f; + + if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { + return NT_STATUS_NOT_IMPLEMENTED; + } + + SETUP_PID; + + f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); + if (!f) return NT_STATUS_INVALID_HANDLE; + io->nttrans.in.file.fnum = f->fnum; + + /* this request doesn't make sense unless its async */ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* we must not timeout on notify requests - they wait + forever */ + private->transport->options.request_timeout = 0; + + c_req = smb_raw_changenotify_send(private->tree, io); + + private->transport->options.request_timeout = saved_timeout; + + ASYNC_RECV_TAIL(io, async_changenotify); +} + +/* + initialise the CIFS->CIFS backend, registering ourselves with the ntvfs subsystem + */ +NTSTATUS ntvfs_smb2_init(void) +{ + NTSTATUS ret; + struct ntvfs_ops ops; + NTVFS_CURRENT_CRITICAL_SIZES(vers); + + ZERO_STRUCT(ops); + + /* fill in the name and type */ + ops.name = "smb2"; + ops.type = NTVFS_DISK; + + /* fill in all the operations */ + ops.connect = cvfs_connect; + ops.disconnect = cvfs_disconnect; + ops.unlink = cvfs_unlink; + ops.chkpath = cvfs_chkpath; + ops.qpathinfo = cvfs_qpathinfo; + ops.setpathinfo = cvfs_setpathinfo; + ops.open = cvfs_open; + ops.mkdir = cvfs_mkdir; + ops.rmdir = cvfs_rmdir; + ops.rename = cvfs_rename; + ops.copy = cvfs_copy; + ops.ioctl = cvfs_ioctl; + ops.read = cvfs_read; + ops.write = cvfs_write; + ops.seek = cvfs_seek; + ops.flush = cvfs_flush; + ops.close = cvfs_close; + ops.exit = cvfs_exit; + ops.lock = cvfs_lock; + ops.setfileinfo = cvfs_setfileinfo; + ops.qfileinfo = cvfs_qfileinfo; + ops.fsinfo = cvfs_fsinfo; + ops.lpq = cvfs_lpq; + ops.search_first = cvfs_search_first; + ops.search_next = cvfs_search_next; + ops.search_close = cvfs_search_close; + ops.trans = cvfs_trans; + ops.logoff = cvfs_logoff; + ops.async_setup = cvfs_async_setup; + ops.cancel = cvfs_cancel; + ops.notify = cvfs_notify; + ops.trans2 = cvfs_trans2; + + /* register ourselves with the NTVFS subsystem. We register + under the name 'smb2'. */ + ret = ntvfs_register(&ops, &vers); + + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0,("Failed to register SMB2 backend\n")); + } + + return ret; +} -- cgit From d9f47ba00b910ecbe031e635eeaf50b1c05a79cb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 15 May 2008 20:47:28 +1000 Subject: added handlers for connect, search_first and fsinfo. Directory listing in smbclient now works (This used to be commit 8007342061d77eb711af0652ecd38aec0d3cc9d1) --- source4/ntvfs/smb2/vfs_smb2.c | 377 +++++++++++++++++++++++++----------------- 1 file changed, 225 insertions(+), 152 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index f253fcecaf..6b0f3e62f4 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -37,6 +37,8 @@ #include "lib/util/dlinklist.h" #include "param/param.h" #include "libcli/resolve/resolve.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" struct cvfs_file { struct cvfs_file *prev, *next; @@ -46,13 +48,17 @@ struct cvfs_file { /* this is stored in ntvfs_private */ struct cvfs_private { - struct smbcli_tree *tree; + struct smb2_tree *tree; struct smbcli_transport *transport; struct ntvfs_module_context *ntvfs; struct async_info *pending; struct cvfs_file *files; - bool map_generic; - bool map_trans2; + + /* a handle on the root of the share */ + /* TODO: leaving this handle open could prevent other users + from opening the share with exclusive access. We probably + need to open it on demand */ + struct smb2_handle roothandle; }; @@ -61,13 +67,11 @@ struct async_info { struct async_info *next, *prev; struct cvfs_private *cvfs; struct ntvfs_request *req; - struct smbcli_request *c_req; + struct smb2_request *c_req; struct cvfs_file *f; void *parms; }; -#define SETUP_PID private->tree->session->pid = req->smbpid - #define SETUP_FILE_HERE(f) do { \ f = ntvfs_handle_get_backend_data(io->generic.in.file.ntvfs, ntvfs); \ if (!f) return NT_STATUS_INVALID_HANDLE; \ @@ -79,23 +83,14 @@ struct async_info { SETUP_FILE_HERE(f); \ } while (0) -#define SETUP_PID_AND_FILE do { \ - SETUP_PID; \ - SETUP_FILE; \ -} while (0) +#define SMB2_SERVER "smb2:server" +#define SMB2_USER "smb2:user" +#define SMB2_PASSWORD "smb2:password" +#define SMB2_DOMAIN "smb2:domain" +#define SMB2_SHARE "smb2:share" +#define SMB2_USE_MACHINE_ACCT "smb2:use-machine-account" -#define CIFS_SERVER "cifs:server" -#define CIFS_USER "cifs:user" -#define CIFS_PASSWORD "cifs:password" -#define CIFS_DOMAIN "cifs:domain" -#define CIFS_SHARE "cifs:share" -#define CIFS_USE_MACHINE_ACCT "cifs:use-machine-account" -#define CIFS_MAP_GENERIC "cifs:map-generic" -#define CIFS_MAP_TRANS2 "cifs:map-trans2" - -#define CIFS_USE_MACHINE_ACCT_DEFAULT false -#define CIFS_MAP_GENERIC_DEFAULT false -#define CIFS_MAP_TRANS2_DEFAULT true +#define SMB2_USE_MACHINE_ACCT_DEFAULT false /* a handler for oplock break events from the server - these need to be passed @@ -115,16 +110,44 @@ static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, uin } if (!h) { - DEBUG(5,("vfs_cifs: ignoring oplock break level %d for fnum %d\n", level, fnum)); + DEBUG(5,("vfs_smb2: ignoring oplock break level %d for fnum %d\n", level, fnum)); return true; } - DEBUG(5,("vfs_cifs: sending oplock break level %d for fnum %d\n", level, fnum)); + DEBUG(5,("vfs_smb2: sending oplock break level %d for fnum %d\n", level, fnum)); status = ntvfs_send_oplock_break(private->ntvfs, h, level); if (!NT_STATUS_IS_OK(status)) return false; return true; } +/* + return a handle to the root of the share +*/ +static NTSTATUS smb2_get_roothandle(struct smb2_tree *tree, struct smb2_handle *handle) +{ + struct smb2_create io; + NTSTATUS status; + + ZERO_STRUCT(io); + io.in.oplock_level = 0; + io.in.desired_access = SEC_STD_SYNCHRONIZE | SEC_DIR_READ_ATTRIBUTE | SEC_DIR_LIST; + io.in.file_attributes = 0; + io.in.create_disposition = NTCREATEX_DISP_OPEN; + io.in.share_access = + NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE| + NTCREATEX_SHARE_ACCESS_DELETE; + io.in.create_options = 0; + io.in.fname = NULL; + + status = smb2_create(tree, tree, &io); + NT_STATUS_NOT_OK_RETURN(status); + + *handle = io.out.file.handle; + + return NT_STATUS_OK; +} + /* connect to a share - used when a tree_connect operation comes in. */ @@ -134,9 +157,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, NTSTATUS status; struct cvfs_private *private; const char *host, *user, *pass, *domain, *remote_share; - struct smb_composite_connect io; struct composite_context *creq; struct share_config *scfg = ntvfs->ctx->config; + struct smb2_tree *tree; struct cli_credentials *credentials; bool machine_account; @@ -145,16 +168,16 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. */ - host = share_string_option(scfg, CIFS_SERVER, NULL); - user = share_string_option(scfg, CIFS_USER, NULL); - pass = share_string_option(scfg, CIFS_PASSWORD, NULL); - domain = share_string_option(scfg, CIFS_DOMAIN, NULL); - remote_share = share_string_option(scfg, CIFS_SHARE, NULL); + host = share_string_option(scfg, SMB2_SERVER, NULL); + user = share_string_option(scfg, SMB2_USER, NULL); + pass = share_string_option(scfg, SMB2_PASSWORD, NULL); + domain = share_string_option(scfg, SMB2_DOMAIN, NULL); + remote_share = share_string_option(scfg, SMB2_SHARE, NULL); if (!remote_share) { remote_share = sharename; } - machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); + machine_account = share_bool_option(scfg, SMB2_USE_MACHINE_ACCT, SMB2_USE_MACHINE_ACCT_DEFAULT); private = talloc_zero(ntvfs, struct cvfs_private); if (!private) { @@ -199,31 +222,19 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - /* connect to the server, using the smbd event context */ - io.in.dest_host = host; - io.in.dest_ports = lp_smb_ports(ntvfs->ctx->lp_ctx); - io.in.called_name = host; - io.in.credentials = credentials; - io.in.fallback_to_anonymous = false; - io.in.workgroup = lp_workgroup(ntvfs->ctx->lp_ctx); - io.in.service = remote_share; - io.in.service_type = "?????"; - lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); - - if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) { - io.in.options.use_level2_oplocks = false; - } + creq = smb2_connect_send(private, host, remote_share, + lp_resolve_context(ntvfs->ctx->lp_ctx), + credentials, + ntvfs->ctx->event_ctx); - creq = smb_composite_connect_send(&io, private, - lp_resolve_context(ntvfs->ctx->lp_ctx), - ntvfs->ctx->event_ctx); - status = smb_composite_connect_recv(creq, private); + status = smb2_connect_recv(creq, private, &tree); NT_STATUS_NOT_OK_RETURN(status); - private->tree = io.out.tree; + status = smb2_get_roothandle(tree, &private->roothandle); + NT_STATUS_NOT_OK_RETURN(status); + private->tree = tree; private->transport = private->tree->session->transport; - SETUP_PID; private->ntvfs = ntvfs; ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); @@ -232,12 +243,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); /* we need to receive oplock break requests from the server */ + /* TODO: enable oplocks smbcli_oplock_handler(private->transport, oplock_handler, private); - - private->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT); - - private->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT); - + */ return NT_STATUS_OK; } @@ -252,7 +260,7 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) /* first cleanup pending requests */ for (a=private->pending; a; a = an) { an = a->next; - smbcli_request_destroy(a->c_req); + smb2_request_destroy(a->c_req); talloc_free(a); } @@ -276,11 +284,13 @@ static int async_info_destructor(struct async_info *async) this handler can only be used for functions that don't return any parameters (those that just return a status code) */ -static void async_simple(struct smbcli_request *c_req) +static void async_simple(struct smb2_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; - req->async_states->status = smbcli_request_simple_recv(c_req); + + smb2_request_receive(c_req); + req->async_states->status = smb2_request_destroy(c_req); talloc_free(async); req->async_states->send_fn(req); } @@ -321,8 +331,7 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; /* see if the front end will allow us to perform this function asynchronously. */ if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { @@ -355,7 +364,7 @@ static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + SETUP_FILE; /* see if the front end will allow us to perform this function asynchronously. */ @@ -375,15 +384,31 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_chkpath *cp) { struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - SETUP_PID; - + struct smb2_request *c_req; + struct smb2_find f; + + /* SMB2 doesn't have a chkpath operation, and also doesn't + have a query path info call, so the best seems to be to do a + find call, using the roothandle we established at connect + time */ + ZERO_STRUCT(f); + f.in.file.handle = private->roothandle; + f.in.level = SMB2_FIND_DIRECTORY_INFO; + f.in.pattern = cp->chkpath.in.path; + /* SMB2 find doesn't accept \ or the empty string - this is the best + approximation */ + if (strcmp(f.in.pattern, "\\") == 0 || + strcmp(f.in.pattern, "") == 0) { + f.in.pattern = "?"; + } + f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE | SMB2_CONTINUE_FLAG_RESTART; + f.in.max_response_size = 0x1000; + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_chkpath(private->tree, cp); + return smb2_find(private->tree, req, &f); } - c_req = smb_raw_chkpath_send(private->tree, cp); + c_req = smb2_find_send(private->tree, &f); SIMPLE_ASYNC_TAIL; } @@ -395,6 +420,7 @@ static void async_qpathinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; + return NT_STATUS_NOT_IMPLEMENTED; req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); talloc_free(async); req->async_states->send_fn(req); @@ -409,8 +435,6 @@ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_pathinfo(private->tree, req, info); } @@ -427,6 +451,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; + return NT_STATUS_NOT_IMPLEMENTED; req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); talloc_free(async); req->async_states->send_fn(req); @@ -441,7 +466,8 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + return NT_STATUS_NOT_IMPLEMENTED; + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_fileinfo(private->tree, req, io); @@ -462,8 +488,7 @@ static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setpathinfo(private->tree, st); } @@ -511,10 +536,8 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct cvfs_file *f; NTSTATUS status; - SETUP_PID; - - if (io->generic.level != RAW_OPEN_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_OPEN_GENERIC) { return ntvfs_map_open(ntvfs, req, io); } @@ -556,8 +579,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_mkdir(private->tree, md); } @@ -576,8 +598,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_rmdir(private->tree, rd); } @@ -595,7 +616,7 @@ static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; if (ren->nttrans.level == RAW_RENAME_NTTRANS) { struct cvfs_file *f; @@ -643,10 +664,8 @@ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - - if (io->generic.level != RAW_READ_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_READ_GENERIC) { return ntvfs_map_read(ntvfs, req, io); } @@ -682,10 +701,8 @@ static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - - if (io->generic.level != RAW_WRITE_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_WRITE_GENERIC) { return ntvfs_map_write(ntvfs, req, io); } SETUP_FILE; @@ -721,7 +738,8 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + return NT_STATUS_NOT_IMPLEMENTED; + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_seek(private->tree, io); @@ -742,7 +760,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; switch (io->generic.level) { case RAW_FLUSH_FLUSH: SETUP_FILE; @@ -773,10 +791,8 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct smbcli_request *c_req; struct cvfs_file *f; - SETUP_PID; - - if (io->generic.level != RAW_CLOSE_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_CLOSE_GENERIC) { return ntvfs_map_close(ntvfs, req, io); } SETUP_FILE_HERE(f); @@ -804,8 +820,7 @@ static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - + return NT_STATUS_NOT_IMPLEMENTED; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_exit(private->tree->session); } @@ -844,6 +859,7 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct async_info *a; + return NT_STATUS_NOT_IMPLEMENTED; /* find the matching request */ for (a=private->pending;a;a=a->next) { if (a->req == req) { @@ -867,10 +883,8 @@ static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID; - - if (io->generic.level != RAW_LOCK_GENERIC && - private->map_generic) { + return NT_STATUS_NOT_IMPLEMENTED; + if (io->generic.level != RAW_LOCK_GENERIC) { return ntvfs_map_lock(ntvfs, req, io); } SETUP_FILE; @@ -893,7 +907,8 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; - SETUP_PID_AND_FILE; + return NT_STATUS_NOT_IMPLEMENTED; + SETUP_FILE; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { return smb_raw_setfileinfo(private->tree, io); @@ -907,11 +922,11 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* a handler for async fsinfo replies */ -static void async_fsinfo(struct smbcli_request *c_req) +static void async_fsinfo(struct smb2_request *c_req) { struct async_info *async = c_req->async.private; struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_fsinfo_recv(c_req, req, async->parms); + req->async_states->status = smb2_getinfo_fs_recv(c_req, req, async->parms); talloc_free(async); req->async_states->send_fn(req); } @@ -923,15 +938,49 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fsinfo *fs) { struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; + struct smb2_request *c_req; + enum smb_fsinfo_level level = fs->generic.level; + + switch (level) { + /* some levels go straight through */ + case RAW_QFS_VOLUME_INFORMATION: + case RAW_QFS_SIZE_INFORMATION: + case RAW_QFS_DEVICE_INFORMATION: + case RAW_QFS_ATTRIBUTE_INFORMATION: + case RAW_QFS_QUOTA_INFORMATION: + case RAW_QFS_FULL_SIZE_INFORMATION: + case RAW_QFS_OBJECTID_INFORMATION: + break; - SETUP_PID; + /* some get mapped */ + case RAW_QFS_VOLUME_INFO: + level = RAW_QFS_VOLUME_INFORMATION; + break; + case RAW_QFS_SIZE_INFO: + level = RAW_QFS_SIZE_INFORMATION; + break; + case RAW_QFS_DEVICE_INFO: + level = RAW_QFS_DEVICE_INFORMATION; + break; + case RAW_QFS_ATTRIBUTE_INFO: + level = RAW_QFS_ATTRIBUTE_INFO; + break; + + default: + /* the rest get refused for now */ + DEBUG(0,("fsinfo level %u not possible on SMB2\n", + (unsigned)fs->generic.level)); + break; + } + + fs->generic.level = level; + fs->generic.handle = private->roothandle; if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_fsinfo(private->tree, req, fs); + return smb2_getinfo_fs(private->tree, req, fs); } - c_req = smb_raw_fsinfo_send(private->tree, req, fs); + c_req = smb2_getinfo_fs_send(private->tree, fs); ASYNC_RECV_TAIL(fs, async_fsinfo); } @@ -954,10 +1003,72 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, bool (*callback)(void *, const union smb_search_data *)) { struct cvfs_private *private = ntvfs->private_data; + struct smb2_find f; + enum smb_search_data_level smb2_level; + uint32_t continue_flags = 0; + uint_t count, i; + union smb_search_data *data; + NTSTATUS status; + + if (io->generic.level != RAW_SEARCH_TRANS2) { + DEBUG(0,("We only support trans2 search in smb2 backend\n")); + return NT_STATUS_NOT_SUPPORTED; + } + + switch (io->generic.data_level) { + case RAW_SEARCH_DATA_DIRECTORY_INFO: + smb2_level = SMB2_FIND_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO: + smb2_level = SMB2_FIND_FULL_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO: + smb2_level = SMB2_FIND_BOTH_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_NAME_INFO: + smb2_level = SMB2_FIND_NAME_INFO; + break; + case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO: + smb2_level = SMB2_FIND_ID_FULL_DIRECTORY_INFO; + break; + case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: + smb2_level = SMB2_FIND_ID_BOTH_DIRECTORY_INFO; + break; + default: + DEBUG(0,("Unsupported search level %u for smb2 backend\n", + (unsigned)io->generic.data_level)); + return NT_STATUS_INVALID_INFO_CLASS; + } + + /* we do the search on the roothandle. This only works because + search is synchronous, otherwise we'd have no way to + distinguish multiple searches happening at once + */ + ZERO_STRUCT(f); + f.in.file.handle = private->roothandle; + f.in.level = smb2_level; + f.in.pattern = io->t2ffirst.in.pattern; + while (f.in.pattern[0] == '\\') { + f.in.pattern++; + } + f.in.continue_flags = 0; + f.in.max_response_size = 0x10000; + + status = smb2_find_level(private->tree, req, &f, &count, &data); + NT_STATUS_NOT_OK_RETURN(status); - SETUP_PID; + for (i=0;it2ffirst.out.handle = 0; + io->t2ffirst.out.count = i; + /* TODO: fix end_of_file */ + io->t2ffirst.out.end_of_search = 1; - return smb_raw_search_first(private->tree, req, io, search_private, callback); + talloc_free(data); + + return NT_STATUS_OK; } /* continue a search */ @@ -968,7 +1079,7 @@ static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; return smb_raw_search_next(private->tree, req, io, search_private, callback); } @@ -979,47 +1090,11 @@ static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, { struct cvfs_private *private = ntvfs->private_data; - SETUP_PID; + return NT_STATUS_NOT_IMPLEMENTED; return smb_raw_search_close(private->tree, io); } -/* - a handler for async trans2 replies - */ -static void async_trans2(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_trans2_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - -/* raw trans2 */ -static NTSTATUS cvfs_trans2(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - struct smb_trans2 *trans2) -{ - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - if (private->map_trans2) { - return NT_STATUS_NOT_IMPLEMENTED; - } - - SETUP_PID; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_trans2(private->tree, req, trans2); - } - - c_req = smb_raw_trans2_send(private->tree, trans2); - - ASYNC_RECV_TAIL(trans2, async_trans2); -} - - /* SMBtrans - not used on file shares */ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, @@ -1050,12 +1125,11 @@ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, int saved_timeout = private->transport->options.request_timeout; struct cvfs_file *f; + return NT_STATUS_NOT_IMPLEMENTED; if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { return NT_STATUS_NOT_IMPLEMENTED; } - SETUP_PID; - f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); if (!f) return NT_STATUS_INVALID_HANDLE; io->nttrans.in.file.fnum = f->fnum; @@ -1123,7 +1197,6 @@ NTSTATUS ntvfs_smb2_init(void) ops.async_setup = cvfs_async_setup; ops.cancel = cvfs_cancel; ops.notify = cvfs_notify; - ops.trans2 = cvfs_trans2; /* register ourselves with the NTVFS subsystem. We register under the name 'smb2'. */ -- cgit From 9b177f8d586830887282dc30e712bae0e9a06f33 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 May 2008 15:01:31 +1000 Subject: added SMB2 proxying for unlink (This used to be commit a5459bd88092863668db199953458fe97162240c) --- source4/ntvfs/smb2/vfs_smb2.c | 470 ++++-------------------------------------- 1 file changed, 43 insertions(+), 427 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 6b0f3e62f4..13dbb4ea2e 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -30,6 +30,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" #include "libcli/raw/raw_proto.h" +#include "libcli/composite/composite.h" #include "libcli/smb_composite/smb_composite.h" #include "auth/auth.h" #include "auth/credentials/credentials.h" @@ -49,7 +50,7 @@ struct cvfs_file { /* this is stored in ntvfs_private */ struct cvfs_private { struct smb2_tree *tree; - struct smbcli_transport *transport; + struct smb2_transport *transport; struct ntvfs_module_context *ntvfs; struct async_info *pending; struct cvfs_file *files; @@ -67,7 +68,8 @@ struct async_info { struct async_info *next, *prev; struct cvfs_private *cvfs; struct ntvfs_request *req; - struct smb2_request *c_req; + void *c_req; + struct composite_context *c_comp; struct cvfs_file *f; void *parms; }; @@ -260,7 +262,7 @@ static NTSTATUS cvfs_disconnect(struct ntvfs_module_context *ntvfs) /* first cleanup pending requests */ for (a=private->pending; a; a = an) { an = a->next; - smb2_request_destroy(a->c_req); + talloc_free(a->c_req); talloc_free(a); } @@ -280,13 +282,13 @@ static int async_info_destructor(struct async_info *async) } /* - a handler for simple async replies + a handler for simple async SMB2 replies this handler can only be used for functions that don't return any parameters (those that just return a status code) */ -static void async_simple(struct smb2_request *c_req) +static void async_simple_smb2(struct smb2_request *c_req) { - struct async_info *async = c_req->async.private; + struct async_info *async = c_req->async.private_data; struct ntvfs_request *req = async->req; smb2_request_receive(c_req); @@ -295,6 +297,21 @@ static void async_simple(struct smb2_request *c_req) req->async_states->send_fn(req); } +/* + a handler for simple async composite replies + this handler can only be used for functions that don't return any + parameters (those that just return a status code) + */ +static void async_simple_composite(struct composite_context *c_req) +{ + struct async_info *async = c_req->async.private_data; + struct ntvfs_request *req = async->req; + + req->async_states->status = composite_wait_free(c_req); + talloc_free(async); + req->async_states->send_fn(req); +} + /* save some typing for the simple functions */ #define ASYNC_RECV_TAIL_F(io, async_fn, file) do { \ @@ -309,7 +326,7 @@ static void async_simple(struct smb2_request *c_req) async->cvfs = private; \ async->c_req = c_req; \ DLIST_ADD(private->pending, async); \ - c_req->async.private = async; \ + c_req->async.private_data = async; \ talloc_set_destructor(async, async_info_destructor); \ } \ c_req->async.fn = async_fn; \ @@ -319,7 +336,15 @@ static void async_simple(struct smb2_request *c_req) #define ASYNC_RECV_TAIL(io, async_fn) ASYNC_RECV_TAIL_F(io, async_fn, NULL) -#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple) +#define SIMPLE_ASYNC_TAIL ASYNC_RECV_TAIL(NULL, async_simple_smb2) +#define SIMPLE_COMPOSITE_TAIL ASYNC_RECV_TAIL(NULL, async_simple_composite) + +#define CHECK_ASYNC(req) do { \ + if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { \ + DEBUG(0,("SMB2 proxy backend does not support sync operation at %s\n", \ + __location__)); \ + return NT_STATUS_NOT_IMPLEMENTED; \ + }} while (0) /* delete a file - the dirtype specifies the file types to include in the search. @@ -329,30 +354,13 @@ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_unlink *unl) { struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; + struct composite_context *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - /* see if the front end will allow us to perform this - function asynchronously. */ - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_unlink(private->tree, unl); - } + CHECK_ASYNC(req); - c_req = smb_raw_unlink_send(private->tree, unl); + c_req = smb2_composite_unlink_send(private->tree, unl); - SIMPLE_ASYNC_TAIL; -} - -/* - a handler for async ioctl replies - */ -static void async_ioctl(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_ioctl_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); + SIMPLE_COMPOSITE_TAIL; } /* @@ -361,20 +369,7 @@ static void async_ioctl(struct smbcli_request *c_req) static NTSTATUS cvfs_ioctl(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_ioctl *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - SETUP_FILE; - - /* see if the front end will allow us to perform this - function asynchronously. */ - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_ioctl(private->tree, req, io); - } - - c_req = smb_raw_ioctl_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_ioctl); + return NT_STATUS_NOT_IMPLEMENTED; } /* @@ -386,6 +381,8 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smb2_request *c_req; struct smb2_find f; + + CHECK_ASYNC(req); /* SMB2 doesn't have a chkpath operation, and also doesn't have a query path info call, so the best seems to be to do a @@ -404,57 +401,18 @@ static NTSTATUS cvfs_chkpath(struct ntvfs_module_context *ntvfs, f.in.continue_flags = SMB2_CONTINUE_FLAG_SINGLE | SMB2_CONTINUE_FLAG_RESTART; f.in.max_response_size = 0x1000; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb2_find(private->tree, req, &f); - } - c_req = smb2_find_send(private->tree, &f); SIMPLE_ASYNC_TAIL; } -/* - a handler for async qpathinfo replies - */ -static void async_qpathinfo(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - return NT_STATUS_NOT_IMPLEMENTED; - req->async_states->status = smb_raw_pathinfo_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - /* return info on a pathname */ static NTSTATUS cvfs_qpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *info) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_pathinfo(private->tree, req, info); - } - - c_req = smb_raw_pathinfo_send(private->tree, info); - - ASYNC_RECV_TAIL(info, async_qpathinfo); -} - -/* - a handler for async qfileinfo replies - */ -static void async_qfileinfo(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; return NT_STATUS_NOT_IMPLEMENTED; - req->async_states->status = smb_raw_fileinfo_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); } /* @@ -463,19 +421,7 @@ static void async_qfileinfo(struct smbcli_request *c_req) static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_fileinfo *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_fileinfo(private->tree, req, io); - } - - c_req = smb_raw_fileinfo_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_qfileinfo); } @@ -485,89 +431,17 @@ static NTSTATUS cvfs_qfileinfo(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *st) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_setpathinfo(private->tree, st); - } - - c_req = smb_raw_setpathinfo_send(private->tree, st); - - SIMPLE_ASYNC_TAIL; } -/* - a handler for async open replies - */ -static void async_open(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct cvfs_private *cvfs = async->cvfs; - struct ntvfs_request *req = async->req; - struct cvfs_file *f = async->f; - union smb_open *io = async->parms; - union smb_handle *file; - talloc_free(async); - req->async_states->status = smb_raw_open_recv(c_req, req, io); - SMB_OPEN_OUT_FILE(io, file); - f->fnum = file->fnum; - file->ntvfs = NULL; - if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; - req->async_states->status = ntvfs_handle_set_backend_data(f->h, cvfs->ntvfs, f); - if (!NT_STATUS_IS_OK(req->async_states->status)) goto failed; - file->ntvfs = f->h; - DLIST_ADD(cvfs->files, f); -failed: - req->async_states->send_fn(req); -} - /* open a file */ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - struct ntvfs_handle *h; - struct cvfs_file *f; - NTSTATUS status; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_OPEN_GENERIC) { - return ntvfs_map_open(ntvfs, req, io); - } - - status = ntvfs_handle_new(ntvfs, req, &h); - NT_STATUS_NOT_OK_RETURN(status); - - f = talloc_zero(h, struct cvfs_file); - NT_STATUS_HAVE_NO_MEMORY(f); - f->h = h; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - union smb_handle *file; - - status = smb_raw_open(private->tree, req, io); - NT_STATUS_NOT_OK_RETURN(status); - - SMB_OPEN_OUT_FILE(io, file); - f->fnum = file->fnum; - file->ntvfs = NULL; - status = ntvfs_handle_set_backend_data(f->h, private->ntvfs, f); - NT_STATUS_NOT_OK_RETURN(status); - file->ntvfs = f->h; - DLIST_ADD(private->files, f); - - return NT_STATUS_OK; - } - - c_req = smb_raw_open_send(private->tree, io); - - ASYNC_RECV_TAIL_F(io, async_open, f); } /* @@ -576,17 +450,7 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_mkdir *md) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_mkdir(private->tree, md); - } - - c_req = smb_raw_mkdir_send(private->tree, md); - - SIMPLE_ASYNC_TAIL; } /* @@ -595,16 +459,7 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_rmdir *rd) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_rmdir(private->tree, rd); - } - c_req = smb_raw_rmdir_send(private->tree, rd); - - SIMPLE_ASYNC_TAIL; } /* @@ -613,25 +468,7 @@ static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_rename(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_rename *ren) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - - if (ren->nttrans.level == RAW_RENAME_NTTRANS) { - struct cvfs_file *f; - f = ntvfs_handle_get_backend_data(ren->nttrans.in.file.ntvfs, ntvfs); - if (!f) return NT_STATUS_INVALID_HANDLE; - ren->nttrans.in.file.fnum = f->fnum; - } - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_rename(private->tree, ren); - } - - c_req = smb_raw_rename_send(private->tree, ren); - - SIMPLE_ASYNC_TAIL; } /* @@ -643,53 +480,13 @@ static NTSTATUS cvfs_copy(struct ntvfs_module_context *ntvfs, return NT_STATUS_NOT_SUPPORTED; } -/* - a handler for async read replies - */ -static void async_read(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_read_recv(c_req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - /* read from a file */ static NTSTATUS cvfs_read(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_read *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_READ_GENERIC) { - return ntvfs_map_read(ntvfs, req, io); - } - - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_read(private->tree, io); - } - - c_req = smb_raw_read_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_read); -} - -/* - a handler for async write replies - */ -static void async_write(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_write_recv(c_req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); } /* @@ -698,34 +495,7 @@ static void async_write(struct smbcli_request *c_req) static NTSTATUS cvfs_write(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_write *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_WRITE_GENERIC) { - return ntvfs_map_write(ntvfs, req, io); - } - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_write(private->tree, io); - } - - c_req = smb_raw_write_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_write); -} - -/* - a handler for async seek replies - */ -static void async_seek(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_seek_recv(c_req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); } /* @@ -735,19 +505,7 @@ static NTSTATUS cvfs_seek(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_seek *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_seek(private->tree, io); - } - - c_req = smb_raw_seek_send(private->tree, io); - - ASYNC_RECV_TAIL(io, async_seek); } /* @@ -757,28 +515,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_flush *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - switch (io->generic.level) { - case RAW_FLUSH_FLUSH: - SETUP_FILE; - break; - case RAW_FLUSH_ALL: - io->generic.in.file.fnum = 0xFFFF; - break; - case RAW_FLUSH_SMB2: - return NT_STATUS_INVALID_LEVEL; - } - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_flush(private->tree, io); - } - - c_req = smb_raw_flush_send(private->tree, io); - - SIMPLE_ASYNC_TAIL; } /* @@ -787,28 +524,7 @@ static NTSTATUS cvfs_flush(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_close *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - struct cvfs_file *f; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_CLOSE_GENERIC) { - return ntvfs_map_close(ntvfs, req, io); - } - SETUP_FILE_HERE(f); - /* Note, we aren't free-ing f, or it's h here. Should we? - even if file-close fails, we'll remove it from the list, - what else would we do? Maybe we should not remove until - after the proxied call completes? */ - DLIST_REMOVE(private->files, f); - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_close(private->tree, io); - } - - c_req = smb_raw_close_send(private->tree, io); - - SIMPLE_ASYNC_TAIL; } /* @@ -817,17 +533,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_exit(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_exit(private->tree->session); - } - - c_req = smb_raw_exit_send(private->tree->session); - - SIMPLE_ASYNC_TAIL; } /* @@ -856,22 +562,7 @@ static NTSTATUS cvfs_async_setup(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req) { - struct cvfs_private *private = ntvfs->private_data; - struct async_info *a; - return NT_STATUS_NOT_IMPLEMENTED; - /* find the matching request */ - for (a=private->pending;a;a=a->next) { - if (a->req == req) { - break; - } - } - - if (a == NULL) { - return NT_STATUS_INVALID_PARAMETER; - } - - return smb_raw_ntcancel(a->c_req); } /* @@ -880,21 +571,7 @@ static NTSTATUS cvfs_cancel(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_lock(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_lock *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->generic.level != RAW_LOCK_GENERIC) { - return ntvfs_map_lock(ntvfs, req, io); - } - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_lock(private->tree, io); - } - - c_req = smb_raw_lock_send(private->tree, io); - SIMPLE_ASYNC_TAIL; } /* @@ -904,18 +581,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_setfileinfo *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - return NT_STATUS_NOT_IMPLEMENTED; - SETUP_FILE; - - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb_raw_setfileinfo(private->tree, io); - } - c_req = smb_raw_setfileinfo_send(private->tree, io); - - SIMPLE_ASYNC_TAIL; } @@ -924,7 +590,7 @@ static NTSTATUS cvfs_setfileinfo(struct ntvfs_module_context *ntvfs, */ static void async_fsinfo(struct smb2_request *c_req) { - struct async_info *async = c_req->async.private; + struct async_info *async = c_req->async.private_data; struct ntvfs_request *req = async->req; req->async_states->status = smb2_getinfo_fs_recv(c_req, req, async->parms); talloc_free(async); @@ -941,6 +607,8 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, struct smb2_request *c_req; enum smb_fsinfo_level level = fs->generic.level; + CHECK_ASYNC(req); + switch (level) { /* some levels go straight through */ case RAW_QFS_VOLUME_INFORMATION: @@ -976,10 +644,6 @@ static NTSTATUS cvfs_fsinfo(struct ntvfs_module_context *ntvfs, fs->generic.level = level; fs->generic.handle = private->roothandle; - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return smb2_getinfo_fs(private->tree, req, fs); - } - c_req = smb2_getinfo_fs_send(private->tree, fs); ASYNC_RECV_TAIL(fs, async_fsinfo); @@ -1005,7 +669,6 @@ static NTSTATUS cvfs_search_first(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smb2_find f; enum smb_search_data_level smb2_level; - uint32_t continue_flags = 0; uint_t count, i; union smb_search_data *data; NTSTATUS status; @@ -1077,22 +740,14 @@ static NTSTATUS cvfs_search_next(struct ntvfs_module_context *ntvfs, void *search_private, bool (*callback)(void *, const union smb_search_data *)) { - struct cvfs_private *private = ntvfs->private_data; - return NT_STATUS_NOT_IMPLEMENTED; - - return smb_raw_search_next(private->tree, req, io, search_private, callback); } /* close a search */ static NTSTATUS cvfs_search_close(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_search_close *io) { - struct cvfs_private *private = ntvfs->private_data; - return NT_STATUS_NOT_IMPLEMENTED; - - return smb_raw_search_close(private->tree, io); } /* SMBtrans - not used on file shares */ @@ -1103,51 +758,12 @@ static NTSTATUS cvfs_trans(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -/* - a handler for async change notify replies - */ -static void async_changenotify(struct smbcli_request *c_req) -{ - struct async_info *async = c_req->async.private; - struct ntvfs_request *req = async->req; - req->async_states->status = smb_raw_changenotify_recv(c_req, req, async->parms); - talloc_free(async); - req->async_states->send_fn(req); -} - /* change notify request - always async */ static NTSTATUS cvfs_notify(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_notify *io) { - struct cvfs_private *private = ntvfs->private_data; - struct smbcli_request *c_req; - int saved_timeout = private->transport->options.request_timeout; - struct cvfs_file *f; - return NT_STATUS_NOT_IMPLEMENTED; - if (io->nttrans.level != RAW_NOTIFY_NTTRANS) { - return NT_STATUS_NOT_IMPLEMENTED; - } - - f = ntvfs_handle_get_backend_data(io->nttrans.in.file.ntvfs, ntvfs); - if (!f) return NT_STATUS_INVALID_HANDLE; - io->nttrans.in.file.fnum = f->fnum; - - /* this request doesn't make sense unless its async */ - if (!(req->async_states->state & NTVFS_ASYNC_STATE_MAY_ASYNC)) { - return NT_STATUS_INVALID_PARAMETER; - } - - /* we must not timeout on notify requests - they wait - forever */ - private->transport->options.request_timeout = 0; - - c_req = smb_raw_changenotify_send(private->tree, io); - - private->transport->options.request_timeout = saved_timeout; - - ASYNC_RECV_TAIL(io, async_changenotify); } /* -- cgit From 03643aec88244d976da394521adbd29a31339569 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 19:54:27 +0200 Subject: Use variables for source directory in a couple more places. (This used to be commit c41bd3005f5f0b9cfd3709fc9217b4a401d265b4) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/config.mk | 16 ++++++++-------- source4/ntvfs/posix/config.mk | 8 ++++---- source4/ntvfs/sysdep/config.mk | 8 ++++---- source4/ntvfs/unixuid/config.mk | 2 +- 5 files changed, 18 insertions(+), 18 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index c66257b73f..f4518698ea 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -7,5 +7,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common ################################################ -ntvfs_common_OBJ_FILES = $(addprefix ntvfs/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) +ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 93cbf64d8f..81c295ef67 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -14,7 +14,7 @@ PRIVATE_DEPENDENCIES = \ # End MODULE ntvfs_cifs ################################################ -ntvfs_cifs_OBJ_FILES = ntvfs/cifs/vfs_cifs.o +ntvfs_cifs_OBJ_FILES = $(ntvfssrcdir)/cifs/vfs_cifs.o ################################################ # Start MODULE ntvfs_simple @@ -25,7 +25,7 @@ PRIVATE_PROTO_HEADER = simple/proto.h # End MODULE ntvfs_simple ################################################ -ntvfs_simple_OBJ_FILES = $(addprefix ntvfs/simple/, vfs_simple.o svfs_util.o) +ntvfs_simple_OBJ_FILES = $(addprefix $(ntvfssrcdir)/simple/, vfs_simple.o svfs_util.o) ################################################ # Start MODULE ntvfs_cifsposix @@ -38,7 +38,7 @@ PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h ################################################ ntvfs_cifsposix_OBJ_FILES = \ - $(addprefix ntvfs/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) + $(addprefix $(ntvfssrcdir)/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) ################################################ # Start MODULE ntvfs_print @@ -48,7 +48,7 @@ SUBSYSTEM = ntvfs # End MODULE ntvfs_print ################################################ -ntvfs_print_OBJ_FILES = ntvfs/print/vfs_print.o +ntvfs_print_OBJ_FILES = $(ntvfssrcdir)/print/vfs_print.o ################################################ # Start MODULE ntvfs_ipc @@ -60,7 +60,7 @@ PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ -ntvfs_ipc_OBJ_FILES = $(addprefix ntvfs/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) +ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) ################################################ # Start MODULE ntvfs_nbench @@ -70,16 +70,16 @@ INIT_FUNCTION = ntvfs_nbench_init # End MODULE ntvfs_nbench ################################################ -ntvfs_nbench_OBJ_FILES = ntvfs/nbench/vfs_nbench.o +ntvfs_nbench_OBJ_FILES = $(ntvfssrcdir)/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] PRIVATE_PROTO_HEADER = ntvfs_proto.h -ntvfs_OBJ_FILES = $(addprefix ntvfs/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) +ntvfs_OBJ_FILES = $(addprefix $(ntvfssrcdir)/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) -# PUBLIC_HEADERS += ntvfs/ntvfs.h +# PUBLIC_HEADERS += $(ntvfssrcdir)/ntvfs.h # # End SUBSYSTEM NTVFS ################################################ diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 865a0ffd4a..256ad44b59 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -7,7 +7,7 @@ PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix # End MODULE pvfs_acl_xattr ################################################ -pvfs_acl_xattr_OBJ_FILES = ntvfs/posix/pvfs_acl_xattr.o +pvfs_acl_xattr_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_xattr.o ################################################ # Start MODULE pvfs_acl_nfs4 @@ -18,7 +18,7 @@ PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix # End MODULE pvfs_acl_nfs4 ################################################ -pvfs_acl_nfs4_OBJ_FILES = ntvfs/posix/pvfs_acl_nfs4.o +pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o ################################################ [MODULE::pvfs_aio] @@ -26,7 +26,7 @@ SUBSYSTEM = ntvfs PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ -pvfs_aio_OBJ_FILES = ntvfs/posix/pvfs_aio.o +pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o ################################################ # Start MODULE ntvfs_posix @@ -41,7 +41,7 @@ PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_ai # End MODULE ntvfs_posix ################################################ -ntvfs_posix_OBJ_FILES = $(addprefix ntvfs/posix/, \ +ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ vfs_posix.o \ pvfs_util.o \ pvfs_search.o \ diff --git a/source4/ntvfs/sysdep/config.mk b/source4/ntvfs/sysdep/config.mk index 68be660049..1122d5c39d 100644 --- a/source4/ntvfs/sysdep/config.mk +++ b/source4/ntvfs/sysdep/config.mk @@ -6,7 +6,7 @@ INIT_FUNCTION = sys_notify_inotify_init # End MODULE sys_notify_inotify ################################################ -sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o +sys_notify_inotify_OBJ_FILES = $(ntvfssrcdir)/sysdep/inotify.o ################################################ # Start SUBSYSTEM sys_notify @@ -14,12 +14,12 @@ sys_notify_inotify_OBJ_FILES = ntvfs/sysdep/inotify.o # End SUBSYSTEM sys_notify ################################################ -sys_notify_OBJ_FILES = ntvfs/sysdep/sys_notify.o +sys_notify_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_notify.o [SUBSYSTEM::sys_lease_linux] -sys_lease_linux_OBJ_FILES = ntvfs/sysdep/sys_lease_linux.o +sys_lease_linux_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_lease_linux.o [SUBSYSTEM::sys_lease] -sys_lease_OBJ_FILES = ntvfs/sysdep/sys_lease.o +sys_lease_OBJ_FILES = $(ntvfssrcdir)/sysdep/sys_lease.o diff --git a/source4/ntvfs/unixuid/config.mk b/source4/ntvfs/unixuid/config.mk index 968e56bde4..6377657cec 100644 --- a/source4/ntvfs/unixuid/config.mk +++ b/source4/ntvfs/unixuid/config.mk @@ -7,4 +7,4 @@ PRIVATE_DEPENDENCIES = SAMDB NSS_WRAPPER # End MODULE ntvfs_unixuid ################################################ -ntvfs_unixuid_OBJ_FILES = ntvfs/unixuid/vfs_unixuid.o +ntvfs_unixuid_OBJ_FILES = $(ntvfssrcdir)/unixuid/vfs_unixuid.o -- cgit From 4c8756f147f8b9a2806fd76e4cb06bb99d391516 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 22:30:08 +0200 Subject: Create prototype headers from Makefile directory, without smb_build in the middle. (This used to be commit f4a77b96f9c17d853348b70794026e5b9e384942) --- source4/ntvfs/common/config.mk | 3 ++- source4/ntvfs/config.mk | 12 ++++++++---- source4/ntvfs/posix/config.mk | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index f4518698ea..0771733eff 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -1,7 +1,6 @@ ################################################ # Start LIBRARY ntvfs_common [SUBSYSTEM::ntvfs_common] -PRIVATE_PROTO_HEADER = proto.h PUBLIC_DEPENDENCIES = NDR_OPENDB NDR_NOTIFY sys_notify sys_lease share LIBDBWRAP PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb # End LIBRARY ntvfs_common @@ -9,3 +8,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) +$(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c)) + diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index 81c295ef67..aa952e1017 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -21,25 +21,27 @@ ntvfs_cifs_OBJ_FILES = $(ntvfssrcdir)/cifs/vfs_cifs.o [MODULE::ntvfs_simple] INIT_FUNCTION = ntvfs_simple_init SUBSYSTEM = ntvfs -PRIVATE_PROTO_HEADER = simple/proto.h # End MODULE ntvfs_simple ################################################ ntvfs_simple_OBJ_FILES = $(addprefix $(ntvfssrcdir)/simple/, vfs_simple.o svfs_util.o) +$(call proto_header_template,$(ntvfssrcdir)/simple/proto.h,$(ntvfs_simple_OBJ_FILES:.o=.c)) + ################################################ # Start MODULE ntvfs_cifsposix [MODULE::ntvfs_cifsposix] #ENABLE = NO INIT_FUNCTION = ntvfs_cifs_posix_init SUBSYSTEM = ntvfs -PRIVATE_PROTO_HEADER = cifs_posix_cli/proto.h # End MODULE ntvfs_cifsposix ################################################ ntvfs_cifsposix_OBJ_FILES = \ $(addprefix $(ntvfssrcdir)/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) +$(call proto_header_template,$(ntvfssrcdir)/cifs_posix_cli/proto.h,$(ntvfs_cifsposix_OBJ_FILES:.o=.c)) + ################################################ # Start MODULE ntvfs_print [MODULE::ntvfs_print] @@ -55,13 +57,14 @@ ntvfs_print_OBJ_FILES = $(ntvfssrcdir)/print/vfs_print.o [MODULE::ntvfs_ipc] SUBSYSTEM = ntvfs INIT_FUNCTION = ntvfs_ipc_init -PRIVATE_PROTO_HEADER = ipc/proto.h PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON # End MODULE ntvfs_ipc ################################################ ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) +$(call proto_header_template,$(ntvssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES)) + ################################################ # Start MODULE ntvfs_nbench [MODULE::ntvfs_nbench] @@ -75,10 +78,11 @@ ntvfs_nbench_OBJ_FILES = $(ntvfssrcdir)/nbench/vfs_nbench.o ################################################ # Start SUBSYSTEM NTVFS [SUBSYSTEM::ntvfs] -PRIVATE_PROTO_HEADER = ntvfs_proto.h ntvfs_OBJ_FILES = $(addprefix $(ntvfssrcdir)/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) +$(call proto_header_template,$(ntvfssrcdir)/ntvfs_proto.h,$(ntvfs_OBJ_FILES:.o=.c)) + # PUBLIC_HEADERS += $(ntvfssrcdir)/ntvfs.h # # End SUBSYSTEM NTVFS diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 256ad44b59..5d90942b12 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -34,7 +34,6 @@ pvfs_aio_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_aio.o SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init -PRIVATE_PROTO_HEADER = vfs_posix_proto.h #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio \ LIBWBCLIENT @@ -71,3 +70,5 @@ ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ xattr_system.o \ xattr_tdb.o) +$(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c)) + -- cgit From 4c70cda986c86fe536327321d04c29eca81b6409 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:02:47 +0200 Subject: Fix a couple (well, little more than that..) of typos. (This used to be commit a6b52119940a900fb0de3864b8bca94e2965cc24) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/config.mk | 8 ++++---- source4/ntvfs/posix/config.mk | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index 0771733eff..a10ae16afd 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -8,5 +8,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) -$(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c))) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index aa952e1017..bd54fc75e5 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -26,7 +26,7 @@ SUBSYSTEM = ntvfs ntvfs_simple_OBJ_FILES = $(addprefix $(ntvfssrcdir)/simple/, vfs_simple.o svfs_util.o) -$(call proto_header_template,$(ntvfssrcdir)/simple/proto.h,$(ntvfs_simple_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/simple/proto.h,$(ntvfs_simple_OBJ_FILES:.o=.c))) ################################################ # Start MODULE ntvfs_cifsposix @@ -40,7 +40,7 @@ SUBSYSTEM = ntvfs ntvfs_cifsposix_OBJ_FILES = \ $(addprefix $(ntvfssrcdir)/cifs_posix_cli/, vfs_cifs_posix.o svfs_util.o) -$(call proto_header_template,$(ntvfssrcdir)/cifs_posix_cli/proto.h,$(ntvfs_cifsposix_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/cifs_posix_cli/proto.h,$(ntvfs_cifsposix_OBJ_FILES:.o=.c))) ################################################ # Start MODULE ntvfs_print @@ -63,7 +63,7 @@ PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) -$(call proto_header_template,$(ntvssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES))) ################################################ # Start MODULE ntvfs_nbench @@ -81,7 +81,7 @@ ntvfs_nbench_OBJ_FILES = $(ntvfssrcdir)/nbench/vfs_nbench.o ntvfs_OBJ_FILES = $(addprefix $(ntvfssrcdir)/, ntvfs_base.o ntvfs_generic.o ntvfs_interface.o ntvfs_util.o) -$(call proto_header_template,$(ntvfssrcdir)/ntvfs_proto.h,$(ntvfs_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/ntvfs_proto.h,$(ntvfs_OBJ_FILES:.o=.c))) # PUBLIC_HEADERS += $(ntvfssrcdir)/ntvfs.h # diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 5d90942b12..0ee3e3be16 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -70,5 +70,5 @@ ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ xattr_system.o \ xattr_tdb.o) -$(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c)) +$(eval $(call proto_header_template,$(ntvfssrcdir)/posix/vfs_posix_proto.h,$(ntvfs_posix_OBJ_FILES:.o=.c))) -- cgit From 60ae8f06574c74261643f469e6be2a945fd90880 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 18 May 2008 23:40:23 +0200 Subject: Fix a bunch of dependencies. (This used to be commit a63f458462d207d215a6e4ef8e480b0c8daedf6a) --- source4/ntvfs/common/config.mk | 2 +- source4/ntvfs/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/config.mk b/source4/ntvfs/common/config.mk index a10ae16afd..1fe093bb69 100644 --- a/source4/ntvfs/common/config.mk +++ b/source4/ntvfs/common/config.mk @@ -8,5 +8,5 @@ PRIVATE_DEPENDENCIES = brlock_ctdb opendb_ctdb ntvfs_common_OBJ_FILES = $(addprefix $(ntvfssrcdir)/common/, init.o brlock.o brlock_tdb.o opendb.o opendb_tdb.o notify.o) -$(eval $(call proto_header_template,$(ntvfssrcdir)/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c))) +$(eval $(call proto_header_template,$(ntvfssrcdir)/common/proto.h,$(ntvfs_common_OBJ_FILES:.o=.c))) diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index bd54fc75e5..8e647516ef 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -63,7 +63,7 @@ PRIVATE_DEPENDENCIES = dcerpc_server DCERPC_COMMON ntvfs_ipc_OBJ_FILES = $(addprefix $(ntvfssrcdir)/ipc/, vfs_ipc.o ipc_rap.o rap_server.o) -$(eval $(call proto_header_template,$(ntvfssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES))) +$(eval $(call proto_header_template,$(ntvfssrcdir)/ipc/proto.h,$(ntvfs_ipc_OBJ_FILES:.o=.c))) ################################################ # Start MODULE ntvfs_nbench -- cgit From 66cbf7eb59ab4a29dca1d30850c9aeb35a598b3d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 May 2008 11:39:16 +1000 Subject: added mkdir to SMB2 proxy (This used to be commit 1323aab11fbf346e19c4cef227d727ddfcaa7d60) --- source4/ntvfs/smb2/vfs_smb2.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 13dbb4ea2e..3a9a74a928 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -450,7 +450,14 @@ static NTSTATUS cvfs_open(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_mkdir *md) { - return NT_STATUS_NOT_IMPLEMENTED; + struct cvfs_private *private = ntvfs->private_data; + struct composite_context *c_req; + + CHECK_ASYNC(req); + + c_req = smb2_composite_mkdir_send(private->tree, md); + + SIMPLE_COMPOSITE_TAIL; } /* -- cgit From e7d993b8b26e121ff37640825b4d2f2c4d6332bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 May 2008 13:05:08 +1000 Subject: added SMB2 proxying of rmdir (This used to be commit 1e0c24b2760f2a632333b51710cd9581f0cee851) --- source4/ntvfs/smb2/vfs_smb2.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 3a9a74a928..cc09daf83f 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -349,6 +349,10 @@ static void async_simple_composite(struct composite_context *c_req) /* delete a file - the dirtype specifies the file types to include in the search. The name can contain CIFS wildcards, but rarely does (except with OS/2 clients) + + BUGS: + - doesn't handle wildcards + - doesn't obey attrib restrictions */ static NTSTATUS cvfs_unlink(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_unlink *unl) @@ -466,7 +470,14 @@ static NTSTATUS cvfs_mkdir(struct ntvfs_module_context *ntvfs, static NTSTATUS cvfs_rmdir(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, struct smb_rmdir *rd) { - return NT_STATUS_NOT_IMPLEMENTED; + struct cvfs_private *private = ntvfs->private_data; + struct composite_context *c_req; + + CHECK_ASYNC(req); + + c_req = smb2_composite_rmdir_send(private->tree, rd); + + SIMPLE_COMPOSITE_TAIL; } /* -- cgit From 2352602a57989ac1572151cba1da1e78b9410860 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 May 2008 11:58:47 +1000 Subject: check the creation options where the client can require a path to be a file or a directory (This used to be commit c05b58940f06b01b9770c218eb0708cb621215ef) --- source4/ntvfs/posix/pvfs_open.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c9c1c56f14..67937324cc 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1117,6 +1117,20 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return status; } + /* if the client specified that it must not be a directory then + check that it isn't */ + if (name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (io->generic.in.create_options & NTCREATEX_OPTIONS_NON_DIRECTORY_FILE)) { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } + + /* if the client specified that it must be a directory then + check that it is */ + if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { + return NT_STATUS_NOT_A_DIRECTORY; + } + /* directory opens are handled separately */ if ((name->exists && (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) || (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)) { -- cgit From 4d39976dddf2adf6a0d659050c3a21a6e0ff8ab2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 May 2008 22:12:20 +1000 Subject: fixed SMB2 locking - SMB2 locking is different in several ways from SMB locking. To fix it properly we will need a new generic mapping structure for locking, but for now do a best effort mapping - added locking to gentest_smb2 (This used to be commit ea6d9cf602302adafe0f9d5f5f90a9b26d1ead6f) --- source4/ntvfs/ntvfs_generic.c | 62 ++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 3653ad82c1..a706e621c9 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1011,38 +1011,56 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, locks->count = lck->unlock.in.count; break; - case RAW_LOCK_SMB2: - if (lck->smb2.in.unknown1 != 1) { + case RAW_LOCK_SMB2: { + /* this is only approximate! We need to change the + generic structure to fix this properly */ + int i; + if (lck->smb2.in.lock_count < 1) { return NT_STATUS_INVALID_PARAMETER; } lck2->generic.level = RAW_LOCK_GENERIC; lck2->generic.in.file.ntvfs= lck->smb2.in.file.ntvfs; - if (lck->smb2.in.flags & SMB2_LOCK_FLAG_EXCLUSIV) { - lck2->generic.in.mode = 0; - } else { - lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; + lck2->generic.in.timeout = UINT32_MAX; + lck2->generic.in.mode = 0; + lck2->generic.in.lock_cnt = 0; + lck2->generic.in.ulock_cnt = 0; + lck2->generic.in.locks = talloc_zero_array(lck2, struct smb_lock_entry, + lck->smb2.in.lock_count); + if (lck2->generic.in.locks == NULL) { + return NT_STATUS_NO_MEMORY; } - if (lck->smb2.in.flags & SMB2_LOCK_FLAG_NO_PENDING) { - lck2->generic.in.timeout = 0; - } else { - lck2->generic.in.timeout = UINT32_MAX; + for (i=0;ismb2.in.lock_count;i++) { + if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) { + int j = lck2->generic.in.ulock_cnt; + lck2->generic.in.ulock_cnt++; + lck2->generic.in.locks[j].pid = 0; + lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; + lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; + lck2->generic.in.locks[j].pid = 0; + } } - if (lck->smb2.in.flags & SMB2_LOCK_FLAG_UNLOCK) { - lck2->generic.in.ulock_cnt = 1; - lck2->generic.in.lock_cnt = 0; - } else { - lck2->generic.in.ulock_cnt = 0; - lck2->generic.in.lock_cnt = 1; + for (i=0;ismb2.in.lock_count;i++) { + if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) { + int j = lck2->generic.in.ulock_cnt + + lck2->generic.in.lock_cnt; + lck2->generic.in.lock_cnt++; + lck2->generic.in.locks[j].pid = 0; + lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; + lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; + lck2->generic.in.locks[j].pid = 0; + if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) { + lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; + } + if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) { + lck2->generic.in.timeout = 0; + } + } } - lck2->generic.in.locks = locks; - locks->pid = 0; - locks->offset = lck->smb2.in.offset; - locks->count = lck->smb2.in.count; - /* initialize output value */ - lck->smb2.out.unknown1 = 0; + lck->smb2.out.reserved = 0; break; + } case RAW_LOCK_SMB2_BREAK: lck2->generic.level = RAW_LOCK_GENERIC; -- cgit From 7a9ffeca21666935ba08cd909b63fc063f7607f7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 17:53:50 +1000 Subject: check for invalid file attribute values in create (This used to be commit dd21e3d9d788a67d4673625ed4892a875f4600dc) --- source4/ntvfs/posix/pvfs_open.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 67937324cc..cc4f0add27 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -548,6 +548,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, uint32_t oplock_level = OPLOCK_NONE, oplock_granted; bool allow_level_II_oplock = false; + if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) { + return NT_STATUS_INVALID_PARAMETER; + } + if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return NT_STATUS_CANNOT_DELETE; -- cgit From ac185ae0c5bca7fdf82e90a7d925c77e9cbe1888 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 23:00:08 +1000 Subject: fixes for EAs and filename in gentest_smb2 results - SMB2 returns 0 for a null EA - return the share qualified name for the filename in SMB2 ALL_INFO level (This used to be commit f9708184a2037f83ebb97c847414326a42436154) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 6bc21e5e3e..102660a0bf 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -298,10 +298,21 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; info->all_info2.out.file_id = name->dos.file_id; info->all_info2.out.ea_size = name->dos.ea_size; + if (info->all_info2.out.ea_size == 4) { + /* SMB2 uses zero for a empty EA set */ + info->all_info2.out.ea_size = 0; + } info->all_info2.out.access_mask = 0; /* only set by qfileinfo */ info->all_info2.out.position = 0; /* only set by qfileinfo */ info->all_info2.out.mode = 0; /* only set by qfileinfo */ - info->all_info2.out.fname.s = name->original_name; + /* windows wants the full path on disk for this + result, but I really don't want to expose that on + the wire, so I'll give the path with a share + prefix, which is a good approximation */ + info->all_info2.out.fname.s = talloc_asprintf(req, "\\%s\\%s", + pvfs->share_name, + name->original_name); + NT_STATUS_HAVE_NO_MEMORY(info->all_info2.out.fname.s); return NT_STATUS_OK; } -- cgit From 2e0f61a18ab002a90faa06477fa258e36b8a5fc0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 May 2008 23:07:16 +1000 Subject: SMB2 read returns NT_STATUS_END_OF_FILE on read past end of file (This used to be commit 1590494daf5abe43e43402e7602f92267bcda34b) --- source4/ntvfs/ntvfs_generic.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index a706e621c9..62a1427405 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1276,6 +1276,11 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, rd->smb2.out.data.length= rd2->generic.out.nread; rd->smb2.out.remaining = 0; rd->smb2.out.reserved = 0; + if (NT_STATUS_IS_OK(status) && + rd->smb2.out.data.length == 0 && + rd->smb2.in.length != 0) { + status = NT_STATUS_END_OF_FILE; + } break; default: return NT_STATUS_INVALID_LEVEL; -- cgit From ec7a6ee8ab25f4550a68b286d9eba32b955a73a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 23 May 2008 00:07:12 +1000 Subject: fix make test for EAs again - go back to 4 byte alignment until I work out the rules that Vista wants more exactly - add the zero sized EA handling for SMB2 more generically (This used to be commit 326b69bc8064cbea357864cecd6bd27b50c57184) --- source4/ntvfs/posix/pvfs_fileinfo.c | 5 +++++ source4/ntvfs/posix/pvfs_qfileinfo.c | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 4c383ed45d..e35f42e955 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -75,6 +75,11 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.alloc_size = pvfs_round_alloc_size(pvfs, name->st.st_size); name->dos.nlink = name->st.st_nlink; name->dos.ea_size = 4; + if (pvfs->ntvfs->ctx->protocol == PROTOCOL_SMB2) { + /* SMB2 represents a null EA with zero bytes */ + name->dos.ea_size = 0; + } + name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; name->dos.flags = 0; diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 102660a0bf..6e3092b744 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -298,10 +298,6 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)? 1 : 0; info->all_info2.out.file_id = name->dos.file_id; info->all_info2.out.ea_size = name->dos.ea_size; - if (info->all_info2.out.ea_size == 4) { - /* SMB2 uses zero for a empty EA set */ - info->all_info2.out.ea_size = 0; - } info->all_info2.out.access_mask = 0; /* only set by qfileinfo */ info->all_info2.out.position = 0; /* only set by qfileinfo */ info->all_info2.out.mode = 0; /* only set by qfileinfo */ -- cgit From c78bf3c2c925060df3362625bbd1c3e96751c087 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 May 2008 09:45:46 +0200 Subject: pvfs_streams: directories don't have streams metze (This used to be commit 9ed7bb5afe6a73206bcba85f25305eb6630a5571) --- source4/ntvfs/posix/pvfs_streams.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 7e6173ef2f..3cd9952fd5 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -36,6 +36,13 @@ NTSTATUS pvfs_stream_information(struct pvfs_state *pvfs, int i; NTSTATUS status; + /* directories don't have streams */ + if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) { + info->num_streams = 0; + info->streams = NULL; + return NT_STATUS_OK; + } + streams = talloc(mem_ctx, struct xattr_DosStreams); if (streams == NULL) { return NT_STATUS_NO_MEMORY; -- cgit From 391b746430ad3d0b371930933e0a77e6a70a9ac0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 May 2008 09:46:50 +0200 Subject: pvfs_resolve: stream_name = "" is only the same as NULL for files metze (This used to be commit 47756129fdf01075bac06cdd24107d7dc8ba34af) --- source4/ntvfs/posix/pvfs_fileinfo.c | 2 ++ source4/ntvfs/posix/pvfs_resolve.c | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index e35f42e955..04f6ad78d0 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -58,6 +58,8 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, if (S_ISDIR(name->st.st_mode)) { name->st.st_size = 0; name->st.st_nlink = 1; + } else if (name->stream_id == 0) { + name->stream_name = NULL; } /* for now just use the simple samba mapping */ diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 325bc74f8f..2e97925c49 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -202,7 +202,13 @@ static NTSTATUS parse_stream_name(struct pvfs_filename *name, const char *s) } *p = 0; if (strcmp(name->stream_name, "") == 0) { - name->stream_name = NULL; + /* + * we don't set stream_name to NULL, here + * as this would be wrong for directories + * + * pvfs_fill_dos_info() will set it to NULL + * if it's not a directory. + */ name->stream_id = 0; } else { name->stream_id = pvfs_name_hash(name->stream_name, -- cgit From 5d648b4aa5540e91fa7ea77668965eefd8926b1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 23 May 2008 09:47:59 +0200 Subject: pvfs_open: return FILE_IS_A_DIRECTORY when opening a stream on a directory metze (This used to be commit 1421b1cc0c442be839be702647009ed5295f34a3) --- source4/ntvfs/posix/pvfs_open.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index cc4f0add27..926c99d37e 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -182,12 +182,19 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, bool del_on_close; uint32_t create_options; uint32_t share_access; + bool forced; create_options = io->generic.in.create_options; share_access = io->generic.in.share_access; + forced = (io->generic.in.create_options & NTCREATEX_OPTIONS_DIRECTORY)?true:false; + if (name->stream_name) { - return NT_STATUS_NOT_A_DIRECTORY; + if (forced) { + return NT_STATUS_NOT_A_DIRECTORY; + } else { + return NT_STATUS_FILE_IS_A_DIRECTORY; + } } /* if the client says it must be a directory, and it isn't, -- cgit From c5c1b3706af13fe729f435e7bf4ec1e73b719eef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 May 2008 14:59:58 +1000 Subject: allow larger streams using the TDB backend (This used to be commit 8c0d756eb887477da867e069dbde3a7ad98d4ae0) --- source4/ntvfs/posix/pvfs_streams.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c index 3cd9952fd5..30d7ce2477 100644 --- a/source4/ntvfs/posix/pvfs_streams.c +++ b/source4/ntvfs/posix/pvfs_streams.c @@ -276,9 +276,12 @@ ssize_t pvfs_stream_write(struct pvfs_state *pvfs, if (count == 0) { return 0; } - if (offset > XATTR_MAX_STREAM_SIZE) { - errno = ENOSPC; - return -1; + + if (count+offset > XATTR_MAX_STREAM_SIZE) { + if (!pvfs->ea_db || count+offset > XATTR_MAX_STREAM_SIZE_TDB) { + errno = ENOSPC; + return -1; + } } /* we have to load the existing stream, then modify, then save */ @@ -332,7 +335,9 @@ NTSTATUS pvfs_stream_truncate(struct pvfs_state *pvfs, DATA_BLOB blob; if (length > XATTR_MAX_STREAM_SIZE) { - return NT_STATUS_DISK_FULL; + if (!pvfs->ea_db || length > XATTR_MAX_STREAM_SIZE_TDB) { + return NT_STATUS_DISK_FULL; + } } /* we have to load the existing stream, then modify, then save */ -- cgit From bf8d9e180e1e908e891e3755bbb70eab550f0638 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 May 2008 15:00:27 +1000 Subject: fill in reserved field on SMB2 flush (This used to be commit 400a3b39d5c151cf43e307af2fa702208d7cd472) --- source4/ntvfs/posix/pvfs_flush.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_flush.c b/source4/ntvfs/posix/pvfs_flush.c index 61e73cedba..6e09c1f34a 100644 --- a/source4/ntvfs/posix/pvfs_flush.c +++ b/source4/ntvfs/posix/pvfs_flush.c @@ -54,6 +54,7 @@ NTSTATUS pvfs_flush(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_HANDLE; } pvfs_flush_file(pvfs, f); + io->smb2.out.reserved = 0; return NT_STATUS_OK; case RAW_FLUSH_ALL: -- cgit From 2ad2bdda89c07c0b8ce754c3b0cd4664eefc697d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 May 2008 15:02:43 +1000 Subject: stricter checks for valid inputs in SMB2 open and lock (This used to be commit a7b5689a73adde59de28770aa3949660441291ea) --- source4/ntvfs/ntvfs_generic.c | 18 ++++++++++++++++-- source4/ntvfs/posix/pvfs_open.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 13 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 62a1427405..9b4f235cde 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -522,6 +522,12 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, io2->generic.in.fname = io->smb2.in.fname; io2->generic.in.sec_desc = NULL; io2->generic.in.ea_list = NULL; + + /* we use a couple of bits of the create options internally */ + if (io2->generic.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) { + return NT_STATUS_INVALID_PARAMETER; + } + status = ntvfs->ops->open(ntvfs, req, io2); break; @@ -1031,6 +1037,9 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } for (i=0;ismb2.in.lock_count;i++) { + if (lck->smb2.in.locks[i].flags & ~SMB2_LOCK_FLAG_ALL_MASK) { + return NT_STATUS_INVALID_PARAMETER; + } if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) { int j = lck2->generic.in.ulock_cnt; lck2->generic.in.ulock_cnt++; @@ -1277,10 +1286,15 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, rd->smb2.out.remaining = 0; rd->smb2.out.reserved = 0; if (NT_STATUS_IS_OK(status) && - rd->smb2.out.data.length == 0 && - rd->smb2.in.length != 0) { + rd->smb2.out.data.length == 0) { status = NT_STATUS_END_OF_FILE; } + /* SMB2 does honor the min_count field, SMB does not */ + if (NT_STATUS_IS_OK(status) && + rd->smb2.in.min_count > rd->smb2.out.data.length) { + rd->smb2.out.data.length = 0; + status = NT_STATUS_END_OF_FILE; + } break; default: return NT_STATUS_INVALID_LEVEL; diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 926c99d37e..59b42fe751 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -203,6 +203,13 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, return NT_STATUS_NOT_A_DIRECTORY; } + /* found with gentest */ + if (io->ntcreatex.in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED && + (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DIRECTORY) && + (io->ntcreatex.in.create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { + return NT_STATUS_INVALID_PARAMETER; + } + switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_OPEN_IF: break; @@ -563,7 +570,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { return NT_STATUS_CANNOT_DELETE; } - + status = pvfs_access_check_create(pvfs, req, name, &access_mask); NT_STATUS_NOT_OK_RETURN(status); @@ -1121,6 +1128,25 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(ntvfs, req, io); } + create_options = io->generic.in.create_options; + share_access = io->generic.in.share_access; + access_mask = io->generic.in.access_mask; + + if (share_access & ~NTCREATEX_SHARE_ACCESS_MASK) { + return NT_STATUS_INVALID_PARAMETER; + } + + /* some create options are not supported */ + if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { + return NT_STATUS_NOT_SUPPORTED; + } + + /* other create options are not allowed */ + if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && + !(access_mask & SEC_STD_DELETE)) { + return NT_STATUS_INVALID_PARAMETER; + } + /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, PVFS_RESOLVE_STREAMS, &name); @@ -1152,16 +1178,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, open doesn't match */ io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY; - create_options = io->generic.in.create_options; - share_access = io->generic.in.share_access; - access_mask = io->generic.in.access_mask; - - /* certain create options are not allowed */ - if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && - !(access_mask & SEC_STD_DELETE)) { - return NT_STATUS_INVALID_PARAMETER; - } - flags = 0; switch (io->generic.in.open_disposition) { -- cgit From 506849f6008386dad5baa287e7e81a73af031622 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 12:42:43 +1000 Subject: check invalid create options in the right order (This used to be commit 73dbfb9b4148dbfdc30518c08db4658d189f4160) --- source4/ntvfs/ntvfs_generic.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 9b4f235cde..c5b88da3d1 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -523,9 +523,16 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, io2->generic.in.sec_desc = NULL; io2->generic.in.ea_list = NULL; + /* we need to check these bits before we check the private mask */ + if (io2->generic.in.create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { + status = NT_STATUS_NOT_SUPPORTED; + break; + } + /* we use a couple of bits of the create options internally */ if (io2->generic.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) { - return NT_STATUS_INVALID_PARAMETER; + status = NT_STATUS_INVALID_PARAMETER; + break; } status = ntvfs->ops->open(ntvfs, req, io2); -- cgit From 9a37e7ed93dabd1880513d10afc1135049f1fb4a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 14:06:51 +1000 Subject: Vista returns ACCESS_DENIED here (This used to be commit f5068c6e50215f6ea7108d58d783394a315ff14f) --- source4/ntvfs/posix/pvfs_acl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index f1e469f790..507c22f050 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -457,7 +457,7 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, } if (uid != 0 && (*access_mask & SEC_FLAG_SYSTEM_SECURITY)) { - return NT_STATUS_PRIVILEGE_NOT_HELD; + return NT_STATUS_ACCESS_DENIED; } if (*access_mask & ~max_bits) { -- cgit From f0b4b15f64259fcdb18f21657434f592bb2f157e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 14:07:11 +1000 Subject: check for some more invalid bits in smb2 create (This used to be commit dcdaa9f5fd9150b16fb277213e864e5c39d831d6) --- source4/ntvfs/posix/pvfs_open.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 59b42fe751..328f064a57 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1147,6 +1147,15 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } + if (access_mask & (SEC_MASK_INVALID | SEC_STD_SYNCHRONIZE)) { + return NT_STATUS_ACCESS_DENIED; + } + + if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE| + FILE_ATTRIBUTE_VOLUME)) { + return NT_STATUS_INVALID_PARAMETER; + } + /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, PVFS_RESOLVE_STREAMS, &name); -- cgit From 6e265867ff8869254820e8af954c8f1316b05d39 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 14:30:42 +1000 Subject: SEC_STD_SYNCHRONIZE is only invalid on SMB2 (This used to be commit 067f1271adaa13d537bbc92b19fe8d633cbaaf50) --- source4/ntvfs/posix/pvfs_open.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 328f064a57..739c127b98 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -565,6 +565,10 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, if (io->ntcreatex.in.file_attr & ~FILE_ATTRIBUTE_ALL_MASK) { return NT_STATUS_INVALID_PARAMETER; } + + if (io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_ENCRYPTED) { + return NT_STATUS_ACCESS_DENIED; + } if ((io->ntcreatex.in.file_attr & FILE_ATTRIBUTE_READONLY) && (create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE)) { @@ -1147,7 +1151,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - if (access_mask & (SEC_MASK_INVALID | SEC_STD_SYNCHRONIZE)) { + if (access_mask & SEC_MASK_INVALID) { + return NT_STATUS_ACCESS_DENIED; + } + + if (req->ctx->protocol == PROTOCOL_SMB2 && + (access_mask & SEC_STD_SYNCHRONIZE)) { return NT_STATUS_ACCESS_DENIED; } -- cgit From 65e31a965ee6514610ec0d4ca52a5cd8772c5254 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 14:59:55 +1000 Subject: make the SEC_STD_SYNCHRONIZE test more specific (This used to be commit 8c263f91bda97eb910c8589b6cd987ec4a62d770) --- source4/ntvfs/posix/pvfs_open.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 739c127b98..cfa88b6baa 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1155,13 +1155,16 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } + /* what does this bit really mean?? */ if (req->ctx->protocol == PROTOCOL_SMB2 && - (access_mask & SEC_STD_SYNCHRONIZE)) { + (access_mask & SEC_STD_SYNCHRONIZE) && + !(access_mask & SEC_STD_READ_CONTROL)) { return NT_STATUS_ACCESS_DENIED; } if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE| - FILE_ATTRIBUTE_VOLUME)) { + FILE_ATTRIBUTE_VOLUME| + (~FILE_ATTRIBUTE_ALL_MASK))) { return NT_STATUS_INVALID_PARAMETER; } -- cgit From cf274201b4e987faa822a137bb67fa191dabc5e8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 15:27:25 +1000 Subject: disable the SEC_STD_SYNCHRONIZE test until we know what it means (This used to be commit 897f4582bee72e319874e8a2d064ba442415571d) --- source4/ntvfs/posix/pvfs_open.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index cfa88b6baa..adcdeb1f2b 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1155,12 +1155,14 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } +#if 0 /* what does this bit really mean?? */ if (req->ctx->protocol == PROTOCOL_SMB2 && (access_mask & SEC_STD_SYNCHRONIZE) && !(access_mask & SEC_STD_READ_CONTROL)) { return NT_STATUS_ACCESS_DENIED; } +#endif if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE| FILE_ATTRIBUTE_VOLUME| -- cgit From 848e7c5830a869d86d7fe236acc1e6a1949252d3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 16:02:10 +1000 Subject: it seems that lock flags are only validated when UNLOCK is set (This used to be commit d1bde5830cd56042236d72598e5cfe9c7abc4c47) --- source4/ntvfs/ntvfs_generic.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index c5b88da3d1..e449e61b34 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1044,11 +1044,12 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } for (i=0;ismb2.in.lock_count;i++) { - if (lck->smb2.in.locks[i].flags & ~SMB2_LOCK_FLAG_ALL_MASK) { - return NT_STATUS_INVALID_PARAMETER; - } if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) { int j = lck2->generic.in.ulock_cnt; + if (lck->smb2.in.locks[i].flags & + (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE)) { + return NT_STATUS_INVALID_PARAMETER; + } lck2->generic.in.ulock_cnt++; lck2->generic.in.locks[j].pid = 0; lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; -- cgit From 46e64417a3b14d1c33ca7e97080c64f8e67efec2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 16:02:27 +1000 Subject: another attempt at the damn SEC_STD_SYNCHRONIZE flag (This used to be commit 2ac27bfffa557d6c0f71c443b43a8d1967edb177) --- source4/ntvfs/posix/pvfs_open.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index adcdeb1f2b..908dd449af 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1155,14 +1155,11 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_ACCESS_DENIED; } -#if 0 /* what does this bit really mean?? */ if (req->ctx->protocol == PROTOCOL_SMB2 && - (access_mask & SEC_STD_SYNCHRONIZE) && - !(access_mask & SEC_STD_READ_CONTROL)) { + access_mask == SEC_STD_SYNCHRONIZE) { return NT_STATUS_ACCESS_DENIED; } -#endif if (io->ntcreatex.in.file_attr & (FILE_ATTRIBUTE_DEVICE| FILE_ATTRIBUTE_VOLUME| -- cgit From cb36437db2d75e7facc91cf0089f2caa20bf0ca0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 16:43:36 +1000 Subject: added support for the output fields of SMB2 close (This used to be commit 2633bc749792c224acc73a2e4ca723404331c19c) --- source4/ntvfs/cifs/vfs_cifs.c | 10 +++++++ source4/ntvfs/ntvfs_generic.c | 63 +++++++++++++++++++++++++++++++++-------- source4/ntvfs/posix/pvfs_open.c | 29 +++++++++++++++++-- 3 files changed, 87 insertions(+), 15 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 2b61268733..844fa11cc5 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -769,6 +769,7 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, struct cvfs_private *private = ntvfs->private_data; struct smbcli_request *c_req; struct cvfs_file *f; + union smb_close io2; SETUP_PID; @@ -776,6 +777,15 @@ static NTSTATUS cvfs_close(struct ntvfs_module_context *ntvfs, private->map_generic) { return ntvfs_map_close(ntvfs, req, io); } + + if (io->generic.level == RAW_CLOSE_GENERIC) { + ZERO_STRUCT(io2); + io2.close.level = RAW_CLOSE_CLOSE; + io2.close.in.file = io->generic.in.file; + io2.close.in.write_time = io->generic.in.write_time; + io = &io2; + } + SETUP_FILE_HERE(f); /* Note, we aren't free-ing f, or it's h here. Should we? even if file-close fails, we'll remove it from the list, diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index e449e61b34..a1c89e7df4 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1407,6 +1407,36 @@ done: } +/* + NTVFS close generic to any mapper +*/ +static NTSTATUS ntvfs_map_close_finish(struct ntvfs_module_context *ntvfs, + struct ntvfs_request *req, + union smb_close *cl, + union smb_close *cl2, + NTSTATUS status) +{ + NT_STATUS_NOT_OK_RETURN(status); + + switch (cl->generic.level) { + case RAW_CLOSE_SMB2: + cl->smb2.out.flags = cl2->generic.out.flags; + cl->smb2.out._pad = 0; + cl->smb2.out.create_time = cl2->generic.out.create_time; + cl->smb2.out.access_time = cl2->generic.out.access_time; + cl->smb2.out.write_time = cl2->generic.out.write_time; + cl->smb2.out.change_time = cl2->generic.out.change_time; + cl->smb2.out.alloc_size = cl2->generic.out.alloc_size; + cl->smb2.out.size = cl2->generic.out.size; + cl->smb2.out.file_attr = cl2->generic.out.file_attr; + break; + default: + break; + } + + return status; +} + /* NTVFS close generic to any mapper */ @@ -1415,6 +1445,7 @@ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, union smb_close *cl) { union smb_close *cl2; + NTSTATUS status; cl2 = talloc(req, union smb_close); if (cl2 == NULL) { @@ -1422,30 +1453,38 @@ NTSTATUS ntvfs_map_close(struct ntvfs_module_context *ntvfs, } switch (cl->generic.level) { - case RAW_CLOSE_CLOSE: + case RAW_CLOSE_GENERIC: return NT_STATUS_INVALID_LEVEL; + case RAW_CLOSE_CLOSE: + cl2->generic.level = RAW_CLOSE_GENERIC; + cl2->generic.in.file = cl->close.in.file; + cl2->generic.in.write_time = cl->close.in.write_time; + cl2->generic.in.flags = 0; + break; + case RAW_CLOSE_SPLCLOSE: - cl2->generic.level = RAW_CLOSE_CLOSE; - cl2->generic.in.file.ntvfs = cl->splclose.in.file.ntvfs; + cl2->generic.level = RAW_CLOSE_GENERIC; + cl2->generic.in.file = cl->splclose.in.file; cl2->generic.in.write_time = 0; + cl2->generic.in.flags = 0; break; case RAW_CLOSE_SMB2: - cl2->generic.level = RAW_CLOSE_CLOSE; - cl2->generic.in.file.ntvfs = cl->smb2.in.file.ntvfs; + cl2->generic.level = RAW_CLOSE_GENERIC; + cl2->generic.in.file = cl->smb2.in.file; cl2->generic.in.write_time = 0; - /* SMB2 Close has output parameter, but we just zero them */ - ZERO_STRUCT(cl->smb2.out); + cl2->generic.in.flags = cl->smb2.in.flags; break; } - /* - * we don't need to call ntvfs_map_async_setup() here, - * as close() doesn't have any output fields - */ + status = ntvfs_map_async_setup(ntvfs, req, cl, cl2, + (second_stage_t)ntvfs_map_close_finish); + NT_STATUS_NOT_OK_RETURN(status); + + status = ntvfs->ops->close(ntvfs, req, cl2); - return ntvfs->ops->close(ntvfs, req, cl2); + return ntvfs_map_async_finish(req, status); } /* diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 908dd449af..49710806c7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1514,21 +1514,44 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, return NT_STATUS_DOS(ERRSRV, ERRerror); } - if (io->generic.level != RAW_CLOSE_CLOSE) { + if (io->generic.level != RAW_CLOSE_GENERIC) { return ntvfs_map_close(ntvfs, req, io); } - f = pvfs_find_fd(pvfs, req, io->close.in.file.ntvfs); + f = pvfs_find_fd(pvfs, req, io->generic.in.file.ntvfs); if (!f) { return NT_STATUS_INVALID_HANDLE; } - if (!null_time(io->close.in.write_time)) { + if (!null_time(io->generic.in.write_time)) { unix_times.actime = 0; unix_times.modtime = io->close.in.write_time; utime(f->handle->name->full_name, &unix_times); } + if (io->generic.in.flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) { + struct pvfs_filename *name; + NTSTATUS status; + struct pvfs_file_handle *h = f->handle; + + status = pvfs_resolve_name_handle(pvfs, h); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + name = h->name; + + io->generic.out.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; + io->generic.out.create_time = name->dos.create_time; + io->generic.out.access_time = name->dos.access_time; + io->generic.out.write_time = name->dos.write_time; + io->generic.out.change_time = name->dos.change_time; + io->generic.out.alloc_size = name->dos.alloc_size; + io->generic.out.size = name->st.st_size; + io->generic.out.file_attr = name->dos.attrib; + } else { + ZERO_STRUCT(io->generic.out); + } + talloc_free(f); return NT_STATUS_OK; -- cgit From beac55a88fd28b6003ba163f32539a7bdc2df1a6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 17:22:02 +1000 Subject: enforce lock ordering in SMB2 (This used to be commit 3bec932a89006521ba74bde7943b8cd5b4a660d8) --- source4/ntvfs/ntvfs_generic.c | 56 ++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 27 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index a1c89e7df4..3d92c0be33 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1027,7 +1027,7 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, case RAW_LOCK_SMB2: { /* this is only approximate! We need to change the generic structure to fix this properly */ - int i; + int i, j; if (lck->smb2.in.lock_count < 1) { return NT_STATUS_INVALID_PARAMETER; } @@ -1044,34 +1044,36 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, return NT_STATUS_NO_MEMORY; } for (i=0;ismb2.in.lock_count;i++) { - if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) { - int j = lck2->generic.in.ulock_cnt; - if (lck->smb2.in.locks[i].flags & - (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE)) { - return NT_STATUS_INVALID_PARAMETER; - } - lck2->generic.in.ulock_cnt++; - lck2->generic.in.locks[j].pid = 0; - lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; - lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; - lck2->generic.in.locks[j].pid = 0; + if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) { + break; + } + j = lck2->generic.in.ulock_cnt; + if (lck->smb2.in.locks[i].flags & + (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE)) { + return NT_STATUS_INVALID_PARAMETER; } + lck2->generic.in.ulock_cnt++; + lck2->generic.in.locks[j].pid = 0; + lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; + lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; + lck2->generic.in.locks[j].pid = 0; } - for (i=0;ismb2.in.lock_count;i++) { - if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) { - int j = lck2->generic.in.ulock_cnt + - lck2->generic.in.lock_cnt; - lck2->generic.in.lock_cnt++; - lck2->generic.in.locks[j].pid = 0; - lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; - lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; - lck2->generic.in.locks[j].pid = 0; - if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) { - lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; - } - if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) { - lck2->generic.in.timeout = 0; - } + for (;ismb2.in.lock_count;i++) { + if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) { + /* w2008 requires unlocks to come first */ + return NT_STATUS_INVALID_PARAMETER; + } + j = lck2->generic.in.ulock_cnt + lck2->generic.in.lock_cnt; + lck2->generic.in.lock_cnt++; + lck2->generic.in.locks[j].pid = 0; + lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; + lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; + lck2->generic.in.locks[j].pid = 0; + if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) { + lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; + } + if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_FAIL_IMMEDIATELY) { + lck2->generic.in.timeout = 0; } } /* initialize output value */ -- cgit From 8daeee5c5d7d5851677089cceaf26a0e32675a96 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 May 2008 18:20:23 +1000 Subject: ensure that we honor SMB2 read min_count properly (This used to be commit 318038d6f670efffa96d8b0db63f46b3752e1cd3) --- source4/ntvfs/ntvfs_generic.c | 12 +----------- source4/ntvfs/posix/pvfs_read.c | 8 ++++++++ 2 files changed, 9 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 3d92c0be33..06d89a717b 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1295,16 +1295,6 @@ static NTSTATUS ntvfs_map_read_finish(struct ntvfs_module_context *ntvfs, rd->smb2.out.data.length= rd2->generic.out.nread; rd->smb2.out.remaining = 0; rd->smb2.out.reserved = 0; - if (NT_STATUS_IS_OK(status) && - rd->smb2.out.data.length == 0) { - status = NT_STATUS_END_OF_FILE; - } - /* SMB2 does honor the min_count field, SMB does not */ - if (NT_STATUS_IS_OK(status) && - rd->smb2.in.min_count > rd->smb2.out.data.length) { - rd->smb2.out.data.length = 0; - status = NT_STATUS_END_OF_FILE; - } break; default: return NT_STATUS_INVALID_LEVEL; @@ -1396,7 +1386,7 @@ NTSTATUS ntvfs_map_read(struct ntvfs_module_context *ntvfs, case RAW_READ_SMB2: rd2->readx.in.file.ntvfs= rd->smb2.in.file.ntvfs; rd2->readx.in.offset = rd->smb2.in.offset; - rd2->readx.in.mincnt = rd->smb2.in.length; + rd2->readx.in.mincnt = rd->smb2.in.min_count; rd2->readx.in.maxcnt = rd->smb2.in.length; rd2->readx.in.remaining = 0; rd2->readx.out.data = rd->smb2.out.data.data; diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index 418b7e09fb..a01a8a57e3 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -93,6 +93,14 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } + /* only SMB2 honors mincnt */ + if (req->ctx->protocol == PROTOCOL_SMB2) { + if (rd->readx.in.mincnt > ret || + (ret == 0 && maxcnt > 0)) { + return NT_STATUS_END_OF_FILE; + } + } + f->handle->position = f->handle->seek_offset = rd->readx.in.offset + ret; rd->readx.out.nread = ret; -- cgit From 715cee3bdbabd86b7603fbb43da470bdb8c1fe9d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 28 May 2008 03:07:42 +0200 Subject: Use variables for directories in ntvfs smb2 module. (This used to be commit ea550711c5949f11f9d2ad41ff96b56644f06547) --- source4/ntvfs/config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/config.mk b/source4/ntvfs/config.mk index bf34c4082a..593c526edb 100644 --- a/source4/ntvfs/config.mk +++ b/source4/ntvfs/config.mk @@ -27,7 +27,7 @@ PRIVATE_DEPENDENCIES = \ # End MODULE ntvfs_smb2 ################################################ -ntvfs_smb2_OBJ_FILES = ntvfs/smb2/vfs_smb2.o +ntvfs_smb2_OBJ_FILES = $(ntvfssrcdir)/smb2/vfs_smb2.o ################################################ -- cgit From b5f39fbda0b7b71c23f0df473d1206daaec88222 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 11:48:11 +1000 Subject: fix error code for read on a directory (This used to be commit afd4f47971bc5f63b32c44dad546a1a4011b86f4) --- source4/ntvfs/posix/pvfs_read.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_read.c b/source4/ntvfs/posix/pvfs_read.c index a01a8a57e3..8e1a59473f 100644 --- a/source4/ntvfs/posix/pvfs_read.c +++ b/source4/ntvfs/posix/pvfs_read.c @@ -46,7 +46,7 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs, } if (f->handle->fd == -1) { - return NT_STATUS_FILE_IS_A_DIRECTORY; + return NT_STATUS_INVALID_DEVICE_REQUEST; } mask = SEC_FILE_READ_DATA; -- cgit From 6222b8e7e215e1d0d7c82d40d35142b8c96afbf6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 11:48:21 +1000 Subject: fixed error code for write on a directory (This used to be commit 68eb5b050edeaa9c95348013b68a785c3f2c21fa) --- source4/ntvfs/posix/pvfs_write.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index dda8c83407..1f662f13fc 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -45,7 +45,7 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, } if (f->handle->fd == -1) { - return NT_STATUS_FILE_IS_A_DIRECTORY; + return NT_STATUS_INVALID_DEVICE_REQUEST; } if (!(f->access_mask & (SEC_FILE_WRITE_DATA | SEC_FILE_APPEND_DATA))) { -- cgit From fd67526bd304dd9391b0014886dd2748aa392721 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 11:49:43 +1000 Subject: answer SMB2_ALL_EAS qfileinfo (This used to be commit f5cf47eef18a5728317de97eab961d948db3f031) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index 6e3092b744..c663466985 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -178,6 +178,15 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, case RAW_FILEINFO_ALL_EAS: return pvfs_query_all_eas(pvfs, req, name, fd, &info->all_eas.out); + case RAW_FILEINFO_SMB2_ALL_EAS: { + NTSTATUS status = pvfs_query_all_eas(pvfs, req, name, fd, &info->all_eas.out); + if (NT_STATUS_IS_OK(status) && + info->all_eas.out.num_eas == 0) { + return NT_STATUS_NO_EAS_ON_FILE; + } + return status; + } + case RAW_FILEINFO_IS_NAME_VALID: return NT_STATUS_OK; -- cgit From 6b707263058ec69f12a6235890005a226c8671de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 16:28:37 +1000 Subject: implement the documented SMB2 create blobs in the server Not all of them are honoured yet, but they are all parsed and the ones that have SMB equivalents are honoured (This used to be commit 9fc70e2ed6a54f6d9a0530f4d37c0f8acadb6778) --- source4/ntvfs/ipc/vfs_ipc.c | 2 +- source4/ntvfs/ntvfs_generic.c | 14 ++++++++++---- source4/ntvfs/posix/pvfs_open.c | 3 +++ 3 files changed, 14 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ipc/vfs_ipc.c b/source4/ntvfs/ipc/vfs_ipc.c index ea7b54ae6a..8ac7ac7d03 100644 --- a/source4/ntvfs/ipc/vfs_ipc.c +++ b/source4/ntvfs/ipc/vfs_ipc.c @@ -321,6 +321,7 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs, status = ipc_open_generic(ntvfs, req, oi->smb2.in.fname, &p); NT_STATUS_NOT_OK_RETURN(status); + ZERO_STRUCT(oi->smb2.out); oi->smb2.out.file.ntvfs = p->handle; oi->smb2.out.oplock_level = oi->smb2.in.oplock_level; oi->smb2.out.create_action = NTCREATEX_ACTION_EXISTED; @@ -332,7 +333,6 @@ static NTSTATUS ipc_open_smb2(struct ntvfs_module_context *ntvfs, oi->smb2.out.size = 0; oi->smb2.out.file_attr = FILE_ATTRIBUTE_NORMAL; oi->smb2.out.reserved2 = 0; - oi->smb2.out.blob = data_blob(NULL, 0); return status; } diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 06d89a717b..9227295696 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -207,6 +207,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, break; case RAW_OPEN_SMB2: + ZERO_STRUCT(io->smb2.out); io->smb2.out.file.ntvfs = io2->generic.out.file.ntvfs; switch (io2->generic.out.oplock_level) { case BATCH_OPLOCK_RETURN: @@ -232,7 +233,6 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, io->smb2.out.size = io2->generic.out.size; io->smb2.out.file_attr = io2->generic.out.attrib; io->smb2.out.reserved2 = 0; - io->smb2.out.blob = data_blob(NULL, 0); break; default: @@ -512,7 +512,7 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, } io2->generic.in.root_fid = 0; io2->generic.in.access_mask = io->smb2.in.desired_access; - io2->generic.in.alloc_size = 0; + io2->generic.in.alloc_size = io->smb2.in.alloc_size; io2->generic.in.file_attr = io->smb2.in.file_attributes; io2->generic.in.share_access = io->smb2.in.share_access; io2->generic.in.open_disposition= io->smb2.in.create_disposition; @@ -520,8 +520,14 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, io2->generic.in.impersonation = io->smb2.in.impersonation_level; io2->generic.in.security_flags = 0; io2->generic.in.fname = io->smb2.in.fname; - io2->generic.in.sec_desc = NULL; - io2->generic.in.ea_list = NULL; + io2->generic.in.sec_desc = io->smb2.in.sec_desc; + io2->generic.in.ea_list = &io->smb2.in.eas; + + /* we don't support timewarp yet */ + if (io->smb2.in.timewarp != 0) { + status = NT_STATUS_OBJECT_NAME_NOT_FOUND; + break; + } /* we need to check these bits before we check the private mask */ if (io2->generic.in.create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 49710806c7..0f08136a79 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -634,6 +634,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, return status; } + /* support initial alloc sizes */ + name->dos.alloc_size = io->ntcreatex.in.alloc_size; name->dos.attrib = attrib; status = pvfs_dosattrib_save(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { @@ -1464,6 +1466,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, talloc_free(lck); return pvfs_map_errno(pvfs, errno); } + name->dos.alloc_size = io->ntcreatex.in.alloc_size; name->dos.attrib = attrib; status = pvfs_dosattrib_save(pvfs, name, fd); if (!NT_STATUS_IS_OK(status)) { -- cgit From fa0bc441e35bf0451f3ea471c4c144206a80febd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 20:06:04 +1000 Subject: don't allow a file to be changed to a directory with setfileinfo (This used to be commit ad7acbf8bf83c7250dfcbd57f0f4e19e57534a92) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 0beca75ead..1dd2c075d9 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -457,7 +457,12 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, /* possibly change the attribute */ if (newstats.dos.attrib != h->name->dos.attrib) { - mode_t mode = pvfs_fileperms(pvfs, newstats.dos.attrib); + mode_t mode; + if ((newstats.dos.attrib & FILE_ATTRIBUTE_DIRECTORY) && + !(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { + return NT_STATUS_INVALID_PARAMETER; + } + mode = pvfs_fileperms(pvfs, newstats.dos.attrib); if (!(h->name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) { if (fchmod(h->fd, mode) == -1) { return pvfs_map_errno(pvfs, errno); -- cgit From 86d69fd4b642860c3092a79ebbfb02544043b82d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 21:48:40 +1000 Subject: SMB2 doesn't have NAME_INFORMATION level (This used to be commit a431d51b113c2e214ccfe7a678ba0a565b020263) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index c663466985..b9f763c2e0 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -216,6 +216,10 @@ static NTSTATUS pvfs_map_fileinfo(struct pvfs_state *pvfs, case RAW_FILEINFO_NAME_INFO: case RAW_FILEINFO_NAME_INFORMATION: + if (req->ctx->protocol == PROTOCOL_SMB2) { + /* strange that SMB2 doesn't have this */ + return NT_STATUS_NOT_SUPPORTED; + } info->name_info.out.fname.s = name->original_name; return NT_STATUS_OK; -- cgit From 67226f054b57961ac00b419761014d4a92e8c18d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 May 2008 22:44:20 +1000 Subject: fixed create_action for truncated files (This used to be commit 884c32fcef48244bd260026a61790332bd706eb4) --- source4/ntvfs/posix/pvfs_open.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 0f08136a79..a1c5571258 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1122,6 +1122,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, uint32_t create_options; uint32_t share_access; uint32_t access_mask; + uint32_t create_action = NTCREATEX_ACTION_EXISTED; bool del_on_close; bool stream_existed, stream_truncate=false; uint32_t oplock_level = OPLOCK_NONE, oplock_granted; @@ -1169,6 +1170,13 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } + /* we ignore some file_attr bits */ + io->ntcreatex.in.file_attr &= ~(FILE_ATTRIBUTE_NONINDEXED | + FILE_ATTRIBUTE_COMPRESSED | + FILE_ATTRIBUTE_REPARSE_POINT | + FILE_ATTRIBUTE_SPARSE | + FILE_ATTRIBUTE_NORMAL); + /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, PVFS_RESOLVE_STREAMS, &name); @@ -1210,6 +1218,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } else { stream_truncate = true; } + create_action = NTCREATEX_ACTION_TRUNCATED; break; case NTCREATEX_DISP_OPEN: @@ -1228,6 +1237,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } else { stream_truncate = true; } + create_action = NTCREATEX_ACTION_TRUNCATED; break; case NTCREATEX_DISP_CREATE: @@ -1487,7 +1497,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, io->generic.out.oplock_level = oplock_granted; io->generic.out.file.ntvfs = h; io->generic.out.create_action = stream_existed? - NTCREATEX_ACTION_EXISTED:NTCREATEX_ACTION_CREATED; + create_action:NTCREATEX_ACTION_CREATED; + io->generic.out.create_time = name->dos.create_time; io->generic.out.access_time = name->dos.access_time; io->generic.out.write_time = name->dos.write_time; -- cgit From e42ded24a085a9bfaae0e4973b8dd52681b51a8a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 18:23:20 +1000 Subject: SEC_FILE_READ_ATTRIBUTE is only automatically granted on SMB, not SMB2 (This used to be commit 7bff0691428ed3f75c1a9cbaae692bc9830640e6) --- source4/ntvfs/posix/pvfs_acl.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 507c22f050..089631a307 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -464,7 +464,11 @@ NTSTATUS pvfs_access_check_unix(struct pvfs_state *pvfs, return NT_STATUS_ACCESS_DENIED; } - *access_mask |= SEC_FILE_READ_ATTRIBUTE; + if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) { + /* on SMB, this bit is always granted, even if not + asked for */ + *access_mask |= SEC_FILE_READ_ATTRIBUTE; + } return NT_STATUS_OK; } @@ -518,8 +522,11 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, /* check the acl against the required access mask */ status = sec_access_check(sd, token, *access_mask, access_mask); - /* this bit is always granted, even if not asked for */ - *access_mask |= SEC_FILE_READ_ATTRIBUTE; + if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) { + /* on SMB, this bit is always granted, even if not + asked for */ + *access_mask |= SEC_FILE_READ_ATTRIBUTE; + } talloc_free(acl); -- cgit From 21d770a02c1e5e492c3d764881b82cbc0871ced0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 18:23:33 +1000 Subject: querying the ACCESS_INFORMATION is always allowed (This used to be commit 25d5b94d6a700f2d294e108aeca85cffcd5bbb4f) --- source4/ntvfs/posix/pvfs_qfileinfo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_qfileinfo.c b/source4/ntvfs/posix/pvfs_qfileinfo.c index b9f763c2e0..3196cf2f8d 100644 --- a/source4/ntvfs/posix/pvfs_qfileinfo.c +++ b/source4/ntvfs/posix/pvfs_qfileinfo.c @@ -41,6 +41,10 @@ static uint32_t pvfs_fileinfo_access(union smb_fileinfo *info) needed = 0; break; + case RAW_FILEINFO_ACCESS_INFORMATION: + needed = 0; + break; + case RAW_FILEINFO_SEC_DESC: needed = 0; if (info->query_secdesc.in.secinfo_flags & (SECINFO_OWNER|SECINFO_GROUP)) { -- cgit From c86dc11be6e626fa81f025d7ec78226fb4249cdc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 19:16:26 +1000 Subject: added support for returning the maximal access MXAC tag in SMB2 create (This used to be commit 4eb49335d5f0319f9aa47ded5215a2977d3336bf) --- source4/ntvfs/ntvfs_generic.c | 2 ++ source4/ntvfs/posix/pvfs_acl.c | 12 ++++++++++++ source4/ntvfs/posix/pvfs_open.c | 24 ++++++++++++++++++++---- 3 files changed, 34 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 9227295696..d705758475 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -233,6 +233,7 @@ static NTSTATUS ntvfs_map_open_finish(struct ntvfs_module_context *ntvfs, io->smb2.out.size = io2->generic.out.size; io->smb2.out.file_attr = io2->generic.out.attrib; io->smb2.out.reserved2 = 0; + io->smb2.out.maximal_access = io2->generic.out.maximal_access; break; default: @@ -522,6 +523,7 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, io2->generic.in.fname = io->smb2.in.fname; io2->generic.in.sec_desc = io->smb2.in.sec_desc; io2->generic.in.ea_list = &io->smb2.in.eas; + io2->generic.in.query_maximal_access = io->smb2.in.query_maximal_access; /* we don't support timewarp yet */ if (io->smb2.in.timewarp != 0) { diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 089631a307..623b1ae5e9 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -807,3 +807,15 @@ NTSTATUS pvfs_acl_inherit(struct pvfs_state *pvfs, return status; } + +/* + return the maximum allowed access mask +*/ +NTSTATUS pvfs_access_maximal_allowed(struct pvfs_state *pvfs, + struct ntvfs_request *req, + struct pvfs_filename *name, + uint32_t *maximal_access) +{ + *maximal_access = SEC_FLAG_MAXIMUM_ALLOWED; + return pvfs_access_check(pvfs, req, name, maximal_access); +} diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a1c5571258..dada9f503f 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -252,8 +252,12 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } else { status = pvfs_access_check_create(pvfs, req, name, &access_mask); } - if (!NT_STATUS_IS_OK(status)) { - return status; + NT_STATUS_NOT_OK_RETURN(status); + + if (io->generic.in.query_maximal_access) { + status = pvfs_access_maximal_allowed(pvfs, req, name, + &io->generic.out.maximal_access); + NT_STATUS_NOT_OK_RETURN(status); } f->ntvfs = h; @@ -578,6 +582,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, status = pvfs_access_check_create(pvfs, req, name, &access_mask); NT_STATUS_NOT_OK_RETURN(status); + if (io->generic.in.query_maximal_access) { + status = pvfs_access_maximal_allowed(pvfs, req, name, + &io->generic.out.maximal_access); + NT_STATUS_NOT_OK_RETURN(status); + } + /* check that the parent isn't opened with delete on close set */ status = pvfs_resolve_parent(pvfs, req, name, &parent); if (NT_STATUS_IS_OK(status)) { @@ -1135,6 +1145,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return ntvfs_map_open(ntvfs, req, io); } + ZERO_STRUCT(io->generic.out); + create_options = io->generic.in.create_options; share_access = io->generic.in.share_access; access_mask = io->generic.in.access_mask; @@ -1282,8 +1294,12 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* check the security descriptor */ status = pvfs_access_check(pvfs, req, name, &access_mask); - if (!NT_STATUS_IS_OK(status)) { - return status; + NT_STATUS_NOT_OK_RETURN(status); + + if (io->generic.in.query_maximal_access) { + status = pvfs_access_maximal_allowed(pvfs, req, name, + &io->generic.out.maximal_access); + NT_STATUS_NOT_OK_RETURN(status); } status = ntvfs_handle_new(pvfs->ntvfs, req, &h); -- cgit From 383d10577cdee64c3d41682413445569ea3d202e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 20:46:18 +1000 Subject: fixed the error code for bad SMB2 ioctls (This used to be commit b1d2d388ecff96dfcc17da24796f36c40cbb3eed) --- source4/ntvfs/posix/pvfs_ioctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_ioctl.c b/source4/ntvfs/posix/pvfs_ioctl.c index d0360e67ed..92d3eae061 100644 --- a/source4/ntvfs/posix/pvfs_ioctl.c +++ b/source4/ntvfs/posix/pvfs_ioctl.c @@ -73,7 +73,8 @@ NTSTATUS pvfs_ioctl(struct ntvfs_module_context *ntvfs, case RAW_IOCTL_SMB2: case RAW_IOCTL_SMB2_NO_HANDLE: - return NT_STATUS_FS_DRIVER_REQUIRED; + /* see WSPP SMB2 test 46 */ + return NT_STATUS_INVALID_DEVICE_REQUEST; } return NT_STATUS_INVALID_LEVEL; -- cgit From f0bc7c07fe3148adee4ee625fcfc24cd5d4cc034 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 29 May 2008 22:22:42 +1000 Subject: don't mask out SEC_FILE_READ_ATTRIBUTE on SMB2 (This used to be commit 1dfa50a48040bdc1166be2dbe1063fd8a79166f8) --- source4/ntvfs/posix/pvfs_acl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 623b1ae5e9..9a9200e4f0 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -500,7 +500,9 @@ NTSTATUS pvfs_access_check(struct pvfs_state *pvfs, /* expand the generic access bits to file specific bits */ *access_mask = pvfs_translate_mask(*access_mask); - *access_mask &= ~SEC_FILE_READ_ATTRIBUTE; + if (pvfs->ntvfs->ctx->protocol != PROTOCOL_SMB2) { + *access_mask &= ~SEC_FILE_READ_ATTRIBUTE; + } status = pvfs_acl_load(pvfs, name, -1, acl); if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { -- cgit From b33dba845e4e583a25c2f88b8439b8dde205dc89 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 May 2008 07:28:29 +1000 Subject: don't emulate broken SMB2 locking behaviour from windows (This used to be commit c50e7a15f9a7f2c5821b5ee468f9ade6eaa0ed55) --- source4/ntvfs/posix/pvfs_lock.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index baa92880f1..822b28246a 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -68,13 +68,8 @@ static void pvfs_lock_async_failed(struct pvfs_state *pvfs, int i, NTSTATUS status) { - /* in SMB2 mode we also try to unlock failing lock */ - if (req->ctx->protocol != PROTOCOL_SMB2) { - i--; - } - /* undo the locks we just did */ - for (;i>=0;i--) { + for (i--;i>=0;i--) { brl_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, @@ -390,12 +385,9 @@ NTSTATUS pvfs_lock(struct ntvfs_module_context *ntvfs, DLIST_ADD(f->pending_list, pending); return NT_STATUS_OK; } - /* in SMB2 mode we also try to unlock failing lock */ - if (req->ctx->protocol != PROTOCOL_SMB2) { - i--; - } + /* undo the locks we just did */ - for (;i>=0;i--) { + for (i--;i>=0;i--) { brl_unlock(pvfs->brl_context, f->brl_handle, locks[i].pid, -- cgit From beaa01e403dda7557a6acdf0181d79d58a33bbbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 May 2008 17:03:54 +1000 Subject: implemented client side SMB2 signing This doessn't work against Windows yet, and I've submitted a WSPP request for clarification of the docs to try and find out why. Meanwhile this is no worse than what we had, as it only gets used when the server demands signing, and we didn't work then anyway. (This used to be commit b788096add3586d7277efcd3bf5ca7f3a604cb7a) --- source4/ntvfs/smb2/vfs_smb2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index cc09daf83f..68b475a084 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -162,9 +162,9 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct composite_context *creq; struct share_config *scfg = ntvfs->ctx->config; struct smb2_tree *tree; - struct cli_credentials *credentials; bool machine_account; + struct smbcli_options options; /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. @@ -224,10 +224,12 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } + lp_smbcli_options(ntvfs->ctx->lp_ctx, &options); + creq = smb2_connect_send(private, host, remote_share, lp_resolve_context(ntvfs->ctx->lp_ctx), credentials, - ntvfs->ctx->event_ctx); + ntvfs->ctx->event_ctx, &options); status = smb2_connect_recv(creq, private, &tree); NT_STATUS_NOT_OK_RETURN(status); -- cgit From 1bdd08227e7d046305705050f21f0f1b6dd6994a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Jun 2008 11:03:19 +1000 Subject: smbpid needs to be 32 bit now to cope with SMB2 (This used to be commit a2854fd6eaf097b5a9a562e0b8f1a599485fec42) --- source4/ntvfs/common/brlock.c | 2 +- source4/ntvfs/common/brlock_tdb.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/brlock.c b/source4/ntvfs/common/brlock.c index c87eca8aff..3b34873152 100644 --- a/source4/ntvfs/common/brlock.c +++ b/source4/ntvfs/common/brlock.c @@ -109,7 +109,7 @@ NTSTATUS brl_remove_pending(struct brl_context *brl, */ NTSTATUS brl_locktest(struct brl_context *brl, struct brl_handle *brlh, - uint16_t smbpid, + uint32_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) { diff --git a/source4/ntvfs/common/brlock_tdb.c b/source4/ntvfs/common/brlock_tdb.c index 362a6d01e2..c94b9b446e 100644 --- a/source4/ntvfs/common/brlock_tdb.c +++ b/source4/ntvfs/common/brlock_tdb.c @@ -57,7 +57,7 @@ struct brl_context { */ struct lock_context { struct server_id server; - uint16_t smbpid; + uint32_t smbpid; struct brl_context *ctx; }; @@ -286,7 +286,7 @@ static NTSTATUS brl_tdb_lock_failed(struct brl_handle *brlh, struct lock_struct */ static NTSTATUS brl_tdb_lock(struct brl_context *brl, struct brl_handle *brlh, - uint16_t smbpid, + uint32_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type, void *notify_ptr) @@ -436,7 +436,7 @@ static void brl_tdb_notify_all(struct brl_context *brl, */ static NTSTATUS brl_tdb_unlock(struct brl_context *brl, struct brl_handle *brlh, - uint16_t smbpid, + uint32_t smbpid, uint64_t start, uint64_t size) { TDB_DATA kbuf, dbuf; @@ -581,7 +581,7 @@ static NTSTATUS brl_tdb_remove_pending(struct brl_context *brl, */ static NTSTATUS brl_tdb_locktest(struct brl_context *brl, struct brl_handle *brlh, - uint16_t smbpid, + uint32_t smbpid, uint64_t start, uint64_t size, enum brl_type lock_type) { -- cgit From 8da3217d1b6b8b7a7b977c1722bc6ad39df49762 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Jun 2008 11:04:13 +1000 Subject: smbpid is 32 bit, and update SMB2 locking per MS-SMB2 The UNLOCK bit is only used from the first lock structure (This used to be commit 9483b7c137b61d3029a1e1e7d8d8d0723b541129) --- source4/ntvfs/ntvfs.h | 2 +- source4/ntvfs/ntvfs_generic.c | 45 +++++++++++++++++------------------------ source4/ntvfs/posix/pvfs_lock.c | 2 +- 3 files changed, 21 insertions(+), 28 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs.h b/source4/ntvfs/ntvfs.h index 7a2edc7e2c..5de8a8b649 100644 --- a/source4/ntvfs/ntvfs.h +++ b/source4/ntvfs/ntvfs.h @@ -263,7 +263,7 @@ struct ntvfs_request { struct auth_session_info *session_info; /* the smb pid is needed for locking contexts */ - uint16_t smbpid; + uint32_t smbpid; /* * client capabilities diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index d705758475..a3a8fcb1f4 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -986,8 +986,8 @@ NTSTATUS ntvfs_map_qpathinfo(struct ntvfs_module_context *ntvfs, NTVFS lock generic to any mapper */ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, - struct ntvfs_request *req, - union smb_lock *lck) + struct ntvfs_request *req, + union smb_lock *lck) { union smb_lock *lck2; struct smb_lock_entry *locks; @@ -1035,7 +1035,8 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, case RAW_LOCK_SMB2: { /* this is only approximate! We need to change the generic structure to fix this properly */ - int i, j; + int i; + bool isunlock; if (lck->smb2.in.lock_count < 1) { return NT_STATUS_INVALID_PARAMETER; } @@ -1051,32 +1052,24 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, if (lck2->generic.in.locks == NULL) { return NT_STATUS_NO_MEMORY; } - for (i=0;ismb2.in.lock_count;i++) { - if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) { - break; - } - j = lck2->generic.in.ulock_cnt; - if (lck->smb2.in.locks[i].flags & - (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE)) { - return NT_STATUS_INVALID_PARAMETER; - } - lck2->generic.in.ulock_cnt++; - lck2->generic.in.locks[j].pid = 0; - lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; - lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; - lck2->generic.in.locks[j].pid = 0; + /* only the first lock gives the UNLOCK bit - see + MS-SMB2 3.3.5.14 */ + if (lck->smb2.in.locks[0].flags & SMB2_LOCK_FLAG_UNLOCK) { + lck2->generic.in.ulock_cnt = lck->smb2.in.lock_count; + isunlock = true; + } else { + lck2->generic.in.lock_cnt = lck->smb2.in.lock_count; + isunlock = false; } - for (;ismb2.in.lock_count;i++) { - if (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK) { - /* w2008 requires unlocks to come first */ + for (i=0;ismb2.in.lock_count;i++) { + if (isunlock && + (lck->smb2.in.locks[i].flags & + (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE))) { return NT_STATUS_INVALID_PARAMETER; } - j = lck2->generic.in.ulock_cnt + lck2->generic.in.lock_cnt; - lck2->generic.in.lock_cnt++; - lck2->generic.in.locks[j].pid = 0; - lck2->generic.in.locks[j].offset = lck->smb2.in.locks[i].offset; - lck2->generic.in.locks[j].count = lck->smb2.in.locks[i].length; - lck2->generic.in.locks[j].pid = 0; + lck2->generic.in.locks[i].pid = req->smbpid; + lck2->generic.in.locks[i].offset = lck->smb2.in.locks[i].offset; + lck2->generic.in.locks[i].count = lck->smb2.in.locks[i].length; if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) { lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; } diff --git a/source4/ntvfs/posix/pvfs_lock.c b/source4/ntvfs/posix/pvfs_lock.c index 822b28246a..0054455838 100644 --- a/source4/ntvfs/posix/pvfs_lock.c +++ b/source4/ntvfs/posix/pvfs_lock.c @@ -31,7 +31,7 @@ */ NTSTATUS pvfs_check_lock(struct pvfs_state *pvfs, struct pvfs_file *f, - uint16_t smbpid, + uint32_t smbpid, uint64_t offset, uint64_t count, enum brl_type rw) { -- cgit From 405e64c437348bc9e3f7d4412a55e5cf05b3890d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 2 Jun 2008 11:05:06 +1000 Subject: more updates for new info levels (This used to be commit 85d1873ee92fcc7df3addc42ddb8189144901f8b) --- source4/ntvfs/posix/pvfs_oplock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_oplock.c b/source4/ntvfs/posix/pvfs_oplock.c index dfa3697af7..71add72987 100644 --- a/source4/ntvfs/posix/pvfs_oplock.c +++ b/source4/ntvfs/posix/pvfs_oplock.c @@ -177,7 +177,7 @@ static void pvfs_oplock_break_dispatch(struct messaging_context *msg, opb = *p; } else { DEBUG(0,("%s: ignore oplock break with length[%u]\n", - __location__, data->length)); + __location__, (unsigned)data->length)); return; } if (opb.file_handle != opl->handle) { -- cgit From 538f624fe02b9420fe44a5c32e0d0fcf6fcf1359 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 3 Jun 2008 09:36:02 +1000 Subject: it is not valid to set a UNLOCK flag on a lock request (This used to be commit 63f315572969e7fc52bdc7c0b38eaaee736d5e2a) --- source4/ntvfs/ntvfs_generic.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index a3a8fcb1f4..4f3a7e2198 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -1067,9 +1067,13 @@ NTSTATUS ntvfs_map_lock(struct ntvfs_module_context *ntvfs, (SMB2_LOCK_FLAG_SHARED|SMB2_LOCK_FLAG_EXCLUSIVE))) { return NT_STATUS_INVALID_PARAMETER; } - lck2->generic.in.locks[i].pid = req->smbpid; + if (!isunlock && + (lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_UNLOCK)) { + return NT_STATUS_INVALID_PARAMETER; + } + lck2->generic.in.locks[i].pid = req->smbpid; lck2->generic.in.locks[i].offset = lck->smb2.in.locks[i].offset; - lck2->generic.in.locks[i].count = lck->smb2.in.locks[i].length; + lck2->generic.in.locks[i].count = lck->smb2.in.locks[i].length; if (!(lck->smb2.in.locks[i].flags & SMB2_LOCK_FLAG_EXCLUSIVE)) { lck2->generic.in.mode = LOCKING_ANDX_SHARED_LOCK; } -- cgit From 0827b08a433b7dec91be7ca7406804087f3fef07 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 15 Apr 2008 16:00:42 +0200 Subject: opendb: add write time handling metze (This used to be commit 3868d8ce630c71e2c70aae442fcdbd68ba1eb708) --- source4/ntvfs/common/opendb.c | 24 ++++++++++++------ source4/ntvfs/common/opendb.h | 9 ++++--- source4/ntvfs/common/opendb_tdb.c | 51 ++++++++++++++++++++++++++++++++++----- source4/ntvfs/posix/pvfs_open.c | 23 ++++++++++++------ source4/ntvfs/posix/vfs_posix.h | 8 ++++++ 5 files changed, 91 insertions(+), 24 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/common/opendb.c b/source4/ntvfs/common/opendb.c index 2913ea8431..6917bad52a 100644 --- a/source4/ntvfs/common/opendb.c +++ b/source4/ntvfs/common/opendb.c @@ -97,11 +97,13 @@ DATA_BLOB odb_get_key(TALLOC_CTX *mem_ctx, struct odb_lock *lck) */ NTSTATUS odb_open_file(struct odb_lock *lck, void *file_handle, const char *path, - int *fd, bool allow_level_II_oplock, + int *fd, NTTIME open_write_time, + bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { return ops->odb_open_file(lck, file_handle, path, - fd, allow_level_II_oplock, + fd, open_write_time, + allow_level_II_oplock, oplock_level, oplock_granted); } @@ -159,15 +161,23 @@ NTSTATUS odb_set_delete_on_close(struct odb_lock *lck, bool del_on_close) } /* - return the current value of the delete_on_close bit, and how many - people still have the file open + update the write time on an open file */ -NTSTATUS odb_get_delete_on_close(struct odb_context *odb, - DATA_BLOB *key, bool *del_on_close) +NTSTATUS odb_set_write_time(struct odb_lock *lck, + NTTIME write_time, bool force) { - return ops->odb_get_delete_on_close(odb, key, del_on_close); + return ops->odb_set_write_time(lck, write_time, force); } +/* + return the current value of the delete_on_close bit, + and the current write time. +*/ +NTSTATUS odb_get_file_infos(struct odb_context *odb, DATA_BLOB *key, + bool *del_on_close, NTTIME *write_time) +{ + return ops->odb_get_file_infos(odb, key, del_on_close, write_time); +} /* determine if a file can be opened with the given share_access, diff --git a/source4/ntvfs/common/opendb.h b/source4/ntvfs/common/opendb.h index 045476337a..179db111ca 100644 --- a/source4/ntvfs/common/opendb.h +++ b/source4/ntvfs/common/opendb.h @@ -27,7 +27,8 @@ struct opendb_ops { DATA_BLOB (*odb_get_key)(TALLOC_CTX *mem_ctx, struct odb_lock *lck); NTSTATUS (*odb_open_file)(struct odb_lock *lck, void *file_handle, const char *path, - int *fd, bool allow_level_II_oplock, + int *fd, NTTIME open_write_time, + bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted); NTSTATUS (*odb_open_file_pending)(struct odb_lock *lck, void *private); NTSTATUS (*odb_close_file)(struct odb_lock *lck, void *file_handle, @@ -36,8 +37,10 @@ struct opendb_ops { NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path); NTSTATUS (*odb_get_path)(struct odb_lock *lck, const char **path); NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close); - NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb, - DATA_BLOB *key, bool *del_on_close); + NTSTATUS (*odb_set_write_time)(struct odb_lock *lck, + NTTIME write_time, bool force); + NTSTATUS (*odb_get_file_infos)(struct odb_context *odb, DATA_BLOB *key, + bool *del_on_close, NTTIME *write_time); NTSTATUS (*odb_can_open)(struct odb_lock *lck, uint32_t stream_id, uint32_t share_access, uint32_t access_mask, bool delete_on_close, diff --git a/source4/ntvfs/common/opendb_tdb.c b/source4/ntvfs/common/opendb_tdb.c index 99c0a95c20..d7531297ed 100644 --- a/source4/ntvfs/common/opendb_tdb.c +++ b/source4/ntvfs/common/opendb_tdb.c @@ -452,7 +452,8 @@ static NTSTATUS odb_tdb_open_can_internal(struct odb_context *odb, */ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, void *file_handle, const char *path, - int *fd, bool allow_level_II_oplock, + int *fd, NTTIME open_write_time, + bool allow_level_II_oplock, uint32_t oplock_level, uint32_t *oplock_granted) { struct odb_context *odb = lck->odb; @@ -474,6 +475,10 @@ static NTSTATUS odb_tdb_open_file(struct odb_lock *lck, NT_STATUS_HAVE_NO_MEMORY(lck->file.path); } + if (lck->file.open_write_time == 0) { + lck->file.open_write_time = open_write_time; + } + /* possibly grant an exclusive, batch or level2 oplock */ @@ -784,21 +789,54 @@ static NTSTATUS odb_tdb_set_delete_on_close(struct odb_lock *lck, bool del_on_cl return odb_push_record(lck, &lck->file); } +/* + update the write time on an open file +*/ +static NTSTATUS odb_tdb_set_write_time(struct odb_lock *lck, + NTTIME write_time, bool force) +{ + if (lck->file.path == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + if (lck->file.changed_write_time != 0 && !force) { + return NT_STATUS_OK; + } + + lck->file.changed_write_time = write_time; + + return odb_push_record(lck, &lck->file); +} + /* return the current value of the delete_on_close bit, and how many people still have the file open */ -static NTSTATUS odb_tdb_get_delete_on_close(struct odb_context *odb, - DATA_BLOB *key, bool *del_on_close) +static NTSTATUS odb_tdb_get_file_infos(struct odb_context *odb, DATA_BLOB *key, + bool *del_on_close, NTTIME *write_time) { struct odb_lock *lck; - (*del_on_close) = false; + if (del_on_close) { + *del_on_close = false; + } + if (write_time) { + *write_time = 0; + } lck = odb_lock(odb, odb, key); NT_STATUS_HAVE_NO_MEMORY(lck); - (*del_on_close) = lck->file.delete_on_close; + if (del_on_close) { + *del_on_close = lck->file.delete_on_close; + } + if (write_time) { + if (lck->file.changed_write_time == 0) { + *write_time = lck->file.open_write_time; + } else { + *write_time = lck->file.changed_write_time; + } + } talloc_free(lck); @@ -852,7 +890,8 @@ static const struct opendb_ops opendb_tdb_ops = { .odb_rename = odb_tdb_rename, .odb_get_path = odb_tdb_get_path, .odb_set_delete_on_close = odb_tdb_set_delete_on_close, - .odb_get_delete_on_close = odb_tdb_get_delete_on_close, + .odb_set_write_time = odb_tdb_set_write_time, + .odb_get_file_infos = odb_tdb_get_file_infos, .odb_can_open = odb_tdb_can_open, .odb_update_oplock = odb_tdb_update_oplock, .odb_break_oplocks = odb_tdb_break_oplocks diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index dada9f503f..bdb6c9bad0 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -280,6 +280,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, f->handle->position = 0; f->handle->mode = 0; f->handle->oplock = NULL; + ZERO_STRUCT(f->handle->write_time); f->handle->open_completed = false; if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && @@ -317,7 +318,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, /* now really mark the file as open */ status = odb_open_file(lck, f->handle, name->full_name, - NULL, false, OPLOCK_NONE, NULL); + NULL, name->dos.write_time, + false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); @@ -377,7 +379,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs, } status = odb_open_file(lck, f->handle, name->full_name, - NULL, false, OPLOCK_NONE, NULL); + NULL, name->dos.write_time, + false, OPLOCK_NONE, NULL); if (!NT_STATUS_IS_OK(status)) { goto cleanup_delete; @@ -594,8 +597,8 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, DATA_BLOB locking_key; status = pvfs_locking_key(parent, req, &locking_key); NT_STATUS_NOT_OK_RETURN(status); - status = odb_get_delete_on_close(pvfs->odb_context, &locking_key, - &del_on_close); + status = odb_get_file_infos(pvfs->odb_context, &locking_key, + &del_on_close, NULL); NT_STATUS_NOT_OK_RETURN(status); if (del_on_close) { return NT_STATUS_DELETE_PENDING; @@ -730,10 +733,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = true; + ZERO_STRUCT(f->handle->write_time); f->handle->open_completed = false; status = odb_open_file(lck, f->handle, name->full_name, - &f->handle->fd, allow_level_II_oplock, + &f->handle->fd, name->dos.write_time, + allow_level_II_oplock, oplock_level, &oplock_granted); talloc_free(lck); if (!NT_STATUS_IS_OK(status)) { @@ -1334,6 +1339,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, f->handle->mode = 0; f->handle->oplock = NULL; f->handle->have_opendb_entry = false; + ZERO_STRUCT(f->handle->write_time); f->handle->open_completed = false; /* form the lock context used for byte range locking and @@ -1437,7 +1443,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* now really mark the file as open */ status = odb_open_file(lck, f->handle, name->full_name, - &f->handle->fd, allow_level_II_oplock, + &f->handle->fd, name->dos.write_time, + allow_level_II_oplock, oplock_level, &oplock_granted); if (!NT_STATUS_IS_OK(status)) { @@ -1915,8 +1922,8 @@ bool pvfs_delete_on_close_set(struct pvfs_state *pvfs, struct pvfs_file_handle * NTSTATUS status; bool del_on_close; - status = odb_get_delete_on_close(pvfs->odb_context, &h->odb_locking_key, - &del_on_close); + status = odb_get_file_infos(pvfs->odb_context, &h->odb_locking_key, + &del_on_close, NULL); if (!NT_STATUS_IS_OK(status)) { DEBUG(1,("WARNING: unable to determine delete on close status for open file\n")); return false; diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index c194698b64..875deb4015 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -169,6 +169,14 @@ struct pvfs_file_handle { /* we need this hook back to our parent for lock destruction */ struct pvfs_state *pvfs; + struct { + bool update_triggered; + struct timed_event *update_event; + bool update_on_close; + NTTIME close_time; + bool update_forced; + } write_time; + /* the open went through to completion */ bool open_completed; }; -- cgit From c43591c2168577a790051fc27840ab5cef7866c4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 5 May 2008 12:18:47 +0200 Subject: pvfs: add PVFS_RESOLVE_NO_OPENDB flag and get the write time from the opendb By default get the current write time from the opendb, but allow callers to pass PVFS_RESOLVE_NO_OPENDB for performance reasons, if they don't need to the write time. metze (This used to be commit def52cc0988c26a815e74b3391e5857512408d90) --- source4/ntvfs/posix/pvfs_fileinfo.c | 31 +++++++++++++++++++++++++++++-- source4/ntvfs/posix/pvfs_open.c | 4 ++-- source4/ntvfs/posix/pvfs_rename.c | 8 ++++++-- source4/ntvfs/posix/pvfs_resolve.c | 28 +++++++++++++++++----------- source4/ntvfs/posix/pvfs_search.c | 2 +- source4/ntvfs/posix/pvfs_seek.c | 2 +- source4/ntvfs/posix/pvfs_unlink.c | 9 +++++++-- source4/ntvfs/posix/vfs_posix.h | 1 + 8 files changed, 64 insertions(+), 21 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_fileinfo.c b/source4/ntvfs/posix/pvfs_fileinfo.c index 04f6ad78d0..a14c8f64ae 100644 --- a/source4/ntvfs/posix/pvfs_fileinfo.c +++ b/source4/ntvfs/posix/pvfs_fileinfo.c @@ -52,8 +52,13 @@ static uint32_t dos_mode_from_stat(struct pvfs_state *pvfs, struct stat *st) /* fill in the dos file attributes for a file */ -NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd) +NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, + uint_t flags, int fd) { + NTSTATUS status; + DATA_BLOB lkey; + NTTIME write_time; + /* make directories appear as size 0 with 1 link */ if (S_ISDIR(name->st.st_mode)) { name->st.st_size = 0; @@ -85,7 +90,29 @@ NTSTATUS pvfs_fill_dos_info(struct pvfs_state *pvfs, struct pvfs_filename *name, name->dos.file_id = (((uint64_t)name->st.st_dev)<<32) | name->st.st_ino; name->dos.flags = 0; - return pvfs_dosattrib_load(pvfs, name, fd); + status = pvfs_dosattrib_load(pvfs, name, fd); + NT_STATUS_NOT_OK_RETURN(status); + + if (flags & PVFS_RESOLVE_NO_OPENDB) { + return NT_STATUS_OK; + } + + status = pvfs_locking_key(name, name, &lkey); + NT_STATUS_NOT_OK_RETURN(status); + + status = odb_get_file_infos(pvfs->odb_context, &lkey, + NULL, &write_time); + data_blob_free(&lkey); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1,("WARNING: odb_get_file_infos: %s\n", nt_errstr(status))); + return status; + } + + if (!null_time(write_time)) { + name->dos.write_time = write_time; + } + + return NT_STATUS_OK; } diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index bdb6c9bad0..94480df6b7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -641,7 +641,7 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, } /* re-resolve the open fd */ - status = pvfs_resolve_name_fd(pvfs, fd, name); + status = pvfs_resolve_name_fd(pvfs, fd, name, 0); if (!NT_STATUS_IS_OK(status)) { close(fd); return status; @@ -1483,7 +1483,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, } /* re-resolve the open fd */ - status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name); + status = pvfs_resolve_name_fd(f->pvfs, fd, f->handle->name, PVFS_RESOLVE_NO_OPENDB); if (!NT_STATUS_IS_OK(status)) { talloc_free(lck); return status; diff --git a/source4/ntvfs/posix/pvfs_rename.c b/source4/ntvfs/posix/pvfs_rename.c index 5c2a627084..d8ea5896e5 100644 --- a/source4/ntvfs/posix/pvfs_rename.c +++ b/source4/ntvfs/posix/pvfs_rename.c @@ -287,7 +287,9 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, /* get a pvfs_filename source object */ status = pvfs_resolve_partial(pvfs, mem_ctx, - dir_path, fname1, &name1); + dir_path, fname1, + PVFS_RESOLVE_NO_OPENDB, + &name1); if (!NT_STATUS_IS_OK(status)) { goto failed; } @@ -306,7 +308,9 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs, /* get a pvfs_filename dest object */ status = pvfs_resolve_partial(pvfs, mem_ctx, - dir_path, fname2, &name2); + dir_path, fname2, + PVFS_RESOLVE_NO_OPENDB, + &name2); if (NT_STATUS_IS_OK(status)) { status = pvfs_can_delete(pvfs, req, name2, NULL); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 2e97925c49..969a50239f 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -57,7 +57,9 @@ static int component_compare(struct pvfs_state *pvfs, const char *comp, const ch TODO: add a cache for previously resolved case-insensitive names TODO: add mangled name support */ -static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename *name) +static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, + struct pvfs_filename *name, + uint_t flags) { /* break into a series of components */ int num_components; @@ -175,7 +177,7 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs, struct pvfs_filename * name->full_name = partial_name; if (name->exists) { - return pvfs_fill_dos_info(pvfs, name, -1); + return pvfs_fill_dos_info(pvfs, name, flags, -1); } return NT_STATUS_OK; @@ -515,7 +517,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* we need to search for a matching name */ saved_name = (*name)->full_name; (*name)->full_name = dir_name; - status = pvfs_case_search(pvfs, *name); + status = pvfs_case_search(pvfs, *name, flags); if (!NT_STATUS_IS_OK(status)) { /* the directory doesn't exist */ (*name)->full_name = saved_name; @@ -536,11 +538,11 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, /* if we can stat() the full name now then we are done */ if (stat((*name)->full_name, &(*name)->st) == 0) { (*name)->exists = true; - return pvfs_fill_dos_info(pvfs, *name, -1); + return pvfs_fill_dos_info(pvfs, *name, flags, -1); } /* search for a matching filename */ - status = pvfs_case_search(pvfs, *name); + status = pvfs_case_search(pvfs, *name, flags); return status; } @@ -556,7 +558,7 @@ NTSTATUS pvfs_resolve_name(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, */ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, const char *unix_dir, const char *fname, - struct pvfs_filename **name) + uint_t flags, struct pvfs_filename **name) { NTSTATUS status; @@ -581,7 +583,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, (*name)->stream_name = NULL; (*name)->stream_id = 0; - status = pvfs_fill_dos_info(pvfs, *name, -1); + status = pvfs_fill_dos_info(pvfs, *name, flags, -1); return status; } @@ -593,7 +595,7 @@ NTSTATUS pvfs_resolve_partial(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, to update the pvfs_filename stat information, and by pvfs_open() */ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, - struct pvfs_filename *name) + struct pvfs_filename *name, uint_t flags) { dev_t device = (dev_t)0; ino_t inode = 0; @@ -626,7 +628,7 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd, name->exists = true; - return pvfs_fill_dos_info(pvfs, name, fd); + return pvfs_fill_dos_info(pvfs, name, flags, fd); } /* @@ -703,7 +705,11 @@ NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs, talloc_free(lck); } - status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + /* + * TODO: pass PVFS_RESOLVE_NO_OPENDB and get + * the write time from odb_lock() above. + */ + status = pvfs_resolve_name_fd(pvfs, h->fd, h->name, 0); NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; @@ -755,7 +761,7 @@ NTSTATUS pvfs_resolve_parent(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, (*name)->stream_name = NULL; (*name)->stream_id = 0; - status = pvfs_fill_dos_info(pvfs, *name, -1); + status = pvfs_fill_dos_info(pvfs, *name, PVFS_RESOLVE_NO_OPENDB, -1); return status; } diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index e47406dc09..e0fe4fb64d 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -84,7 +84,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs, in pvfs_list_seek_ofs() for how we cope with this */ - status = pvfs_resolve_partial(pvfs, file, unix_path, fname, &name); + status = pvfs_resolve_partial(pvfs, file, unix_path, fname, 0, &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/pvfs_seek.c b/source4/ntvfs/posix/pvfs_seek.c index 3ea8b7cb6e..a3c4024ed7 100644 --- a/source4/ntvfs/posix/pvfs_seek.c +++ b/source4/ntvfs/posix/pvfs_seek.c @@ -52,7 +52,7 @@ NTSTATUS pvfs_seek(struct ntvfs_module_context *ntvfs, break; case SEEK_MODE_END: - status = pvfs_resolve_name_fd(pvfs, h->fd, h->name); + status = pvfs_resolve_name_fd(pvfs, h->fd, h->name, PVFS_RESOLVE_NO_OPENDB); h->seek_offset = h->name->st.st_size + io->lseek.in.offset; break; } diff --git a/source4/ntvfs/posix/pvfs_unlink.c b/source4/ntvfs/posix/pvfs_unlink.c index 4cb47a4f1f..6a57041770 100644 --- a/source4/ntvfs/posix/pvfs_unlink.c +++ b/source4/ntvfs/posix/pvfs_unlink.c @@ -201,7 +201,10 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, /* resolve the cifs name to a posix name */ status = pvfs_resolve_name(pvfs, req, unl->unlink.in.pattern, - PVFS_RESOLVE_WILDCARD | PVFS_RESOLVE_STREAMS, &name); + PVFS_RESOLVE_WILDCARD | + PVFS_RESOLVE_STREAMS | + PVFS_RESOLVE_NO_OPENDB, + &name); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -246,7 +249,9 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs, /* get a pvfs_filename object */ status = pvfs_resolve_partial(pvfs, req, pvfs_list_unix_path(dir), - fname, &name); + fname, + PVFS_RESOLVE_NO_OPENDB, + &name); if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index 875deb4015..d25f8a879e 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -228,6 +228,7 @@ struct pvfs_search_state { /* flags to pvfs_resolve_name() */ #define PVFS_RESOLVE_WILDCARD (1<<0) #define PVFS_RESOLVE_STREAMS (1<<1) +#define PVFS_RESOLVE_NO_OPENDB (1<<2) /* flags in pvfs->flags */ #define PVFS_FLAG_CI_FILESYSTEM (1<<0) /* the filesystem is case insensitive */ -- cgit From 47b54c7680c98fee40916cbfb5c3ad05a178d3a1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Jun 2008 11:34:10 +0200 Subject: pvfs: add posix:writetimeupdatedelay option metze (This used to be commit c3ba19ca62affced96b927fcbe63cf5d075aed22) --- source4/ntvfs/posix/vfs_posix.c | 4 ++++ source4/ntvfs/posix/vfs_posix.h | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index 14b5210fd0..b5dd270346 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -95,6 +95,10 @@ static void pvfs_setup_options(struct pvfs_state *pvfs) PVFS_OPLOCK_TIMEOUT, PVFS_OPLOCK_TIMEOUT_DEFAULT); + pvfs->writetime_delay = share_int_option(scfg, + PVFS_WRITETIME_DELAY, + PVFS_WRITETIME_DELAY_DEFAULT); + pvfs->share_name = talloc_strdup(pvfs, scfg->name); pvfs->fs_attribs = diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index d25f8a879e..cf39bcf0ac 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -59,6 +59,9 @@ struct pvfs_state { /* the oplock break timeout (secs) */ uint_t oplock_break_timeout; + /* the write time update delay (nsecs) */ + uint_t writetime_delay; + /* filesystem attributes (see FS_ATTR_*) */ uint32_t fs_attribs; @@ -258,6 +261,7 @@ struct pvfs_odb_retry; #define PVFS_FAKE_OPLOCKS "posix:fakeoplocks" #define PVFS_SHARE_DELAY "posix:sharedelay" #define PVFS_OPLOCK_TIMEOUT "posix:oplocktimeout" +#define PVFS_WRITETIME_DELAY "posix:writetimeupdatedelay" #define PVFS_ALLOCATION_ROUNDING "posix:allocationrounding" #define PVFS_SEARCH_INACTIVITY "posix:searchinactivity" #define PVFS_ACL "posix:acl" @@ -267,6 +271,7 @@ struct pvfs_odb_retry; #define PVFS_FAKE_OPLOCKS_DEFAULT false #define PVFS_SHARE_DELAY_DEFAULT 1000000 /* nsecs */ #define PVFS_OPLOCK_TIMEOUT_DEFAULT 30 /* secs */ +#define PVFS_WRITETIME_DELAY_DEFAULT 2000000 /* nsecs */ #define PVFS_ALLOCATION_ROUNDING_DEFAULT 512 #define PVFS_SEARCH_INACTIVITY_DEFAULT 300 -- cgit From ad19d5455ead83d5b4127e93d6466aab4cee75c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Jun 2008 11:36:08 +0200 Subject: pvfs: trigger a write time update 2 seconds after the first write metze (This used to be commit c8e15d4c185f18322a882aa908939fa9d0e341a0) --- source4/ntvfs/posix/pvfs_write.c | 55 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_write.c b/source4/ntvfs/posix/pvfs_write.c index 1f662f13fc..2da0e4bb3a 100644 --- a/source4/ntvfs/posix/pvfs_write.c +++ b/source4/ntvfs/posix/pvfs_write.c @@ -22,7 +22,60 @@ #include "includes.h" #include "vfs_posix.h" #include "librpc/gen_ndr/security.h" +#include "lib/events/events.h" +static void pvfs_write_time_update_handler(struct event_context *ev, + struct timed_event *te, + struct timeval tv, + void *private_data) +{ + struct pvfs_file_handle *h = talloc_get_type(private_data, + struct pvfs_file_handle); + struct odb_lock *lck; + NTSTATUS status; + NTTIME write_time; + + lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for write time update\n")); + return; + } + + write_time = timeval_to_nttime(&tv); + + status = odb_set_write_time(lck, write_time, false); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to update write time: %s\n", + nt_errstr(status))); + return; + } + + talloc_free(lck); + + h->write_time.update_event = NULL; +} + +static void pvfs_trigger_write_time_update(struct pvfs_file_handle *h) +{ + struct pvfs_state *pvfs = h->pvfs; + struct timeval tv; + + if (h->write_time.update_triggered) { + return; + } + + tv = timeval_current_ofs(0, pvfs->writetime_delay); + + h->write_time.update_triggered = true; + h->write_time.update_on_close = true; + h->write_time.update_event = event_add_timed(pvfs->ntvfs->ctx->event_ctx, + h, tv, + pvfs_write_time_update_handler, + h); + if (!h->write_time.update_event) { + DEBUG(0,("Failed event_add_timed\n")); + } +} /* write to a file @@ -61,6 +114,8 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs, status = pvfs_break_level2_oplocks(f); NT_STATUS_NOT_OK_RETURN(status); + pvfs_trigger_write_time_update(f->handle); + if (f->handle->name->stream_name) { ret = pvfs_stream_write(pvfs, f->handle, -- cgit From d1bb49a2ab08f8f4eb27ae44bf04bc381faa85c1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Jun 2008 11:47:12 +0200 Subject: pvfs_setfileinfo: update the write time in the opendb metze (This used to be commit 418e2592b48d558ff1d32031d64263ae21cf1eb0) --- source4/ntvfs/posix/pvfs_setfileinfo.c | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index 1dd2c075d9..b0f636f999 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -454,6 +454,30 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } } + if (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE) { + struct odb_lock *lck; + + lck = odb_lock(req, h->pvfs->odb_context, &h->odb_locking_key); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for write time update\n")); + return NT_STATUS_INTERNAL_ERROR; + } + + status = odb_set_write_time(lck, newstats.dos.write_time, true); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to update write time: %s\n", + nt_errstr(status))); + talloc_free(lck); + return status; + } + + talloc_free(lck); + + h->write_time.update_forced = true; + h->write_time.update_on_close = false; + talloc_free(h->write_time.update_event); + h->write_time.update_event = NULL; + } /* possibly change the attribute */ if (newstats.dos.attrib != h->name->dos.attrib) { @@ -753,6 +777,29 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, return pvfs_map_errno(pvfs, errno); } } + if (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE) { + if (lck == NULL) { + DATA_BLOB lkey; + status = pvfs_locking_key(name, name, &lkey); + NT_STATUS_NOT_OK_RETURN(status); + + lck = odb_lock(req, pvfs->odb_context, &lkey); + data_blob_free(&lkey); + if (lck == NULL) { + DEBUG(0,("Unable to lock opendb for write time update\n")); + return NT_STATUS_INTERNAL_ERROR; + } + } + + status = odb_set_write_time(lck, newstats.dos.write_time, true); + if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + /* it could be that nobody has opened the file */ + } else if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable to update write time: %s\n", + nt_errstr(status))); + return status; + } + } /* possibly change the attribute */ newstats.dos.attrib |= (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY); -- cgit From 60759b64a7508b161de795e42c46c2bd62e0728a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Jun 2008 11:54:21 +0200 Subject: pvfs: correctly set the write time in the handle destructor metze (This used to be commit 58c118ab4d2b76c4ea68d79b711b81900634f767) --- source4/ntvfs/posix/pvfs_open.c | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 94480df6b7..c7f93fb0d8 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -436,6 +436,9 @@ cleanup_delete: */ static int pvfs_handle_destructor(struct pvfs_file_handle *h) { + talloc_free(h->write_time.update_event); + h->write_time.update_event = NULL; + if ((h->create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && h->name->stream_name) { NTSTATUS status; @@ -454,6 +457,14 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) h->fd = -1; } + if (!h->write_time.update_forced && + h->write_time.update_on_close && + h->write_time.close_time == 0) { + struct timeval tv; + tv = timeval_current(); + h->write_time.close_time = timeval_to_nttime(&tv); + } + if (h->have_opendb_entry) { struct odb_lock *lck; NTSTATUS status; @@ -465,6 +476,26 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) return 0; } + if (h->write_time.update_forced) { + status = odb_get_file_infos(h->pvfs->odb_context, + &h->odb_locking_key, + NULL, + &h->write_time.close_time); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable get write time for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + } + + h->write_time.update_forced = false; + h->write_time.update_on_close = true; + } else if (h->write_time.update_on_close) { + status = odb_set_write_time(lck, h->write_time.close_time, true); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Unable set write time for '%s' - %s\n", + h->name->full_name, nt_errstr(status))); + } + } + status = odb_close_file(lck, h, &delete_path); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Unable to remove opendb entry for '%s' - %s\n", @@ -487,11 +518,26 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) FILE_NOTIFY_CHANGE_FILE_NAME, delete_path); } + h->write_time.update_on_close = false; } talloc_free(lck); } + if (h->write_time.update_on_close) { + struct utimbuf unix_times; + + unix_times.actime = nt_time_to_unix(h->name->dos.access_time); + unix_times.modtime = nt_time_to_unix(h->write_time.close_time); + + if (unix_times.actime != 0 || unix_times.modtime != 0) { + if (utime(h->name->full_name, &unix_times) == -1) { + DEBUG(0,("pvfs_close: utime() failed '%s' - %s\n", + h->name->full_name, strerror(errno))); + } + } + } + return 0; } -- cgit From 6e52c4feb80ef68659569ffef8796441df9a7cee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 May 2008 22:16:55 +0200 Subject: pvfs_close: correctly handle the write time updates passed by close() metze (This used to be commit 7f033ce4fb6fc897f8159926d5a6d2e45dd447b6) --- source4/ntvfs/posix/pvfs_open.c | 7 +++---- source4/ntvfs/posix/pvfs_resolve.c | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index c7f93fb0d8..a78d0a79c7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1591,7 +1591,6 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, { struct pvfs_state *pvfs = ntvfs->private_data; struct pvfs_file *f; - struct utimbuf unix_times; if (io->generic.level == RAW_CLOSE_SPLCLOSE) { return NT_STATUS_DOS(ERRSRV, ERRerror); @@ -1607,9 +1606,9 @@ NTSTATUS pvfs_close(struct ntvfs_module_context *ntvfs, } if (!null_time(io->generic.in.write_time)) { - unix_times.actime = 0; - unix_times.modtime = io->close.in.write_time; - utime(f->handle->name->full_name, &unix_times); + f->handle->write_time.update_forced = false; + f->handle->write_time.update_on_close = true; + unix_to_nt_time(&f->handle->write_time.close_time, io->generic.in.write_time); } if (io->generic.in.flags & SMB2_CLOSE_FLAGS_FULL_INFORMATION) { diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c index 969a50239f..0f19788b97 100644 --- a/source4/ntvfs/posix/pvfs_resolve.c +++ b/source4/ntvfs/posix/pvfs_resolve.c @@ -712,6 +712,10 @@ NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs, status = pvfs_resolve_name_fd(pvfs, h->fd, h->name, 0); NT_STATUS_NOT_OK_RETURN(status); + if (!null_nttime(h->write_time.close_time)) { + h->name->dos.write_time = h->write_time.close_time; + } + return NT_STATUS_OK; } -- cgit From b800af662cd1135432c835643e2736921e173998 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 3 Jun 2008 13:32:04 +0200 Subject: pvfs: use utimes() instead of utime() to get better timestamp resolution Note: that libreplace always provides utimes() metze (This used to be commit 61bad69e2d7f84e2c6d6fb82917cfa86b17f54b0) --- source4/ntvfs/posix/pvfs_open.c | 12 +++++----- source4/ntvfs/posix/pvfs_setfileinfo.c | 40 ++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 20 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index a78d0a79c7..43203086f8 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -525,14 +525,14 @@ static int pvfs_handle_destructor(struct pvfs_file_handle *h) } if (h->write_time.update_on_close) { - struct utimbuf unix_times; + struct timeval tv[2]; - unix_times.actime = nt_time_to_unix(h->name->dos.access_time); - unix_times.modtime = nt_time_to_unix(h->write_time.close_time); + nttime_to_timeval(&tv[0], h->name->dos.access_time); + nttime_to_timeval(&tv[1], h->write_time.close_time); - if (unix_times.actime != 0 || unix_times.modtime != 0) { - if (utime(h->name->full_name, &unix_times) == -1) { - DEBUG(0,("pvfs_close: utime() failed '%s' - %s\n", + if (!timeval_is_zero(&tv[0]) || !timeval_is_zero(&tv[1])) { + if (utimes(h->name->full_name, tv) == -1) { + DEBUG(0,("pvfs_handle_destructor: utimes() failed '%s' - %s\n", h->name->full_name, strerror(errno))); } } diff --git a/source4/ntvfs/posix/pvfs_setfileinfo.c b/source4/ntvfs/posix/pvfs_setfileinfo.c index b0f636f999..2cde5f42aa 100644 --- a/source4/ntvfs/posix/pvfs_setfileinfo.c +++ b/source4/ntvfs/posix/pvfs_setfileinfo.c @@ -273,7 +273,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, union smb_setfileinfo *info) { struct pvfs_state *pvfs = ntvfs->private_data; - struct utimbuf unix_times; struct pvfs_file *f; struct pvfs_file_handle *h; struct pvfs_filename newstats; @@ -437,21 +436,28 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs, } /* possibly change the file timestamps */ - ZERO_STRUCT(unix_times); if (newstats.dos.create_time != h->name->dos.create_time) { change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (newstats.dos.access_time != h->name->dos.access_time) { - unix_times.actime = nt_time_to_unix(newstats.dos.access_time); change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS; } if (newstats.dos.write_time != h->name->dos.write_time) { - unix_times.modtime = nt_time_to_unix(newstats.dos.write_time); change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE; } - if (unix_times.actime != 0 || unix_times.modtime != 0) { - if (utime(h->name->full_name, &unix_times) == -1) { - return pvfs_map_errno(pvfs, errno); + if ((change_mask & FILE_NOTIFY_CHANGE_LAST_ACCESS) || + (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE)) { + struct timeval tv[2]; + + nttime_to_timeval(&tv[0], newstats.dos.access_time); + nttime_to_timeval(&tv[1], newstats.dos.write_time); + + if (!timeval_is_zero(&tv[0]) || !timeval_is_zero(&tv[1])) { + if (utimes(h->name->full_name, tv) == -1) { + DEBUG(0,("pvfs_setfileinfo: utimes() failed '%s' - %s\n", + h->name->full_name, strerror(errno))); + return pvfs_map_errno(pvfs, errno); + } } } if (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE) { @@ -594,7 +600,6 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, struct pvfs_filename *name; struct pvfs_filename newstats; NTSTATUS status; - struct utimbuf unix_times; uint32_t access_needed; uint32_t change_mask = 0; struct odb_lock *lck = NULL; @@ -760,21 +765,28 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs, } /* possibly change the file timestamps */ - ZERO_STRUCT(unix_times); if (newstats.dos.create_time != name->dos.create_time) { change_mask |= FILE_NOTIFY_CHANGE_CREATION; } if (newstats.dos.access_time != name->dos.access_time) { - unix_times.actime = nt_time_to_unix(newstats.dos.access_time); change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS; } if (newstats.dos.write_time != name->dos.write_time) { - unix_times.modtime = nt_time_to_unix(newstats.dos.write_time); change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE; } - if (unix_times.actime != 0 || unix_times.modtime != 0) { - if (utime(name->full_name, &unix_times) == -1) { - return pvfs_map_errno(pvfs, errno); + if ((change_mask & FILE_NOTIFY_CHANGE_LAST_ACCESS) || + (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE)) { + struct timeval tv[2]; + + nttime_to_timeval(&tv[0], newstats.dos.access_time); + nttime_to_timeval(&tv[1], newstats.dos.write_time); + + if (!timeval_is_zero(&tv[0]) || !timeval_is_zero(&tv[1])) { + if (utimes(name->full_name, tv) == -1) { + DEBUG(0,("pvfs_setpathinfo: utimes() failed '%s' - %s\n", + name->full_name, strerror(errno))); + return pvfs_map_errno(pvfs, errno); + } } } if (change_mask & FILE_NOTIFY_CHANGE_LAST_WRITE) { -- cgit From c9d2570ce3dbca9b4933cbcfacd0242f41a08000 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 28 Jun 2008 10:27:16 +0200 Subject: pvfs: pvfs_aio should be a subsystem instead of an extra ntvfs module metze (This used to be commit c904e28bef95cb0d61bf86f2ba1cef2d4e018d5f) --- source4/ntvfs/posix/config.mk | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 0ee3e3be16..11fa067068 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -21,8 +21,7 @@ PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix pvfs_acl_nfs4_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_nfs4.o ################################################ -[MODULE::pvfs_aio] -SUBSYSTEM = ntvfs +[SUBSYSTEM::pvfs_aio] PRIVATE_DEPENDENCIES = LIBAIO_LINUX ################################################ -- cgit From 98014c5668e3269a059658e433d636213e2b06e6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 28 Jun 2008 10:28:15 +0200 Subject: pvfs: create a pvfs_acl subsystem That means that the pvfs_acl implementations no longer register as ntvfs modules (which was wrong) metze (This used to be commit 89e90556ec57fce24faf0ed3d6fe262edd974b28) --- source4/ntvfs/ntvfs_base.c | 2 -- source4/ntvfs/posix/config.mk | 20 +++++++++++++------- source4/ntvfs/posix/pvfs_acl.c | 22 ++++++++++++++++++++++ source4/ntvfs/posix/vfs_posix.c | 7 +++++++ source4/ntvfs/posix/vfs_posix.h | 1 + 5 files changed, 43 insertions(+), 9 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_base.c b/source4/ntvfs/ntvfs_base.c index 6de13e4a0a..1385481bbc 100644 --- a/source4/ntvfs/ntvfs_base.c +++ b/source4/ntvfs/ntvfs_base.c @@ -209,8 +209,6 @@ NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx) extern NTSTATUS ntvfs_nbench_init(void); extern NTSTATUS ntvfs_unixuid_init(void); extern NTSTATUS ntvfs_ipc_init(void); - extern NTSTATUS pvfs_acl_nfs4_init(void); - extern NTSTATUS pvfs_acl_xattr_init(void); extern NTSTATUS ntvfs_print_init(void); extern NTSTATUS ntvfs_simple_init(void); extern NTSTATUS ntvfs_cifs_posix_init(void); diff --git a/source4/ntvfs/posix/config.mk b/source4/ntvfs/posix/config.mk index 11fa067068..1ea4e8f97d 100644 --- a/source4/ntvfs/posix/config.mk +++ b/source4/ntvfs/posix/config.mk @@ -1,9 +1,16 @@ + +[SUBSYSTEM::pvfs_acl] + +pvfs_acl_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl.o + +$(eval $(call proto_header_template,$(ntvfssrcdir)/posix/vfs_acl_proto.h,$(pvfs_acl_OBJ_FILES:.o=.c))) + ################################################ # Start MODULE pvfs_acl_xattr [MODULE::pvfs_acl_xattr] INIT_FUNCTION = pvfs_acl_xattr_init -SUBSYSTEM = ntvfs -PRIVATE_DEPENDENCIES = NDR_XATTR ntvfs_posix +SUBSYSTEM = pvfs_acl +PRIVATE_DEPENDENCIES = NDR_XATTR # End MODULE pvfs_acl_xattr ################################################ @@ -13,8 +20,8 @@ pvfs_acl_xattr_OBJ_FILES = $(ntvfssrcdir)/posix/pvfs_acl_xattr.o # Start MODULE pvfs_acl_nfs4 [MODULE::pvfs_acl_nfs4] INIT_FUNCTION = pvfs_acl_nfs4_init -SUBSYSTEM = ntvfs -PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB ntvfs_posix +SUBSYSTEM = pvfs_acl +PRIVATE_DEPENDENCIES = NDR_NFS4ACL SAMDB # End MODULE pvfs_acl_nfs4 ################################################ @@ -34,8 +41,8 @@ SUBSYSTEM = ntvfs OUTPUT_TYPE = MERGED_OBJ INIT_FUNCTION = ntvfs_posix_init #PRIVATE_DEPENDENCIES = pvfs_acl_xattr pvfs_acl_nfs4 -PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING pvfs_aio \ - LIBWBCLIENT +PRIVATE_DEPENDENCIES = NDR_XATTR WRAP_XATTR BLKID ntvfs_common MESSAGING \ + LIBWBCLIENT pvfs_acl pvfs_aio # End MODULE ntvfs_posix ################################################ @@ -64,7 +71,6 @@ ntvfs_posix_OBJ_FILES = $(addprefix $(ntvfssrcdir)/posix/, \ pvfs_ioctl.o \ pvfs_xattr.o \ pvfs_streams.o \ - pvfs_acl.o \ pvfs_notify.o \ xattr_system.o \ xattr_tdb.o) diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 9a9200e4f0..57a463aba6 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -24,6 +24,7 @@ #include "vfs_posix.h" #include "librpc/gen_ndr/xattr.h" #include "libcli/security/security.h" +#include "param/param.h" /* the list of currently registered ACL backends */ @@ -79,6 +80,27 @@ const struct pvfs_acl_ops *pvfs_acl_backend_byname(const char *name) return NULL; } +NTSTATUS pvfs_acl_init(struct loadparm_context *lp_ctx) +{ + static bool initialized = false; + extern NTSTATUS pvfs_acl_nfs4_init(void); + extern NTSTATUS pvfs_acl_xattr_init(void); + init_module_fn static_init[] = { STATIC_pvfs_acl_MODULES }; + init_module_fn *shared_init; + + if (initialized) return NT_STATUS_OK; + initialized = true; + + shared_init = load_samba_modules(NULL, lp_ctx, "pvfs_acl"); + + run_init_functions(static_init); + run_init_functions(shared_init); + + talloc_free(shared_init); + + return NT_STATUS_OK; +} + /* map a single access_mask from generic to specific bits for files/dirs diff --git a/source4/ntvfs/posix/vfs_posix.c b/source4/ntvfs/posix/vfs_posix.c index b5dd270346..ce0da7033d 100644 --- a/source4/ntvfs/posix/vfs_posix.c +++ b/source4/ntvfs/posix/vfs_posix.c @@ -176,6 +176,13 @@ static NTSTATUS pvfs_connect(struct ntvfs_module_context *ntvfs, char *base_directory; NTSTATUS status; + /* + * TODO: call this from ntvfs_posix_init() + * but currently we don't have a lp_ctx there + */ + status = pvfs_acl_init(ntvfs->ctx->lp_ctx); + NT_STATUS_NOT_OK_RETURN(status); + pvfs = talloc_zero(ntvfs, struct pvfs_state); NT_STATUS_HAVE_NO_MEMORY(pvfs); diff --git a/source4/ntvfs/posix/vfs_posix.h b/source4/ntvfs/posix/vfs_posix.h index cf39bcf0ac..1a54b57d63 100644 --- a/source4/ntvfs/posix/vfs_posix.h +++ b/source4/ntvfs/posix/vfs_posix.h @@ -283,6 +283,7 @@ struct pvfs_acl_ops { }; #include "ntvfs/posix/vfs_posix_proto.h" +#include "ntvfs/posix/vfs_acl_proto.h" NTSTATUS pvfs_aio_pread(struct ntvfs_request *req, union smb_read *rd, struct pvfs_file *f, uint32_t maxcnt); -- cgit From e92125e6319d49185a3d0456a8a0e5c1b8d364e7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jul 2008 14:00:18 +1000 Subject: Ignore and handle more NT Create & X options. The MS-SMB document explains that some of these options should be ignored. The test proves it. /* Must be ignored by the server, per MS-SMB 2.2.8 */ /* Must be ignored by the server, per MS-SMB 2.2.8 */ If we implement HSM in samba4 (likely) we should honour this bit. /* Don't pull this file off tape in a HSM system */ Andrew Bartlett (This used to be commit 502739ff90d56d2c9aabe8e224317f6ceb175c17) --- source4/ntvfs/posix/pvfs_open.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 43203086f8..5302fc3f50 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1206,11 +1206,22 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - /* some create options are not supported */ if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { return NT_STATUS_NOT_SUPPORTED; } + /* TODO: When we implement HSM, add a hook here not to pull + * the actual file off tape, when this option is passed from + * the client */ + if (create_options & NTCREATEX_OPTIONS_NO_RECALL) { + /* no-op */ + } + + /* These options are ignored */ + if (create_options & (NTCREATEX_OPTIONS_FREE_SPACE_QUERY | NTCREATEX_OPTIONS_OPFILTER)) { + /* no-op */ + } + /* other create options are not allowed */ if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && !(access_mask & SEC_STD_DELETE)) { -- cgit From 853194c308a0f2171808b78b17aed50c5fab1b3b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jul 2008 18:40:19 +1000 Subject: More 'must be ignored' options from the MS-SMB doc. Also in particular the 'sync' flags (which Samba has traditionally ignored). Thanks to Olivier Salamin for pointing out more flags that needed to be handled. Andrew Bartlett (This used to be commit 370bb39cd79fe49efd36a1ceb3e896d386e6d3ce) --- source4/ntvfs/posix/pvfs_open.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 5302fc3f50..01a249ceb7 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1173,7 +1173,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_open *io) { struct pvfs_state *pvfs = ntvfs->private_data; - int flags; + int flags = 0; struct pvfs_filename *name; struct pvfs_file *f; struct ntvfs_handle *h; @@ -1206,6 +1206,9 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } + /* These options are ignored */ + create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK; + if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { return NT_STATUS_NOT_SUPPORTED; } @@ -1217,11 +1220,23 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, /* no-op */ } - /* These options are ignored */ - if (create_options & (NTCREATEX_OPTIONS_FREE_SPACE_QUERY | NTCREATEX_OPTIONS_OPFILTER)) { + /* TODO: If (unlikely) Linux does a good compressed + * filesystem, we might need an ioctl call for this */ + if (create_options & NTCREATEX_OPTIONS_NO_COMPRESSION) { /* no-op */ } + if (create_options & NTCREATEX_OPTIONS_NO_INTERMEDIATE_BUFFERING) { + create_options |= NTCREATEX_OPTIONS_WRITE_THROUGH; + } + + /* Open the file with sync, if they asked for it, but + 'strict sync = no' turns this client request into a no-op */ + if (create_options & (NTCREATEX_OPTIONS_WRITE_THROUGH) && !(pvfs->flags | PVFS_FLAG_STRICT_SYNC)) { + flags |= O_SYNC; + } + + /* other create options are not allowed */ if ((create_options & NTCREATEX_OPTIONS_DELETE_ON_CLOSE) && !(access_mask & SEC_STD_DELETE)) { @@ -1282,8 +1297,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, open doesn't match */ io->generic.in.file_attr &= ~FILE_ATTRIBUTE_DIRECTORY; - flags = 0; - switch (io->generic.in.open_disposition) { case NTCREATEX_DISP_SUPERSEDE: case NTCREATEX_DISP_OVERWRITE_IF: -- cgit From 1d12c640666c574b537d254a07af404e61445f6b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 24 Jul 2008 14:19:49 +1000 Subject: fixed spelling error (This used to be commit 341f64834e13cdbc7d4742a4652ae39b70a4231f) --- source4/ntvfs/posix/xattr_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/xattr_system.c b/source4/ntvfs/posix/xattr_system.c index 7283d716b4..9a89f2a338 100644 --- a/source4/ntvfs/posix/xattr_system.c +++ b/source4/ntvfs/posix/xattr_system.c @@ -74,7 +74,7 @@ again: return NT_STATUS_NOT_FOUND; } else { - /* if not this was probably a legittimate error + /* if not this was probably a legitimate error * reset ret and errno to the correct values */ errno = EPERM; ret = -1; -- cgit From 2ecda9fde4aa00aecd6df6ebeb162d173853d146 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 24 Jul 2008 14:21:52 +1000 Subject: we can't query the ACL on a new file till it exists! (This used to be commit 4f6646f06988b1fb8be9e0c8ae833bb9792184af) --- source4/ntvfs/posix/pvfs_open.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 01a249ceb7..6114b2052c 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -631,12 +631,6 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, status = pvfs_access_check_create(pvfs, req, name, &access_mask); NT_STATUS_NOT_OK_RETURN(status); - if (io->generic.in.query_maximal_access) { - status = pvfs_access_maximal_allowed(pvfs, req, name, - &io->generic.out.maximal_access); - NT_STATUS_NOT_OK_RETURN(status); - } - /* check that the parent isn't opened with delete on close set */ status = pvfs_resolve_parent(pvfs, req, name, &parent); if (NT_STATUS_IS_OK(status)) { @@ -707,6 +701,12 @@ static NTSTATUS pvfs_create_file(struct pvfs_state *pvfs, goto cleanup_delete; } + if (io->generic.in.query_maximal_access) { + status = pvfs_access_maximal_allowed(pvfs, req, name, + &io->generic.out.maximal_access); + NT_STATUS_NOT_OK_RETURN(status); + } + /* form the lock context used for byte range locking and opendb locking */ status = pvfs_locking_key(name, f->handle, &f->handle->odb_locking_key); -- cgit From cc60d5a0320f824f7dc7b8abbe9cb0ccd668dda2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 14 Aug 2008 12:37:31 +0200 Subject: pvfs: fix handling of create_option flags metze (This used to be commit 3c6cadf76861d6522c5ec41953df1ba2fac4910d) --- source4/ntvfs/posix/pvfs_open.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c index 6114b2052c..c127885a68 100644 --- a/source4/ntvfs/posix/pvfs_open.c +++ b/source4/ntvfs/posix/pvfs_open.c @@ -1181,6 +1181,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, int fd; struct odb_lock *lck; uint32_t create_options; + uint32_t create_options_must_ignore_mask; uint32_t share_access; uint32_t access_mask; uint32_t create_action = NTCREATEX_ACTION_EXISTED; @@ -1206,13 +1207,22 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs, return NT_STATUS_INVALID_PARAMETER; } - /* These options are ignored */ - create_options &= ~NTCREATEX_OPTIONS_MUST_IGNORE_MASK; + /* + * These options are ignored, + * but we reuse some of them as private values for the generic mapping + */ + create_options_must_ignore_mask = NTCREATEX_OPTIONS_MUST_IGNORE_MASK; + create_options_must_ignore_mask &= ~NTCREATEX_OPTIONS_PRIVATE_MASK; + create_options &= ~create_options_must_ignore_mask; if (create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { return NT_STATUS_NOT_SUPPORTED; } + if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) { + return NT_STATUS_INVALID_PARAMETER; + } + /* TODO: When we implement HSM, add a hook here not to pull * the actual file off tape, when this option is passed from * the client */ -- cgit From 548ed8d9586bbf9504bec5064a14893f5827b0e4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 14 Aug 2008 09:52:45 +0200 Subject: ntvfs_generic: fix handling of create_options for SMB2 metze (This used to be commit cbd585d2a1e179615eba773cb07385524369c686) --- source4/ntvfs/ntvfs_generic.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'source4/ntvfs') diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c index 4f3a7e2198..c34bb7125e 100644 --- a/source4/ntvfs/ntvfs_generic.c +++ b/source4/ntvfs/ntvfs_generic.c @@ -532,16 +532,14 @@ NTSTATUS ntvfs_map_open(struct ntvfs_module_context *ntvfs, } /* we need to check these bits before we check the private mask */ - if (io2->generic.in.create_options & NTCREATEX_OPTIONS_NOT_SUPPORTED_MASK) { + if (io2->generic.in.create_options & SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK) { status = NT_STATUS_NOT_SUPPORTED; break; } - /* we use a couple of bits of the create options internally */ - if (io2->generic.in.create_options & NTCREATEX_OPTIONS_PRIVATE_MASK) { - status = NT_STATUS_INVALID_PARAMETER; - break; - } + /* TODO: find out why only SMB2 ignores these */ + io2->generic.in.create_options &= ~NTCREATEX_OPTIONS_SYNC_ALERT; + io2->generic.in.create_options &= ~NTCREATEX_OPTIONS_ASYNC_ALERT; status = ntvfs->ops->open(ntvfs, req, io2); break; -- cgit