diff options
Diffstat (limited to 'source4/rpc_server/srvsvc/srvsvc_ntvfs.c')
-rw-r--r-- | source4/rpc_server/srvsvc/srvsvc_ntvfs.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/source4/rpc_server/srvsvc/srvsvc_ntvfs.c b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c new file mode 100644 index 0000000000..7dbaaa0f23 --- /dev/null +++ b/source4/rpc_server/srvsvc/srvsvc_ntvfs.c @@ -0,0 +1,131 @@ +/* + Unix SMB/CIFS implementation. + + srvsvc pipe ntvfs helper functions + + Copyright (C) Stefan (metze) 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. +*/ +#include "includes.h" +#include "rpc_server/dcerpc_server.h" +#include "librpc/gen_ndr/ndr_srvsvc.h" +#include "rpc_server/common/common.h" +#include "ntvfs/ntvfs.h" +#include "rpc_server/srvsvc/proto.h" +#include "lib/socket/socket.h" + +struct socket_address *srvsvc_get_my_addr(void *p, TALLOC_CTX *mem_ctx) +{ + struct dcesrv_connection *conn = talloc_get_type(p, struct dcesrv_connection); + return dcesrv_connection_get_my_addr(conn, mem_ctx); +} + +struct socket_address *srvsvc_get_peer_addr(void *p, TALLOC_CTX *mem_ctx) +{ + struct dcesrv_connection *conn = talloc_get_type(p, struct dcesrv_connection); + return dcesrv_connection_get_peer_addr(conn, mem_ctx); +} + +struct srvsvc_ntvfs_ctx { + struct ntvfs_context *ntvfs; +}; + +static int srvsvc_ntvfs_ctx_destructor(void *p) +{ + struct srvsvc_ntvfs_ctx *c = talloc_get_type(p, struct srvsvc_ntvfs_ctx); + ntvfs_disconnect(c->ntvfs); + return 0; +} + +NTSTATUS srvsvc_create_ntvfs_context(struct dcesrv_call_state *dce_call, + TALLOC_CTX *mem_ctx, + const char *share, + struct ntvfs_context **_ntvfs) +{ + NTSTATUS status; + struct srvsvc_ntvfs_ctx *c; + struct ntvfs_request *ntvfs_req; + enum ntvfs_type type; + int snum; + + snum = lp_find_valid_service(share); + if (snum == -1) { + DEBUG(0,("srvsvc_create_ntvfs_context: couldn't find service %s\n", share)); + return NT_STATUS_BAD_NETWORK_NAME; + } + +#if 0 /* TODO: fix access cecking */ + if (!socket_check_access(dce_call->connection->socket, + lp_servicename(snum), + lp_hostsallow(snum), + lp_hostsdeny(snum))) { + return NT_STATUS_ACCESS_DENIED; + } +#endif + + /* work out what sort of connection this is */ + if (strcmp(lp_fstype(snum), "IPC") == 0) { + type = NTVFS_IPC; + } else if (lp_print_ok(snum)) { + type = NTVFS_PRINT; + } else { + type = NTVFS_DISK; + } + + c = talloc(mem_ctx, struct srvsvc_ntvfs_ctx); + NT_STATUS_HAVE_NO_MEMORY(c); + + /* init ntvfs function pointers */ + status = ntvfs_init_connection(c, snum, type, + PROTOCOL_NT1, + dce_call->event_ctx, + dce_call->conn->msg_ctx, + dce_call->conn->server_id, + &c->ntvfs); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("srvsvc_create_ntvfs_context: ntvfs_init_connection failed for service %s\n", + lp_servicename(snum))); + return status; + } + talloc_set_destructor(c, srvsvc_ntvfs_ctx_destructor); + + /* + * NOTE: we only set the addr callbacks as we're not interesseted in oplocks or in getting file handles + */ + status = ntvfs_set_addr_callbacks(c->ntvfs, srvsvc_get_my_addr, srvsvc_get_peer_addr, dce_call->conn); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("srvsvc_create_ntvfs_context: NTVFS failed to set the addr callbacks!\n")); + return status; + } + + ntvfs_req = ntvfs_request_create(c->ntvfs, mem_ctx, + dce_call->conn->auth_state.session_info, + 0, /* TODO: fill in PID */ + 0, /* TODO: fill in MID */ + dce_call->time, + NULL, NULL, 0); + NT_STATUS_HAVE_NO_MEMORY(ntvfs_req); + + /* Invoke NTVFS connection hook */ + status = ntvfs_connect(ntvfs_req, lp_servicename(snum)); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("srvsvc_create_ntvfs_context: NTVFS ntvfs_connect() failed!\n")); + return status; + } + + *_ntvfs = c->ntvfs; + return NT_STATUS_OK; +} |