summaryrefslogtreecommitdiff
path: root/source3/rpc_server/srv_pipe_hnd.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_server/srv_pipe_hnd.c')
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c210
1 files changed, 46 insertions, 164 deletions
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c
index faba41b925..e51bc5ae4d 100644
--- a/source3/rpc_server/srv_pipe_hnd.c
+++ b/source3/rpc_server/srv_pipe_hnd.c
@@ -78,8 +78,10 @@ void init_rpc_pipe_hnd(void)
Initialise an outgoing packet.
****************************************************************************/
-static BOOL pipe_init_outgoing_data(output_data *o_data)
+static BOOL pipe_init_outgoing_data(pipes_struct *p)
{
+ output_data *o_data = &p->out_data;
+
/* Reset the offset counters. */
o_data->data_sent_length = 0;
o_data->current_pdu_len = 0;
@@ -94,7 +96,7 @@ static BOOL pipe_init_outgoing_data(output_data *o_data)
* Initialize the outgoing RPC data buffer.
* we will use this as the raw data area for replying to rpc requests.
*/
- if(!prs_init(&o_data->rdata, MAX_PDU_FRAG_LEN, 4, MARSHALL)) {
+ if(!prs_init(&o_data->rdata, MAX_PDU_FRAG_LEN, 4, p->mem_ctx, MARSHALL)) {
DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
return False;
}
@@ -103,60 +105,6 @@ static BOOL pipe_init_outgoing_data(output_data *o_data)
}
/****************************************************************************
- Attempt to find a remote process to communicate RPC's with.
-****************************************************************************/
-
-#if 0
-
-static void attempt_remote_rpc_connect(pipes_struct *p)
-{
- struct user_creds usr;
- user_struct *vuser = get_valid_user_struct(p->vuid);
-
- p->m = NULL;
-
- if (vuser == NULL) {
- DEBUG(4,("attempt_remote_rpc_connect: invalid vuid %d\n", (int)p->vuid));
- return;
- }
-
- ZERO_STRUCT(usr);
-
- /* set up unix credentials from the smb side, to feed over the pipe */
- make_creds_unix(&usr.uxc, vuser->user.unix_name, vuser->user.smb_name,
- vuser->user.full_name, vuser->guest);
- usr.ptr_uxc = 1;
- make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
- vuser->n_groups, vuser->groups);
- usr.ptr_uxs = 1;
-
- usr.ptr_ssk = 1;
- DEBUG(10,("user session key not available (yet).\n"));
- DEBUG(10,("password-change operations may fail.\n"));
-
-#if USER_SESSION_KEY_DEFINED_IN_VUSER_STRUCT
- memcpy(usr.usr_sess_key, vuser->usr_sess_key, sizeof(usr.usr_sess_key));
-#else
- memset(usr.usr_sess_key, 0, sizeof(usr.usr_sess_key));
-#endif
-
- /* set up nt credentials from the smb side, to feed over the pipe */
- /* lkclXXXX todo!
- make_creds_nt(&usr.ntc);
- make_creds_nt_sec(&usr.nts);
- */
-
- become_root(); /* to connect to pipe */
- p->m = msrpc_use_add(p->name, sys_getpid(), &usr, False);
- unbecome_root();
-
- if (p->m == NULL)
- DEBUG(10,("attempt_remote_rpc_connect: msrpc redirect failed - using local implementation.\n"));
-}
-
-#endif
-
-/****************************************************************************
Find first available pipe slot.
****************************************************************************/
@@ -196,6 +144,12 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
ZERO_STRUCTP(p);
+ if ((p->mem_ctx = talloc_init()) == NULL) {
+ DEBUG(0,("open_rpc_pipe_p: talloc_init failed.\n"));
+ free(p);
+ return NULL;
+ }
+
DLIST_ADD(Pipes, p);
/*
@@ -205,7 +159,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
* change the type to UNMARSALLING before processing the stream.
*/
- if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, 4, MARSHALL)) {
+ if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, 4, p->mem_ctx, MARSHALL)) {
DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
return NULL;
}
@@ -250,7 +204,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
/*
* Initialize the outgoing RPC data buffer with no memory.
*/
- prs_init(&p->out_data.rdata, 0, 4, MARSHALL);
+ prs_init(&p->out_data.rdata, 0, 4, p->mem_ctx, MARSHALL);
ZERO_STRUCT(p->pipe_user);
@@ -332,7 +286,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
return -1;
}
- prs_init( &rpc_in, 0, 4, UNMARSHALL);
+ prs_init( &rpc_in, 0, 4, p->mem_ctx, UNMARSHALL);
prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
p->in_data.pdu_received_len, False);
@@ -344,6 +298,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
DEBUG(0,("unmarshall_rpc_header: failed to unmarshall RPC_HDR.\n"));
set_incoming_fault(p);
+ prs_mem_free(&rpc_in);
return -1;
}
@@ -354,6 +309,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
if(p->hdr.major != 5 && p->hdr.minor != 0) {
DEBUG(0,("unmarshall_rpc_header: invalid major/minor numbers in RPC_HDR.\n"));
set_incoming_fault(p);
+ prs_mem_free(&rpc_in);
return -1;
}
@@ -366,6 +322,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
if((p->hdr.pkt_type == RPC_REQUEST) && (prs_offset(&p->in_data.data) == 0) && !(p->hdr.flags & RPC_FLG_FIRST)) {
DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
set_incoming_fault(p);
+ prs_mem_free(&rpc_in);
return -1;
}
@@ -376,6 +333,7 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > MAX_PDU_FRAG_LEN)) {
DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
set_incoming_fault(p);
+ prs_mem_free(&rpc_in);
return -1;
}
@@ -394,6 +352,8 @@ static ssize_t unmarshall_rpc_header(pipes_struct *p)
memset((char *)&p->in_data.current_in_pdu[0], '\0', RPC_HEADER_LEN);
+ prs_mem_free(&rpc_in);
+
return 0; /* No extra data processed. */
}
@@ -505,7 +465,7 @@ authentication failed. Denying the request.\n", p->name));
* Process the complete data stream here.
*/
- if(pipe_init_outgoing_data(&p->out_data))
+ if(pipe_init_outgoing_data(p))
ret = api_pipe_request(p);
/*
@@ -536,6 +496,14 @@ static ssize_t process_complete_pdu(pipes_struct *p)
char *data_p = (char *)&p->in_data.current_in_pdu[0];
BOOL reply = False;
+ if (p->mem_ctx) {
+ talloc_destroy_pool(p->mem_ctx);
+ } else {
+ p->mem_ctx = talloc_init();
+ if (p->mem_ctx == NULL)
+ p->fault_state = True;
+ }
+
if(p->fault_state) {
DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
p->name ));
@@ -544,7 +512,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
return (ssize_t)data_len;
}
- prs_init( &rpc_in, 0, 4, UNMARSHALL);
+ prs_init( &rpc_in, 0, 4, p->mem_ctx, UNMARSHALL);
prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);
DEBUG(10,("process_complete_pdu: processing packet type %u\n",
@@ -556,14 +524,14 @@ static ssize_t process_complete_pdu(pipes_struct *p)
/*
* We assume that a pipe bind is only in one pdu.
*/
- if(pipe_init_outgoing_data(&p->out_data))
+ if(pipe_init_outgoing_data(p))
reply = api_pipe_bind_req(p, &rpc_in);
break;
case RPC_BINDRESP:
/*
* We assume that a pipe bind_resp is only in one pdu.
*/
- if(pipe_init_outgoing_data(&p->out_data))
+ if(pipe_init_outgoing_data(p))
reply = api_pipe_bind_auth_resp(p, &rpc_in);
break;
case RPC_REQUEST:
@@ -578,6 +546,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on pipe %s\n", p->pipe_srv_name));
set_incoming_fault(p);
setup_fault_pdu(p);
+ prs_mem_free(&rpc_in);
} else {
/*
* Reset the lengths. We're ready for a new pdu.
@@ -586,6 +555,7 @@ static ssize_t process_complete_pdu(pipes_struct *p)
p->in_data.pdu_received_len = 0;
}
+ prs_mem_free(&rpc_in);
return (ssize_t)data_len;
}
@@ -687,14 +657,7 @@ ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
DEBUG(10,("write_to_pipe: data_left = %u\n", (unsigned int)data_left ));
- /*
- * Deal with the redirect to the remote RPC daemon.
- */
-
- if(p->m)
- data_used = write(p->m->fd, data, data_left);
- else
- data_used = process_incoming_data(p, data, data_left);
+ data_used = process_incoming_data(p, data, data_left);
DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));
@@ -709,70 +672,6 @@ ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
}
/****************************************************************************
- Gets data from a remote TNG daemon. Gets data from the remote daemon into
- the outgoing prs_struct.
-
- NB. Note to Luke : This code will be broken until Luke implements a length
- field before reply data...
-
-****************************************************************************/
-
-static BOOL read_from_remote(pipes_struct *p)
-{
- uint32 data_len;
- uint32 data_len_left;
-
- if(prs_offset(&p->out_data.rdata) == 0) {
-
- ssize_t len = 0;
-
- /*
- * Read all the reply data as a stream of pre-created
- * PDU's from the remote deamon into the rdata struct.
- */
-
- /*
- * Create the response data buffer.
- */
-
- if(!pipe_init_outgoing_data(&p->out_data)) {
- DEBUG(0,("read_from_remote: failed to create outgoing buffer.\n"));
- return False;
- }
-
- /* Read from remote here. */
- if((len = read_with_timeout(p->m->fd, prs_data_p(&p->out_data.rdata), 1, 65536, 10000)) < 0) {
- DEBUG(0,("read_from_remote: failed to read from external daemon.\n"));
- prs_mem_free(&p->out_data.rdata);
- return False;
- }
-
- /* Set the length we got. */
- prs_set_offset(&p->out_data.rdata, (uint32)len);
- }
-
- /*
- * The amount we send is the minimum of the available
- * space and the amount left to send.
- */
-
- data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length;
-
- /*
- * Ensure there really is data left to send.
- */
-
- if(!data_len_left) {
- DEBUG(0,("read_from_remote: no data left to send !\n"));
- return False;
- }
-
- data_len = MIN(data_len_left, MAX_PDU_FRAG_LEN);
-
- return False; /* Notfinished... */
-}
-
-/****************************************************************************
Replies to a request to read data from a pipe.
Headers are interspersed with the data at PDU intervals. By the time
@@ -844,28 +743,16 @@ returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
return 0;
}
- if(p->m) {
- /*
- * Remote to the RPC daemon.
- */
- if(!read_from_remote(p)) {
- DEBUG(0,("read_from_pipe: %s: read_from_remote failed.\n", p->name ));
- return -1;
- }
-
- } else {
-
- /*
- * We need to create a new PDU from the data left in p->rdata.
- * Create the header/data/footers. This also sets up the fields
- * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
- * and stores the outgoing PDU in p->current_pdu.
- */
+ /*
+ * We need to create a new PDU from the data left in p->rdata.
+ * Create the header/data/footers. This also sets up the fields
+ * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
+ * and stores the outgoing PDU in p->current_pdu.
+ */
- if(!create_next_pdu(p)) {
- DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n", p->name));
- return -1;
- }
+ if(!create_next_pdu(p)) {
+ DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n", p->name));
+ return -1;
}
data_returned = MIN(n, p->out_data.current_pdu_len);
@@ -937,18 +824,13 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
prs_mem_free(&p->out_data.rdata);
prs_mem_free(&p->in_data.data);
+ if (p->mem_ctx)
+ talloc_destroy(p->mem_ctx);
+
bitmap_clear(bmap, p->pnum - pipe_handle_offset);
pipes_open--;
- if (p->m != NULL) {
- DEBUG(4,("close_rpc_pipe_hnd: closing msrpc redirect: "));
- if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
- DEBUG(4,("OK\n"));
- else
- DEBUG(4,("FAILED\n"));
- }
-
DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
p->name, p->pnum, pipes_open));