mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
r11603: converted the smb server to use the new generic packet code
(This used to be commit 0fc496bb6f520ddf6d85cc2f3df80f93b871cfe9)
This commit is contained in:
parent
a3fcb93df1
commit
7e963eb6e7
source4/smb_server
@ -20,6 +20,6 @@ ADD_OBJ_FILES = \
|
|||||||
signing.o \
|
signing.o \
|
||||||
management.o
|
management.o
|
||||||
REQUIRED_SUBSYSTEMS = \
|
REQUIRED_SUBSYSTEMS = \
|
||||||
NTVFS
|
NTVFS LIBPACKET
|
||||||
# End SUBSYSTEM SMB
|
# End SUBSYSTEM SMB
|
||||||
#######################
|
#######################
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "smbd/service_stream.h"
|
#include "smbd/service_stream.h"
|
||||||
#include "smb_server/smb_server.h"
|
#include "smb_server/smb_server.h"
|
||||||
#include "lib/messaging/irpc.h"
|
#include "lib/messaging/irpc.h"
|
||||||
|
#include "lib/stream/packet.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -68,85 +69,18 @@ static void construct_reply(struct smbsrv_request *req);
|
|||||||
receive a SMB request header from the wire, forming a request_context
|
receive a SMB request header from the wire, forming a request_context
|
||||||
from the result
|
from the result
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static NTSTATUS receive_smb_request(struct smbsrv_connection *smb_conn)
|
static NTSTATUS receive_smb_request(void *private, DATA_BLOB blob)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
struct smbsrv_connection *smb_conn = talloc_get_type(private, struct smbsrv_connection);
|
||||||
ssize_t len;
|
|
||||||
struct smbsrv_request *req;
|
struct smbsrv_request *req;
|
||||||
size_t nread;
|
|
||||||
|
|
||||||
/* allocate the request if needed */
|
req = init_smb_request(smb_conn);
|
||||||
if (smb_conn->partial_req == NULL) {
|
if (req == NULL) {
|
||||||
req = init_smb_request(smb_conn);
|
return NT_STATUS_NO_MEMORY;
|
||||||
if (req == NULL) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->in.buffer = talloc_array(req, uint8_t, NBT_HDR_SIZE);
|
|
||||||
if (req->in.buffer == NULL) {
|
|
||||||
talloc_free(req);
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
req->in.size = 0;
|
|
||||||
smb_conn->partial_req = req;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
req = smb_conn->partial_req;
|
req->in.buffer = talloc_steal(req, blob.data);
|
||||||
|
req->in.size = blob.length;
|
||||||
/* read in the header */
|
|
||||||
if (req->in.size < NBT_HDR_SIZE) {
|
|
||||||
status = socket_recv(smb_conn->connection->socket,
|
|
||||||
req->in.buffer + req->in.size,
|
|
||||||
NBT_HDR_SIZE - req->in.size,
|
|
||||||
&nread, 0);
|
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
if (nread == 0) {
|
|
||||||
return NT_STATUS_END_OF_FILE;
|
|
||||||
}
|
|
||||||
req->in.size += nread;
|
|
||||||
|
|
||||||
/* when we have a full NBT header, then allocate the packet */
|
|
||||||
if (req->in.size == NBT_HDR_SIZE) {
|
|
||||||
len = smb_len(req->in.buffer) + NBT_HDR_SIZE;
|
|
||||||
req->in.buffer = talloc_realloc(req, req->in.buffer,
|
|
||||||
uint8_t, len);
|
|
||||||
if (req->in.buffer == NULL) {
|
|
||||||
return NT_STATUS_NO_MEMORY;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read in the main packet */
|
|
||||||
len = smb_len(req->in.buffer) + NBT_HDR_SIZE;
|
|
||||||
|
|
||||||
status = socket_recv(smb_conn->connection->socket,
|
|
||||||
req->in.buffer + req->in.size,
|
|
||||||
len - req->in.size,
|
|
||||||
&nread, 0);
|
|
||||||
if (NT_STATUS_IS_ERR(status)) {
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
if (nread == 0) {
|
|
||||||
return NT_STATUS_END_OF_FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
req->in.size += nread;
|
|
||||||
|
|
||||||
if (req->in.size != len) {
|
|
||||||
return NT_STATUS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we have a full packet */
|
|
||||||
req->request_time = timeval_current();
|
req->request_time = timeval_current();
|
||||||
req->chained_fnum = -1;
|
req->chained_fnum = -1;
|
||||||
req->in.allocated = req->in.size;
|
req->in.allocated = req->in.size;
|
||||||
@ -171,8 +105,6 @@ static NTSTATUS receive_smb_request(struct smbsrv_connection *smb_conn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
smb_conn->partial_req = NULL;
|
|
||||||
|
|
||||||
construct_reply(req);
|
construct_reply(req);
|
||||||
|
|
||||||
return NT_STATUS_OK;
|
return NT_STATUS_OK;
|
||||||
@ -659,7 +591,7 @@ error:
|
|||||||
*/
|
*/
|
||||||
void smbsrv_terminate_connection(struct smbsrv_connection *smb_conn, const char *reason)
|
void smbsrv_terminate_connection(struct smbsrv_connection *smb_conn, const char *reason)
|
||||||
{
|
{
|
||||||
smb_conn->terminate = True;
|
smb_conn->terminate = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -668,31 +600,17 @@ void smbsrv_terminate_connection(struct smbsrv_connection *smb_conn, const char
|
|||||||
static void smbsrv_recv(struct stream_connection *conn, uint16_t flags)
|
static void smbsrv_recv(struct stream_connection *conn, uint16_t flags)
|
||||||
{
|
{
|
||||||
struct smbsrv_connection *smb_conn = talloc_get_type(conn->private, struct smbsrv_connection);
|
struct smbsrv_connection *smb_conn = talloc_get_type(conn->private, struct smbsrv_connection);
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
DEBUG(10,("smbsrv_recv\n"));
|
DEBUG(10,("smbsrv_recv\n"));
|
||||||
|
|
||||||
/* our backends are designed to process one request at a time,
|
packet_recv(smb_conn->packet);
|
||||||
unless they deliberately mark the request as async and
|
if (smb_conn->terminate) {
|
||||||
process it later on a timer or other event. This enforces
|
|
||||||
that ordering. */
|
|
||||||
if (smb_conn->processing) {
|
|
||||||
EVENT_FD_NOT_READABLE(conn->event.fde);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
smb_conn->processing = True;
|
|
||||||
status = receive_smb_request(smb_conn);
|
|
||||||
smb_conn->processing = False;
|
|
||||||
if (NT_STATUS_IS_ERR(status) || smb_conn->terminate) {
|
|
||||||
talloc_free(conn->event.fde);
|
talloc_free(conn->event.fde);
|
||||||
conn->event.fde = NULL;
|
conn->event.fde = NULL;
|
||||||
stream_terminate_connection(smb_conn->connection, nt_errstr(status));
|
stream_terminate_connection(smb_conn->connection, smb_conn->terminate);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
EVENT_FD_READABLE(conn->event.fde);
|
|
||||||
|
|
||||||
/* free up temporary memory */
|
/* free up temporary memory */
|
||||||
lp_talloc_free();
|
lp_talloc_free();
|
||||||
}
|
}
|
||||||
@ -734,7 +652,7 @@ static void smbsrv_send(struct stream_connection *conn, uint16_t flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (smb_conn->terminate) {
|
if (smb_conn->terminate) {
|
||||||
stream_terminate_connection(smb_conn->connection, "send termination");
|
stream_terminate_connection(smb_conn->connection, smb_conn->terminate);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -745,6 +663,17 @@ static void smbsrv_send(struct stream_connection *conn, uint16_t flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
handle socket recv errors
|
||||||
|
*/
|
||||||
|
static void smbsrv_recv_error(void *private, NTSTATUS status)
|
||||||
|
{
|
||||||
|
struct smbsrv_connection *smb_conn = talloc_get_type(private, struct smbsrv_connection);
|
||||||
|
|
||||||
|
smbsrv_terminate_connection(smb_conn, nt_errstr(status));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
initialise a server_context from a open socket and register a event handler
|
initialise a server_context from a open socket and register a event handler
|
||||||
for reading from that socket
|
for reading from that socket
|
||||||
@ -770,6 +699,15 @@ static void smbsrv_accept(struct stream_connection *conn)
|
|||||||
smb_conn->negotiate.called_name = NULL;
|
smb_conn->negotiate.called_name = NULL;
|
||||||
smb_conn->negotiate.calling_name = NULL;
|
smb_conn->negotiate.calling_name = NULL;
|
||||||
|
|
||||||
|
smb_conn->packet = packet_init(smb_conn);
|
||||||
|
packet_set_private(smb_conn->packet, smb_conn);
|
||||||
|
packet_set_socket(smb_conn->packet, conn->socket);
|
||||||
|
packet_set_callback(smb_conn->packet, receive_smb_request);
|
||||||
|
packet_set_full_request(smb_conn->packet, packet_full_request_nbt);
|
||||||
|
packet_set_error_handler(smb_conn->packet, smbsrv_recv_error);
|
||||||
|
packet_set_event_context(smb_conn->packet, conn->event.ctx);
|
||||||
|
packet_set_serialise(smb_conn->packet, conn->event.fde);
|
||||||
|
|
||||||
smbsrv_vuid_init(smb_conn);
|
smbsrv_vuid_init(smb_conn);
|
||||||
|
|
||||||
srv_init_signing(smb_conn);
|
srv_init_signing(smb_conn);
|
||||||
@ -777,7 +715,6 @@ static void smbsrv_accept(struct stream_connection *conn)
|
|||||||
smbsrv_tcon_init(smb_conn);
|
smbsrv_tcon_init(smb_conn);
|
||||||
|
|
||||||
smb_conn->connection = conn;
|
smb_conn->connection = conn;
|
||||||
smb_conn->processing = False;
|
|
||||||
smb_conn->config.security = lp_security();
|
smb_conn->config.security = lp_security();
|
||||||
smb_conn->config.nt_status_support = lp_nt_status_support();
|
smb_conn->config.nt_status_support = lp_nt_status_support();
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ struct smbsrv_connection {
|
|||||||
struct stream_connection *connection;
|
struct stream_connection *connection;
|
||||||
|
|
||||||
/* this holds a partially received request */
|
/* this holds a partially received request */
|
||||||
struct smbsrv_request *partial_req;
|
struct packet_context *packet;
|
||||||
|
|
||||||
/* this holds list of replies that are waiting to be sent
|
/* this holds list of replies that are waiting to be sent
|
||||||
to the client */
|
to the client */
|
||||||
@ -266,10 +266,8 @@ struct smbsrv_connection {
|
|||||||
uint8_t command;
|
uint8_t command;
|
||||||
} *trans_partial;
|
} *trans_partial;
|
||||||
|
|
||||||
BOOL processing;
|
|
||||||
|
|
||||||
/* mark a connection for termination */
|
/* mark a connection for termination */
|
||||||
BOOL terminate;
|
const char *terminate;
|
||||||
|
|
||||||
/* configuration parameters */
|
/* configuration parameters */
|
||||||
struct {
|
struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user