diff options
author | Stefan Metzmacher <metze@samba.org> | 2006-05-20 12:25:45 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:08:12 -0500 |
commit | 7442613a53f5a226429a76e2f7bad6db5032418e (patch) | |
tree | 13d56a1ff1b1e087414e7278a7ef282c42da24f2 /source4 | |
parent | 7930ae6a70dd80e93d593383eca028722ab90251 (diff) | |
download | samba-7442613a53f5a226429a76e2f7bad6db5032418e.tar.gz samba-7442613a53f5a226429a76e2f7bad6db5032418e.tar.bz2 samba-7442613a53f5a226429a76e2f7bad6db5032418e.zip |
r15748: - implement SMB2 TreeConnect server code
TODO: pass in oplock and handle callbacks, but as we don't do file access
yet, it's no problem to skip them
metze
(This used to be commit 4ae4a742fc2e40b2937d9ce01f2e45f43f7ff1c3)
Diffstat (limited to 'source4')
-rw-r--r-- | source4/smb_server/smb2/tcon.c | 110 |
1 files changed, 105 insertions, 5 deletions
diff --git a/source4/smb_server/smb2/tcon.c b/source4/smb_server/smb2/tcon.c index 50c62109d9..85ebc33f5d 100644 --- a/source4/smb_server/smb2/tcon.c +++ b/source4/smb_server/smb2/tcon.c @@ -25,25 +25,125 @@ #include "smb_server/service_smb_proto.h" #include "smb_server/smb2/smb2_server.h" #include "librpc/gen_ndr/security.h" +#include "smbd/service_stream.h" +#include "ntvfs/ntvfs.h" static NTSTATUS smb2srv_tcon_backend(struct smb2srv_request *req, union smb_tcon *io) { struct smbsrv_tcon *tcon; + NTSTATUS status; + enum ntvfs_type type; + uint16_t type_smb2; + int snum; + const char *service = io->smb2.in.path; + + if (strncmp(service, "\\\\", 2) == 0) { + const char *p = strchr(service+2, '\\'); + if (p) { + service = p + 1; + } + } + + snum = smbsrv_find_service(service); + if (snum == -1) { + DEBUG(0,("smb2srv_tcon_backend: couldn't find service %s\n", service)); + return NT_STATUS_BAD_NETWORK_NAME; + } + + if (!socket_check_access(req->smb_conn->connection->socket, + lp_servicename(snum), + lp_hostsallow(snum), + lp_hostsdeny(snum))) { + return NT_STATUS_ACCESS_DENIED; + } + + /* work out what sort of connection this is */ + if (strcmp(lp_fstype(snum), "IPC") == 0) { + type = NTVFS_IPC; + type_smb2 = 0x0003; + } else if (lp_print_ok(snum)) { + type = NTVFS_PRINT; + type_smb2 = 0x0002; + } else { + type = NTVFS_DISK; + type_smb2 = 0x0001; + } + + tcon = smbsrv_smb2_tcon_new(req->session, lp_servicename(snum)); + if (!tcon) { + DEBUG(0,("smb2srv_tcon_backend: Couldn't find free connection.\n")); + return NT_STATUS_INSUFFICIENT_RESOURCES; + } + req->tcon = tcon; + + /* init ntvfs function pointers */ + status = ntvfs_init_connection(tcon, snum, type, + req->smb_conn->negotiate.protocol, + req->smb_conn->connection->event.ctx, + req->smb_conn->connection->msg_ctx, + req->smb_conn->connection->server_id, + &tcon->ntvfs); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("smb2srv_tcon_backend: ntvfs_init_connection failed for service %s\n", + lp_servicename(snum))); + goto failed; + } - tcon = smbsrv_smb2_tcon_new(req->session, "fake"); - NT_STATUS_HAVE_NO_MEMORY(tcon); +/* status = ntvfs_set_oplock_handler(tcon->ntvfs, smb2srv_send_oplock_break, tcon); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("smb2srv_tcon_backend: NTVFS failed to set the oplock handler!\n")); + goto failed; + } +*/ + status = ntvfs_set_addr_callbacks(tcon->ntvfs, smbsrv_get_my_addr, smbsrv_get_peer_addr, req->smb_conn); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("smb2srv_tcon_backend: NTVFS failed to set the addr callbacks!\n")); + goto failed; + } - /* TODO: do real tree connect */ +/* status = ntvfs_set_handle_callbacks(tcon->ntvfs, + smb2srv_handle_create_new, + smb2srv_handle_make_valid, + smb2srv_handle_destroy, + smb2srv_handle_search_by_wire_key, + smb2srv_handle_get_wire_key, + tcon); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("smb2srv_tcon_backend: NTVFS failed to set the handle callbacks!\n")); + goto failed; + } +*/ + req->ntvfs = ntvfs_request_create(req->tcon->ntvfs, req, + req->session->session_info, + 0, /* TODO: fill in PID */ + 0, /* TODO: fill in MID */ + req->request_time, + req, NULL, 0); + if (!req->ntvfs) { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + + /* Invoke NTVFS connection hook */ + status = ntvfs_connect(req->ntvfs, lp_servicename(snum)); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("smb2srv_tcon_backend: NTVFS ntvfs_connect() failed!\n")); + goto failed; + } - io->smb2.out.unknown1 = 0x0001; /* 1 - DISK, 2 - Print, 3 - IPC */ + io->smb2.out.unknown1 = type_smb2; /* 1 - DISK, 2 - Print, 3 - IPC */ io->smb2.out.unknown2 = 0x00000000; io->smb2.out.unknown3 = 0x00000000; io->smb2.out.access_mask= SEC_RIGHTS_FILE_ALL; io->smb2.out.tid = tcon->tid; - req->tcon = tcon; return NT_STATUS_OK; + +failed: + req->tcon = NULL; + talloc_free(tcon); + return status; } static void smb2srv_tcon_send(struct smb2srv_request *req, union smb_tcon *io) |