From 203c93e9221bfa71a00165f251695cafb92f035b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 23 Oct 1997 16:17:07 +0000 Subject: general sorting out, from crashes generated by do_lsa_req_chal() in client.c trying to set up the data parameters etc and not understanding what's going on. in api_netlogTNP, added smb_io_rpc_hdr() call to decode the header received (and in this instance, generated by do_lsa_req_chal()). and then noticed that it's two bytes out. but i don't know how to do "byte parameters" and it's not the same format as the LSA_REQCHAL received from nt workstations. agh! (This used to be commit 0cc8ce43e1d54b44237bb525f4cf6b77e7ca3ced) --- source3/client/client.c | 88 +++++++++++++++++++++++++++---------------------- source3/include/proto.h | 4 +-- source3/pipenetlog.c | 35 +++++++++++--------- source3/pipentlsa.c | 16 +++++++-- source3/pipesrvsvc.c | 19 ++++++++--- source3/pipeutil.c | 6 ++-- source3/smbd/ipc.c | 3 +- source3/smbparse.c | 9 ++--- 8 files changed, 105 insertions(+), 75 deletions(-) (limited to 'source3') diff --git a/source3/client/client.c b/source3/client/client.c index c3b0fafb18..0e6c1c384a 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -3528,9 +3528,10 @@ static BOOL do_lsa_req_chal(uint16 fnum) char *rparam = NULL; char *rdata = NULL; char *p; + char *rpc_hdr; int rdrcnt,rprcnt; int count = 0; - pstring param; /* only 1024 bytes */ + pstring data; /* only 1024 bytes */ uint16 setup[2]; /* only need 2 uint16 setup parameters */ LSA_Q_REQ_CHAL q_c; DOM_CHAL clnt_chal; @@ -3547,28 +3548,29 @@ static BOOL do_lsa_req_chal(uint16 fnum) /* store the parameters */ make_q_req_chal(&q_c, desthost, myhostname, &clnt_chal); - /* i have absolutely no idea why you do this */ - SIVAL(param, 0, 0xF400); + /* i have absolutely no idea why you do this. or what it is. help! */ + SIVAL(data, 0, 0xF400); + + rpc_hdr = data + 2; /* turn parameters into data stream */ - p = lsa_io_q_req_chal(False, &q_c, param + 0x18, param, 4, 5); + p = lsa_io_q_req_chal(False, &q_c, rpc_hdr + 0x18, rpc_hdr, 4, 5); /* create the request RPC_HDR _after_ the main data: length is now known */ - create_rpc_request(call_id, LSA_REQCHAL, param, PTR_DIFF(p, param)); + create_rpc_request(call_id, LSA_REQCHAL, rpc_hdr, PTR_DIFF(p, rpc_hdr)); /* create setup parameters. */ SIVAL(setup, 0, 0x0026); /* 0x26 indicates "transact named pipe" */ SIVAL(setup, 2, fnum); /* file handle, from the SMBcreateX pipe, earlier */ /* send the data on \PIPE\ */ - if (cli_call_api("\\PIPE\\", PTR_DIFF(p, param), 0, 2, 1024, + if (cli_call_api("\\PIPE\\", 0, PTR_DIFF(p, data), 2, 1024, BUFFER_SIZE, &rprcnt,&rdrcnt, - param, NULL, setup, + NULL, data, setup, &rparam,&rdata)) { DEBUG(5, ("cli_call_api: return OK\n")); - sleep(10); #if 0 /* oh, now what??? */ @@ -3595,46 +3597,52 @@ static BOOL do_lsa_req_chal(uint16 fnum) /**************************************************************************** open an rpc pipe (\NETLOGON or \srvsvc for example) ****************************************************************************/ -static int open_rpc_pipe(char *inbuf, char *outbuf, char *rname) +static uint16 open_rpc_pipe(char *inbuf, char *outbuf, char *rname) { - int fnum; - char *p; + int fnum; + char *p; - DEBUG(5,("open_rpc_pipe: %s\n", rname)); + DEBUG(5,("open_rpc_pipe: %s\n", rname)); - bzero(outbuf,smb_size); - set_message(outbuf,15,1 + strlen(rname),True); + bzero(outbuf,smb_size); + set_message(outbuf,15,1 + strlen(rname),True); - CVAL(outbuf,smb_com) = SMBopenX; - SSVAL(outbuf,smb_tid, cnum); - cli_setup_pkt(outbuf); + CVAL(outbuf,smb_com) = SMBopenX; + SSVAL(outbuf,smb_tid, cnum); + cli_setup_pkt(outbuf); - SSVAL(outbuf,smb_vwv0,0xFF); - SSVAL(outbuf,smb_vwv2,1); - SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4)); - SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN); - SSVAL(outbuf,smb_vwv8,1); - - p = smb_buf(outbuf); - strcpy(p,rname); - p = skip_string(p,1); + SSVAL(outbuf,smb_vwv0,0xFF); + SSVAL(outbuf,smb_vwv2,1); + SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4)); + SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN); + SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN); + SSVAL(outbuf,smb_vwv8,1); - send_smb(Client,outbuf); - receive_smb(Client,inbuf,CLIENT_TIMEOUT); - - if (CVAL(inbuf,smb_rcls) != 0) - { - DEBUG(0,("%s opening remote pipe %s\n", smb_errstr(inbuf),rname)); + p = smb_buf(outbuf); + strcpy(p,rname); + p = skip_string(p,1); - return -1; - } + send_smb(Client,outbuf); + receive_smb(Client,inbuf,CLIENT_TIMEOUT); + + if (CVAL(inbuf,smb_rcls) != 0) + { + if (CVAL(inbuf,smb_rcls) == ERRSRV && + SVAL(inbuf,smb_err) == ERRnoresource && + cli_reopen_connection(inbuf,outbuf)) + { + return open_rpc_pipe(inbuf, outbuf, rname); + } + DEBUG(0,("opening remote pipe %s - error %s\n", rname, smb_errstr(inbuf))); + + return 0xffff; + } - fnum = SVAL(inbuf, smb_vwv0); + fnum = SVAL(inbuf, smb_vwv2); - DEBUG(5,("opening pipe: fnum %d\n", fnum)); + DEBUG(5,("opening pipe: fnum %d\n", fnum)); - return fnum; + return fnum; } /**************************************************************************** @@ -3642,7 +3650,7 @@ static int open_rpc_pipe(char *inbuf, char *outbuf, char *rname) ****************************************************************************/ static BOOL cli_lsa_req_chal(void) { - int fnum; + uint16 fnum; char *inbuf,*outbuf; inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); @@ -3657,7 +3665,7 @@ static BOOL cli_lsa_req_chal(void) /* open the \PIPE\NETLOGON file */ fnum = open_rpc_pipe(inbuf, outbuf, PIPE_NETLOGON); - if (fnum > 0) + if (fnum != 0xffff) { do_lsa_req_chal(fnum); diff --git a/source3/include/proto.h b/source3/include/proto.h index a86a4999d9..96c4779e62 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -713,7 +713,7 @@ BOOL name_to_rid(char *user_name, uint32 *u_rid, uint32 *g_rid); char *dom_sid_to_string(DOM_SID *sid); int make_dom_sids(char *sids_str, DOM_SID *sids, int max_sids); int make_dom_gids(char *gids_str, DOM_GID *gids); -int create_rpc_request(uint32 call_id, uint16 op_num, char *q, int data_len); +int create_rpc_request(uint32 call_id, uint8 op_num, char *q, int data_len); int create_rpc_reply(uint32 call_id, char *q, int data_len); /*The following definitions come from predict.c */ @@ -915,7 +915,7 @@ char* smb_io_id_info1(BOOL io, DOM_ID_INFO_1 *id, char *q, char *base, int align char* smb_io_sam_info(BOOL io, DOM_SAM_INFO *sam, char *q, char *base, int align, int depth); char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align, int depth); void make_rpc_header(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, - uint32 call_id, int data_len, int opnum); + uint32 call_id, int data_len, uint8 opnum); char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align, int depth); char* smb_io_pol_hnd(BOOL io, LSA_POL_HND *pol, char *q, char *base, int align, int depth); char* smb_io_dom_query_3(BOOL io, DOM_QUERY_3 *d_q, char *q, char *base, int align, int depth); diff --git a/source3/pipenetlog.c b/source3/pipenetlog.c index fcd44b9701..ee00eee0ed 100644 --- a/source3/pipenetlog.c +++ b/source3/pipenetlog.c @@ -624,33 +624,38 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - /* really should decode these using an RPC_HDR structure */ - int pkttype = CVAL(data, 2); - uint32 call_id = SVAL(data,12); - uint16 opnum = SVAL(data,22); - user_struct *vuser; - if (pkttype == RPC_BIND) /* RPC BIND */ + RPC_HDR hdr; + + if (data == NULL) + { + DEBUG(2,("api_netlogrpcTNP: NULL data received\n")); + return False; + } + + smb_io_rpc_hdr(True, &hdr, data, data, 4, 5); + + if (hdr.pkt_type == RPC_BIND) /* RPC BIND */ { - DEBUG(4,("netlogon rpc bind %x\n",pkttype)); + DEBUG(4,("netlogon rpc bind %x\n",hdr.pkt_type)); LsarpcTNP1(data,rdata,rdata_len); return True; } - DEBUG(4,("netlogon TransactNamedPipe op %x\n",opnum)); + DEBUG(4,("netlogon TransactNamedPipe op %x\n",hdr.reserved)); if ((vuser = get_valid_user_struct(uid)) == NULL) return False; DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); - switch (opnum) + switch (hdr.reserved) { case LSA_REQCHAL: { DEBUG(3,("LSA_REQCHAL\n")); api_lsa_req_chal(cnum, uid, vuser, param, data, rdata, rdata_len); - create_rpc_reply(call_id, *rdata, *rdata_len); + create_rpc_reply(hdr.call_id, *rdata, *rdata_len); break; } @@ -658,7 +663,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_AUTH2\n")); api_lsa_auth_2(vuser, param, data, rdata, rdata_len); - create_rpc_reply(call_id, *rdata, *rdata_len); + create_rpc_reply(hdr.call_id, *rdata, *rdata_len); break; } @@ -666,7 +671,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_SRVPWSET\n")); api_lsa_srv_pwset(vuser, param, data, rdata, rdata_len); - create_rpc_reply(call_id, *rdata, *rdata_len); + create_rpc_reply(hdr.call_id, *rdata, *rdata_len); break; } @@ -674,7 +679,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_SAMLOGON\n")); api_lsa_sam_logon(vuser, param, data, rdata, rdata_len); - create_rpc_reply(call_id, *rdata, *rdata_len); + create_rpc_reply(hdr.call_id, *rdata, *rdata_len); break; } @@ -682,13 +687,13 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, { DEBUG(3,("LSA_SAMLOGOFF\n")); api_lsa_sam_logoff(vuser, param, data, rdata, rdata_len); - create_rpc_reply(call_id, *rdata, *rdata_len); + create_rpc_reply(hdr.call_id, *rdata, *rdata_len); break; } default: { - DEBUG(4, ("**** netlogon, unknown code: %lx\n", opnum)); + DEBUG(4, ("**** netlogon, unknown code: %lx\n", hdr.reserved)); break; } } diff --git a/source3/pipentlsa.c b/source3/pipentlsa.c index cabde4f8cd..69a8030f53 100644 --- a/source3/pipentlsa.c +++ b/source3/pipentlsa.c @@ -300,10 +300,20 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, char **rdata,char **rparam, int *rdata_len,int *rparam_len) { + int pkttype; + uint32 call_id; + uint16 opnum; + + if (data == NULL) + { + DEBUG(2, ("api_ntLsarpcTNP: NULL data parameter\n")); + return False; + } + /* really should decode these using an RPC_HDR structure */ - int pkttype = CVAL(data, 2); - uint32 call_id = CVAL(data, 12); - uint16 opnum = SVAL(data, 22); + pkttype = CVAL(data, 2); + call_id = CVAL(data, 12); + opnum = SVAL(data, 22); if (pkttype == RPC_BIND) /* RPC BIND */ { diff --git a/source3/pipesrvsvc.c b/source3/pipesrvsvc.c index 2c94bb2ebf..8f80cb1bd6 100644 --- a/source3/pipesrvsvc.c +++ b/source3/pipesrvsvc.c @@ -188,13 +188,24 @@ BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data, char **rdata,char **rparam, int *rdata_len,int *rparam_len) { - int pkttype = CVAL(data, 2); - uint32 call_id = SVAL(data,12); - uint16 opnum = SVAL(data,22); - extern pstring myname; char *q; + int pkttype; + uint32 call_id; + uint16 opnum; + + if (data == NULL) + { + DEBUG(2,("api_srvsvcTNP: NULL data parameter\n")); + return False; + } + + /* really should decode these with a RPC_HDR structure */ + pkttype = CVAL(data, 2); + call_id = SVAL(data,12); + opnum = SVAL(data,22); + if (pkttype == RPC_BIND) /* RPC BIND */ { DEBUG(4,("srvsvc rpc bind %x\n",pkttype)); diff --git a/source3/pipeutil.c b/source3/pipeutil.c index 135eb19190..dff0374433 100644 --- a/source3/pipeutil.c +++ b/source3/pipeutil.c @@ -217,12 +217,11 @@ int make_dom_gids(char *gids_str, DOM_GID *gids) return count; } -int create_rpc_request(uint32 call_id, uint16 op_num, char *q, int data_len) +int create_rpc_request(uint32 call_id, uint8 op_num, char *q, int data_len) { RPC_HDR hdr; - /* XXXX cheat - use cancel count to store opnum */ - make_rpc_header(&hdr, RPC_RESPONSE, call_id, data_len, op_num); + make_rpc_header(&hdr, RPC_REQUEST, call_id, data_len, op_num); return smb_io_rpc_hdr(False, &hdr, q, q, 4, 0) - q; } @@ -230,7 +229,6 @@ int create_rpc_reply(uint32 call_id, char *q, int data_len) { RPC_HDR hdr; - /* XXXX cheat - use cancel count to store opnum */ make_rpc_header(&hdr, RPC_RESPONSE, call_id, data_len, 0); return smb_io_rpc_hdr(False, &hdr, q, q, 4, 0) - q; } diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 01502573fc..ebfa564f6e 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -2781,7 +2781,8 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf, fd = setup[1]; subcommand = setup[0]; - DEBUG(3,("Got API command %d on pipe %s ",subcommand,Files[fd].name)); + DEBUG(3,("Got API command %d on pipe %s (fd %x)", + subcommand,Files[fd].name, fd)); DEBUG(3,("(tdscnt=%d,tpscnt=%d,mdrcnt=%d,mprcnt=%d,cnum=%d,vuid=%d)\n", tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid)); diff --git a/source3/smbparse.c b/source3/smbparse.c index ec0e877778..7c42ae52b0 100644 --- a/source3/smbparse.c +++ b/source3/smbparse.c @@ -612,7 +612,7 @@ char* smb_io_gid(BOOL io, DOM_GID *gid, char *q, char *base, int align, int dept creates an RPC_HDR structure. ********************************************************************/ void make_rpc_header(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, - uint32 call_id, int data_len, int opnum) + uint32 call_id, int data_len, uint8 opnum) { if (hdr == NULL) return; @@ -626,8 +626,8 @@ void make_rpc_header(RPC_HDR *hdr, enum RPC_PKT_TYPE pkt_type, hdr->call_id = call_id; /* call identifier - match incoming RPC */ hdr->alloc_hint = data_len - 0x18; /* allocation hint (no idea) */ hdr->context_id = 0; /* presentation context identifier */ - hdr->cancel_count = opnum; /* cancel count. or opnum. XXXX CHEAT! */ - hdr->reserved = 0; /* reserved */ + hdr->cancel_count = 0; /* cancel count. */ + hdr->reserved = opnum; /* response: reserved. request: opnum */ } /******************************************************************* @@ -640,9 +640,6 @@ char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align, int DEBUG(5,("%s%04x smb_io_rpc_hdr\n", tab_depth(depth), PTR_DIFF(q, base))); depth++; - /* reserved should be zero: enforce it */ - rpc->reserved = 0; - DBG_RW_CVAL("major ", depth, base, io, q, rpc->major); q++; DBG_RW_CVAL("minor ", depth, base, io, q, rpc->minor); q++; DBG_RW_CVAL("pkt_type ", depth, base, io, q, rpc->pkt_type); q++; -- cgit