From 195e3d44daccc3b6457486018ba0322ac9d44566 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 7 Feb 2000 16:25:15 +0000 Subject: spoolss definitions. also added some prs_struct functions, 'cause I'm handling buffers as prs_struct. J.F. (This used to be commit 81e375bbbe0fb022a44a2aaaa3729a9518b7a854) --- source3/rpc_parse/parse_misc.c | 25 ++++++++++++++++++++ source3/rpc_parse/parse_prs.c | 50 +++++++++++++++++++++++++++++++++++++++ source3/rpc_parse/parse_rpc.c | 21 ++++++++-------- source3/rpc_server/srv_pipe_srv.c | 47 ++++++++++++++++++++++++++++++++---- 4 files changed, 128 insertions(+), 15 deletions(-) (limited to 'source3') diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 5277825767..21d97b444c 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -592,6 +592,31 @@ BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth) return True; } +/******************************************************************* +reads or writes a BUFFER5 structure. +the buf_len member tells you how large the buffer is. +********************************************************************/ +BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "smb_io_buffer4"); + depth++; + + if (buf5 == NULL) return False; + + prs_align(ps); + prs_uint32("buf_len", ps, depth, &(buf5->buf_len)); + + /* reading: alloc the buffer first */ + if ( ps->io ) + { + buf5->buffer=(uint16 *)malloc( sizeof(uint16)*buf5->buf_len ); + } + + prs_uint16s(True, "buffer", ps, depth, buf5->buffer, buf5->buf_len); + + return True; +} + /******************************************************************* Inits a BUFFER2 structure. ********************************************************************/ diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 6bb07c5f64..24eff1b779 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -282,6 +282,21 @@ BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src) return True; } +/******************************************************************* + Append some data from one parse_struct into another. + ********************************************************************/ + +BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, uint32 len) +{ + if(!prs_grow(dst, len)) + return False; + + memcpy(&dst->data_p[dst->data_offset], prs_data_p(src), (size_t)len); + dst->data_offset += len; + + return True; +} + /******************************************************************* Append the data from a buffer into a parse_struct. ********************************************************************/ @@ -351,6 +366,25 @@ char *prs_mem_get(prs_struct *ps, uint32 extra_size) return &ps->data_p[ps->data_offset]; } +/******************************************************************* + Change the struct type. + ********************************************************************/ + +BOOL prs_switch_type(prs_struct *ps, BOOL io) +{ + if ((ps->io ^ io) == True) + ps->io=io; +} + +/******************************************************************* + Force a prs_struct to be dynamic even when it's size is 0. + ********************************************************************/ + +void prs_force_dynamic(prs_struct *ps) +{ + ps->is_dynamic=True; +} + /******************************************************************* Stream a uint8. ********************************************************************/ @@ -416,6 +450,22 @@ BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *dat return True; } +/****************************************************************** + Stream an array of uint16s. Length is number of uint16s. + ********************************************************************/ + +BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len) +{ + char *q = prs_mem_get(ps, len * sizeof(uint16)); + if (q == NULL) + return False; + + DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) + ps->data_offset += (len * sizeof(uint16)); + + return True; +} + /****************************************************************** Stream an array of uint32s. Length is number of uint32s. ********************************************************************/ diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index d4ea84628a..54d3eea74d 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -105,6 +105,15 @@ interface/version dce/rpc pipe identification }, 0x01 \ } +#define SYNT_SPOOLSS_V1 \ +{ \ + { \ + 0x12345678, 0x1234, 0xabcb, \ + { 0xef, 0x00, 0x01, 0x23, \ + 0x45, 0x67, 0x89, 0xab } \ + }, 0x01 \ +} + #define SYNT_NONE_V0 \ { \ { \ @@ -114,17 +123,6 @@ interface/version dce/rpc pipe identification }, 0x00 \ } -/* pipe string names */ -#define PIPE_SRVSVC "\\PIPE\\srvsvc" -#define PIPE_SAMR "\\PIPE\\samr" -#define PIPE_WINREG "\\PIPE\\winreg" -#define PIPE_WKSSVC "\\PIPE\\wkssvc" -#define PIPE_NETLOGON "\\PIPE\\NETLOGON" -#define PIPE_NTLSA "\\PIPE\\ntlsa" -#define PIPE_NTSVCS "\\PIPE\\ntsvcs" -#define PIPE_LSASS "\\PIPE\\lsass" -#define PIPE_LSARPC "\\PIPE\\lsarpc" - struct pipe_id_info pipe_names [] = { /* client pipe , abstract syntax , server pipe , transfer syntax */ @@ -134,6 +132,7 @@ struct pipe_id_info pipe_names [] = { PIPE_SRVSVC , SYNT_SRVSVC_V3 , PIPE_NTSVCS , TRANS_SYNT_V2 }, { PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 }, { PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 }, + { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 }, { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 } }; diff --git a/source3/rpc_server/srv_pipe_srv.c b/source3/rpc_server/srv_pipe_srv.c index 236558ba70..2cebc8148b 100644 --- a/source3/rpc_server/srv_pipe_srv.c +++ b/source3/rpc_server/srv_pipe_srv.c @@ -465,6 +465,7 @@ static struct api_cmd api_fd_commands[] = #if DISABLED_IN_2_0 { "winreg", "winreg", api_reg_rpc }, #endif + { "spoolss", "spoolss", api_spoolss_rpc }, { NULL, NULL, NULL } }; @@ -585,7 +586,7 @@ static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd) Respond to a pipe bind request. *******************************************************************/ -static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type) { RPC_HDR_BA hdr_ba; RPC_HDR_RB hdr_rb; @@ -684,9 +685,21 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) p->ntlmssp_auth_requested = True; } - /* name has to be \PIPE\xxxxx */ - fstrcpy(ack_pipe_name, "\\PIPE\\"); - fstrcat(ack_pipe_name, p->pipe_srv_name); + switch (pkt_type) { + case RPC_BINDACK: + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, p->pipe_srv_name); + case RPC_ALTCONTRESP: + /* secondary address CAN be NULL + * as the specs says it's ignored. + * It MUST NULL to have the spoolss working. + */ + fstrcpy(ack_pipe_name, ""); + break; + default: + return False; + } DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); @@ -831,6 +844,29 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) return False; } +/******************************************************************* + Respond to a pipe bind request. +*******************************************************************/ + +static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +{ + return api_pipe_bind_and_alt_req(p, pd, RPC_BINDACK); +} + +/******************************************************************* + Respond to a pipe alter request. + + The RPC Alter-Context call is used only by the spoolss pipe + simply because there is a bug (?) in the MS unmarshalling code + or in the marshalling code. If it's in the later, then Samba + have the same bug. +*******************************************************************/ + +static BOOL api_pipe_altercontext_req(pipes_struct *p, prs_struct *pd) +{ + return api_pipe_bind_and_alt_req(p, pd, RPC_ALTCONTRESP); +} + /**************************************************************************** Deal with sign & seal processing on an RPC request. ****************************************************************************/ @@ -1011,6 +1047,9 @@ BOOL rpc_command(pipes_struct *p, char *input_data, int data_len) case RPC_BIND: reply = api_pipe_bind_req(p, &rpc_in); break; + case RPC_ALTCONT: + reply = api_pipe_altercontext_req(p, &rpc_in); + break; case RPC_REQUEST: if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) { /* authentication _was_ requested -- cgit