From 2e415d4e98530f4b95114a2d49850702ee214a6f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 21 May 2006 12:15:04 +0000 Subject: r15773: - implement srvsvc_NetGetFileSecurity() and srvsvc_NetSetFileSecurity() - we do this by just creating a ntvfs_context (this doesn't need and smbsrv_* stuff :-) and then call ntvfs_qpathinfo() and ntvfs_setpathinfo() metze (This used to be commit e1635ce5c07615eded6eac237cde3945a46ebbd9) --- source4/rpc_server/config.mk | 4 +- source4/rpc_server/srvsvc/dcesrv_srvsvc.c | 68 +++++++++++++++- source4/rpc_server/srvsvc/srvsvc_ntvfs.c | 131 ++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+), 4 deletions(-) create mode 100644 source4/rpc_server/srvsvc/srvsvc_ntvfs.c (limited to 'source4') diff --git a/source4/rpc_server/config.mk b/source4/rpc_server/config.mk index 17e5ca8d81..473b0a3df7 100644 --- a/source4/rpc_server/config.mk +++ b/source4/rpc_server/config.mk @@ -68,9 +68,11 @@ PUBLIC_DEPENDENCIES = \ # Start MODULE dcerpc_srvsvc [MODULE::dcerpc_srvsvc] INIT_FUNCTION = dcerpc_server_srvsvc_init +PRIVATE_PROTO_HEADER = srvsvc/proto.h SUBSYSTEM = dcerpc_server OBJ_FILES = \ - srvsvc/dcesrv_srvsvc.o + srvsvc/dcesrv_srvsvc.o \ + srvsvc/srvsvc_ntvfs.o PUBLIC_DEPENDENCIES = \ DCERPC_COMMON NDR_SRVSVC # End MODULE dcerpc_srvsvc diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c index 911f997fc0..c1854a6b20 100644 --- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c +++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c @@ -3,7 +3,7 @@ endpoint server for the srvsvc pipe - Copyright (C) Stefan (metze) Metzmacher 2004 + Copyright (C) Stefan (metze) Metzmacher 2004-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 @@ -27,6 +27,8 @@ #include "auth/auth.h" #include "libcli/security/security.h" #include "system/time.h" +#include "ntvfs/ntvfs.h" +#include "rpc_server/srvsvc/proto.h" #define SRVSVC_CHECK_ADMIN_ACCESS do { \ struct security_token *t = dce_call->conn->auth_state.session_info->security_token; \ @@ -1403,7 +1405,40 @@ static WERROR srvsvc_NetShareDelCommit(struct dcesrv_call_state *dce_call, TALLO static WERROR srvsvc_NetGetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetGetFileSecurity *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct sec_desc_buf *sd_buf; + struct ntvfs_context *ntvfs_ctx = NULL; + struct ntvfs_request *ntvfs_req; + union smb_fileinfo *io; + NTSTATUS nt_status; + + nt_status = srvsvc_create_ntvfs_context(dce_call, mem_ctx, r->in.share, &ntvfs_ctx); + if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); + + ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx, + dce_call->conn->auth_state.session_info, + 0, + 0, + dce_call->time, + NULL, NULL, 0); + W_ERROR_HAVE_NO_MEMORY(ntvfs_req); + + sd_buf = talloc(mem_ctx, struct sec_desc_buf); + W_ERROR_HAVE_NO_MEMORY(sd_buf); + + io = talloc(mem_ctx, union smb_fileinfo); + W_ERROR_HAVE_NO_MEMORY(io); + + io->query_secdesc.level = RAW_FILEINFO_SEC_DESC; + io->query_secdesc.in.file.path = r->in.file; + io->query_secdesc.in.secinfo_flags = r->in.securityinformation; + + nt_status = ntvfs_qpathinfo(ntvfs_req, io); + if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); + + sd_buf->sd = io->query_secdesc.out.sd; + + r->out.sd_buf = sd_buf; + return WERR_OK; } @@ -1413,7 +1448,34 @@ static WERROR srvsvc_NetGetFileSecurity(struct dcesrv_call_state *dce_call, TALL static WERROR srvsvc_NetSetFileSecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct srvsvc_NetSetFileSecurity *r) { - DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); + struct ntvfs_context *ntvfs_ctx; + struct ntvfs_request *ntvfs_req; + union smb_setfileinfo *io; + NTSTATUS nt_status; + + nt_status = srvsvc_create_ntvfs_context(dce_call, mem_ctx, r->in.share, &ntvfs_ctx); + if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); + + ntvfs_req = ntvfs_request_create(ntvfs_ctx, mem_ctx, + dce_call->conn->auth_state.session_info, + 0, + 0, + dce_call->time, + NULL, NULL, 0); + W_ERROR_HAVE_NO_MEMORY(ntvfs_req); + + io = talloc(mem_ctx, union smb_setfileinfo); + W_ERROR_HAVE_NO_MEMORY(io); + + io->set_secdesc.level = RAW_FILEINFO_SEC_DESC; + io->set_secdesc.in.file.path = r->in.file; + io->set_secdesc.in.secinfo_flags = r->in.securityinformation; + io->set_secdesc.in.sd = r->in.sd_buf.sd; + + nt_status = ntvfs_setpathinfo(ntvfs_req, io); + if (!NT_STATUS_IS_OK(nt_status)) return ntstatus_to_werror(nt_status); + + return WERR_OK; } 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; +} -- cgit