summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsource3/configure.developer2
-rw-r--r--source3/rpc_server/srv_util.c114
-rw-r--r--source3/smbd/ipc.c2
3 files changed, 89 insertions, 29 deletions
diff --git a/source3/configure.developer b/source3/configure.developer
index 0898b87119..91fc5021d9 100755
--- a/source3/configure.developer
+++ b/source3/configure.developer
@@ -1,3 +1,3 @@
#!/bin/sh
-export CFLAGS="-g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual"
+export CFLAGS="-g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align"
./configure
diff --git a/source3/rpc_server/srv_util.c b/source3/rpc_server/srv_util.c
index 59db0bed2c..0cb730470e 100644
--- a/source3/rpc_server/srv_util.c
+++ b/source3/rpc_server/srv_util.c
@@ -166,18 +166,29 @@ BOOL create_rpc_reply(pipes_struct *p,
uint32 data_start, uint32 data_end)
{
char *data;
+ BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN);
+ BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL);
uint32 data_len;
+ uint32 auth_len;
DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
data_start, data_end, p->hdr_ba.bba.max_tsize));
- mem_buf_init(&(p->rhdr.data), 0);
- mem_alloc_data(p->rhdr.data, 0x18);
+ auth_len = p->hdr.auth_len;
- p->rhdr.align = 4;
- p->rhdr.io = False;
+ if (p->ntlmssp_auth)
+ {
+ DEBUG(10,("create_rpc_reply: auth\n"));
+ if (auth_len != 16)
+ {
+ return False;
+ }
+ }
+
+ prs_init(&p->rhdr , 0x18, 4, 0, False);
+ prs_init(&p->rauth, 1024, 4, 0, False);
+ prs_init(&p->rverf, 0x08, 4, 0, False);
- p->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
p->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */
/* set up rpc header (fragmentation issues) */
@@ -190,6 +201,8 @@ BOOL create_rpc_reply(pipes_struct *p,
p->hdr.flags = 0;
}
+ p->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */
+
if (p->hdr_resp.alloc_hint + 0x18 <= p->hdr_ba.bba.max_tsize)
{
p->hdr.flags |= RPC_FLG_LAST;
@@ -200,30 +213,83 @@ BOOL create_rpc_reply(pipes_struct *p,
p->hdr.frag_len = p->hdr_ba.bba.max_tsize;
}
- data_len = p->hdr.frag_len;
+ if (p->ntlmssp_auth)
+ {
+ p->hdr_resp.alloc_hint -= auth_len - 16;
+ }
+
+ if (p->ntlmssp_auth)
+ {
+ data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18;
+ }
+ else
+ {
+ data_len = p->hdr.frag_len;
+ }
p->rhdr.data->offset.start = 0;
p->rhdr.data->offset.end = 0x18;
/* store the header in the data stream */
- p->rhdr.offset = 0;
- smb_io_rpc_hdr ("hdr", &(p->hdr ), &(p->rhdr), 0);
+ smb_io_rpc_hdr ("hdr" , &(p->hdr ), &(p->rhdr), 0);
smb_io_rpc_hdr_resp("resp", &(p->hdr_resp), &(p->rhdr), 0);
- p->frag_len_left = p->hdr.frag_len - p->file_offset;
- p->next_frag_start = p->hdr.frag_len;
-
/* don't use rdata: use rdata_i instead, which moves... */
- /* make a pointer to the rdata data. NOT A COPY */
+ /* make a pointer to the rdata data, NOT A COPY */
+ p->rdata_i.data = NULL;
prs_init(&p->rdata_i, 0, p->rdata.align, p->rdata.data->margin, p->rdata.io);
data = mem_data(&(p->rdata.data), data_start);
- mem_create(p->rdata_i.data, data, data_start, data_len, 0, False);
+ mem_create(p->rdata_i.data, data, 0, data_len, 0, False);
+ p->rdata_i.offset = data_len;
+
+ if (auth_len > 0)
+ {
+ uint32 crc32;
+
+ DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n",
+ BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len));
+
+ if (auth_seal)
+ {
+ NTLMSSPcalc(p->ntlmssp_hash, data, data_len);
+ crc32 = crc32_calc_buffer(data_len, data);
+ }
+
+ if (auth_seal || auth_verify)
+ {
+ make_rpc_hdr_auth(&p->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0));
+ smb_io_rpc_hdr_auth("hdr_auth", &p->auth_info, &p->rauth, 0);
+ }
+
+ if (auth_verify)
+ {
+ char *auth_data;
+ make_rpc_auth_ntlmssp_chk(&p->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, p->ntlmssp_seq_num);
+ smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p->ntlmssp_chk), &p->rverf, 0);
+ auth_data = (uchar*)mem_data(&p->rverf.data, 4);
+ NTLMSSPcalc(p->ntlmssp_hash, auth_data, 12);
+ }
+ }
/* set up the data chain */
- prs_link(NULL , &p->rhdr , &p->rdata_i);
- prs_link(&p->rhdr, &p->rdata_i, NULL );
+ if (p->ntlmssp_auth)
+ {
+ prs_link(NULL , &p->rhdr , &p->rdata_i);
+ prs_link(&p->rhdr , &p->rdata_i, &p->rauth );
+ prs_link(&p->rdata_i, &p->rauth , &p->rverf );
+ prs_link(&p->rauth , &p->rverf , NULL );
+ }
+ else
+ {
+ prs_link(NULL , &p->rhdr , &p->rdata_i);
+ prs_link(&p->rhdr, &p->rdata_i, NULL );
+ }
+ /* indicate to subsequent data reads where we are up to */
+ p->frag_len_left = p->hdr.frag_len - p->file_offset;
+ p->next_frag_start = p->hdr.frag_len;
+
return p->rhdr.data != NULL && p->rhdr.offset == 0x18;
}
@@ -271,7 +337,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p)
#endif
become_root(True);
p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain,
- p->ntlmssp_chal.challenge, (uchar*)lm_owf, (uchar*)nt_owf, NULL);
+ (uchar*)p->ntlmssp_chal.challenge,
+ (char*)lm_owf, (char*)nt_owf, NULL);
smb_pass = getsmbpwnam(p->user_name);
unbecome_root(True);
@@ -418,7 +485,7 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd)
DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__));
prs_init(&(p->rdata), 1024, 4, 0, False);
- prs_init(&(p->rhdr ), 0x10, 4, 0, False);
+ prs_init(&(p->rhdr ), 0x18, 4, 0, False);
prs_init(&(p->rauth), 1024, 4, 0, False);
prs_init(&(p->rverf), 0x08, 4, 0, False);
prs_init(&(p->rntlm), 1024, 4, 0, False);
@@ -561,6 +628,7 @@ static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd)
{
return False;
}
+ p->ntlmssp_seq_num = 0;
}
pd->offset = old_offset;
@@ -671,17 +739,9 @@ static BOOL api_rpc_command(pipes_struct *p,
}
/* start off with 1024 bytes, and a large safety margin too */
- mem_buf_init(&(p->rdata.data), SAFETY_MARGIN);
- mem_alloc_data(p->rdata.data, 1024);
-
- p->rdata.io = False;
- p->rdata.align = 4;
-
- p->rdata.data->offset.start = 0;
- p->rdata.data->offset.end = 0xffffffff;
+ prs_init(&p->rdata, 1024, 4, SAFETY_MARGIN, False);
/* do the actual command */
- p->rdata.offset = 0;
api_rpc_cmds[fn_num].fn(p->vuid, data, &(p->rdata));
if (p->rdata.data == NULL || p->rdata.offset == 0)
@@ -717,7 +777,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds
}
/* create the rpc header */
- if (!create_rpc_reply(p, 0, p->rdata.offset))
+ if (!create_rpc_reply(p, 0, p->rdata.offset + (p->ntlmssp_auth ? (16 + 16) : 0)))
{
return False;
}
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 3e697a59ce..249c286ec7 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -3195,7 +3195,7 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
DEBUG(5,("api_fd_reply\n"));
/* make a static data parsing structure from the api_fd_reply data */
- prs_init(&pd, 0, 4, True, 0);
+ prs_init(&pd, 0, 4, 0, True);
mem_create(pd.data, data, 0, tdscnt, 0, False);
/* First find out the name of this file. */