diff options
-rw-r--r-- | source/client/client.c | 16 | ||||
-rw-r--r-- | source/client/ntclient.c | 272 | ||||
-rw-r--r-- | source/include/byteorder.h | 6 | ||||
-rw-r--r-- | source/include/proto.h | 13 | ||||
-rw-r--r-- | source/include/smb.h | 6 | ||||
-rw-r--r-- | source/libsmb/credentials.c | 107 | ||||
-rw-r--r-- | source/libsmb/smbdes.c | 5 | ||||
-rw-r--r-- | source/libsmb/smbencrypt.c | 24 | ||||
-rw-r--r-- | source/lsaparse.c | 18 | ||||
-rw-r--r-- | source/pipenetlog.c | 137 | ||||
-rw-r--r-- | source/pipentlsa.c | 6 | ||||
-rw-r--r-- | source/pipesrvsvc.c | 6 | ||||
-rw-r--r-- | source/smbd/ipc.c | 5 | ||||
-rw-r--r-- | source/smbd/reply.c | 2 | ||||
-rw-r--r-- | source/smbd/server.c | 8 | ||||
-rw-r--r-- | source/smbd/uid.c | 44 | ||||
-rw-r--r-- | source/smbparse.c | 26 |
17 files changed, 498 insertions, 203 deletions
diff --git a/source/client/client.c b/source/client/client.c index 5dbb2f3b1c1..68cd930cf93 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -3886,6 +3886,8 @@ static void usage(char *pname) return(ret); } +#ifdef NTDOMAIN + if (nt_domain_logon) { int ret = 0; @@ -3897,25 +3899,17 @@ static void usage(char *pname) if (cli_open_sockets(port)) { - DOM_CHAL srv_chal; - if (!cli_send_login(NULL,NULL,True,True)) return(1); - if (!cli_lsa_req_chal(&srv_chal, desthost, myhostname, Client, cnum)) - { - return (1); - } -#if 0 - cli_lsa_auth2(); - cli_lsa_sam_logon(); - cli_lsa_sam_logoff(); -#endif + do_nt_login(desthost, myhostname, Client, cnum); + cli_send_logout(); close_sockets(); } return(ret); } +#endif if (cli_open_sockets(port)) { diff --git a/source/client/ntclient.c b/source/client/ntclient.c index decc2e34d66..9fa64bd2efd 100644 --- a/source/client/ntclient.c +++ b/source/client/ntclient.c @@ -29,11 +29,65 @@ extern int DEBUGLEVEL; #define CLIENT_TIMEOUT (30*1000) +#ifdef NTDOMAIN + +/**************************************************************************** + open an rpc pipe (\NETLOGON or \srvsvc for example) + ****************************************************************************/ +static uint16 open_rpc_pipe(char *inbuf, char *outbuf, char *rname, int Client, int cnum) +{ + int fnum; + char *p; + + DEBUG(5,("open_rpc_pipe: %s\n", rname)); + + 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); + + 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); + + 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, Client, cnum); + } + DEBUG(0,("opening remote pipe %s - error %s\n", rname, smb_errstr(inbuf))); + + return 0xffff; + } + + fnum = SVAL(inbuf, smb_vwv2); + + DEBUG(5,("opening pipe: fnum %d\n", fnum)); + + return fnum; +} + /**************************************************************************** do a LSA Request Challenge ****************************************************************************/ static BOOL do_lsa_req_chal(uint16 fnum, - char *desthost, char *myhostname, DOM_CHAL *srv_chal) + char *desthost, char *myhostname, + DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal) { char *rparam = NULL; char *rdata = NULL; @@ -42,22 +96,18 @@ static BOOL do_lsa_req_chal(uint16 fnum, pstring data; /* only 1024 bytes */ uint16 setup[2]; /* only need 2 uint16 setup parameters */ LSA_Q_REQ_CHAL q_c; - DOM_CHAL clnt_chal; int call_id = 0x1; BOOL valid_chal = False; - if (srv_chal == NULL) return False; + if (srv_chal == NULL || clnt_chal == NULL) return False; /* create and send a MSRPC command with api LSA_REQCHAL */ - clnt_chal.data[0] = 0x11111111; - clnt_chal.data[1] = 0x22222222; - DEBUG(4,("LSA Request Challenge from %s to %s: %lx %lx\n", - desthost, myhostname, clnt_chal.data[0], clnt_chal.data[1])); + desthost, myhostname, clnt_chal->data[0], clnt_chal->data[1])); /* store the parameters */ - make_q_req_chal(&q_c, desthost, myhostname, &clnt_chal); + make_q_req_chal(&q_c, desthost, myhostname, clnt_chal); /* turn parameters into data stream */ @@ -133,66 +183,137 @@ static BOOL do_lsa_req_chal(uint16 fnum, } /**************************************************************************** - open an rpc pipe (\NETLOGON or \srvsvc for example) - ****************************************************************************/ -static uint16 open_rpc_pipe(char *inbuf, char *outbuf, char *rname, int Client, int cnum) +do a LSA Authenticate 2 +****************************************************************************/ +static BOOL do_lsa_auth2(uint16 fnum, + char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name, + DOM_CHAL *clnt_chal, uint32 neg_flags, DOM_CHAL *srv_chal) { - int fnum; + char *rparam = NULL; + char *rdata = NULL; char *p; + int rdrcnt,rprcnt; + pstring data; /* only 1024 bytes */ + uint16 setup[2]; /* only need 2 uint16 setup parameters */ + LSA_Q_AUTH_2 q_a; + int call_id = 0x1; + BOOL valid_chal = False; - DEBUG(5,("open_rpc_pipe: %s\n", rname)); + if (srv_chal == NULL || clnt_chal == NULL) return False; - bzero(outbuf,smb_size); - set_message(outbuf,15,1 + strlen(rname),True); + /* create and send a MSRPC command with api LSA_AUTH2 */ - CVAL(outbuf,smb_com) = SMBopenX; - SSVAL(outbuf,smb_tid, cnum); - cli_setup_pkt(outbuf); + DEBUG(4,("LSA Authenticate 2: srv:%s acct:%s sc:%x mc: %s chal %lx %lx neg: %lx\n", + logon_srv, acct_name, sec_chan, comp_name, + clnt_chal->data[0], clnt_chal->data[1], neg_flags)); - 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); + /* store the parameters */ + make_q_auth_2(&q_a, logon_srv, acct_name, sec_chan, comp_name, + clnt_chal, neg_flags); - p = smb_buf(outbuf); - strcpy(p,rname); - p = skip_string(p,1); + /* turn parameters into data stream */ + p = lsa_io_q_auth_2(False, &q_a, data + 0x18, data, 4, 0); - send_smb(Client,outbuf); - receive_smb(Client,inbuf,CLIENT_TIMEOUT); + /* create the request RPC_HDR _after_ the main data: length is now known */ + create_rpc_request(call_id, LSA_AUTH2, data, PTR_DIFF(p, data)); - if (CVAL(inbuf,smb_rcls) != 0) + /* 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\\", 0, PTR_DIFF(p, data), 2, 1024, + BUFFER_SIZE, + &rprcnt,&rdrcnt, + NULL, data, setup, + &rparam,&rdata)) { - if (CVAL(inbuf,smb_rcls) == ERRSRV && - SVAL(inbuf,smb_err) == ERRnoresource && - cli_reopen_connection(inbuf,outbuf)) + LSA_R_AUTH_2 r_a; + RPC_HDR hdr; + int hdr_len; + int pkt_len; + + DEBUG(5, ("cli_call_api: return OK\n")); + + p = rdata; + + if (p) p = smb_io_rpc_hdr (True, &hdr, p, rdata, 4, 0); + if (p) p = align_offset(p, rdata, 4); /* oh, what a surprise */ + + hdr_len = PTR_DIFF(p, rdata); + + if (p && hdr_len != hdr.frag_len - hdr.alloc_hint) { - return open_rpc_pipe(inbuf, outbuf, rname, Client, cnum); + /* header length not same as calculated header length */ + DEBUG(2,("do_lsa_auth2: hdr_len %x != frag_len-alloc_hint\n", + hdr_len, hdr.frag_len - hdr.alloc_hint)); + p = NULL; } - DEBUG(0,("opening remote pipe %s - error %s\n", rname, smb_errstr(inbuf))); - return 0xffff; - } + if (p) p = lsa_io_r_auth_2(True, &r_a, p, rdata, 4, 0); + + pkt_len = PTR_DIFF(p, rdata); - fnum = SVAL(inbuf, smb_vwv2); + if (p && pkt_len != hdr.frag_len) + { + /* packet data size not same as reported fragment length */ + DEBUG(2,("do_lsa_auth2: pkt_len %x != frag_len \n", + pkt_len, hdr.frag_len)); + p = NULL; + } - DEBUG(5,("opening pipe: fnum %d\n", fnum)); + if (p && r_a.status != 0) + { + /* report error code */ + DEBUG(0,("LSA_AUTH2: nt_status error %lx\n", r_a.status)); + p = NULL; + } - return fnum; + if (p && r_a.srv_flgs.neg_flags != q_a.clnt_flgs.neg_flags) + { + /* report different neg_flags */ + DEBUG(0,("LSA_AUTH2: error neg_flags (q,r) differ - (%lx,%lx)\n", + q_a.clnt_flgs.neg_flags, r_a.srv_flgs.neg_flags)); + p = NULL; + } + + if (p) + { + /* ok, at last: we're happy. return the challenge */ + memcpy(srv_chal, r_a.srv_chal.data, sizeof(srv_chal->data)); + valid_chal = True; + } + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + return valid_chal; } /**************************************************************************** - +experimental nt login. ****************************************************************************/ -BOOL cli_lsa_req_chal(DOM_CHAL *srv_chal, char *desthost, char *myhostname, +BOOL do_nt_login(char *desthost, char *myhostname, int Client, int cnum) { + DOM_CHAL clnt_chal; + DOM_CHAL srv_chal; + + DOM_CHAL auth2_clnt_chal; + DOM_CHAL auth2_srv_chal; + + UTIME zerotime; + + uint32 sess_key[2]; + char nt_owf_mach_pwd[16]; + fstring mach_acct; + fstring mach_pwd; + uint16 fnum; char *inbuf,*outbuf; - if (srv_chal == NULL) return False; + zerotime.time = 0; inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); @@ -204,19 +325,72 @@ BOOL cli_lsa_req_chal(DOM_CHAL *srv_chal, char *desthost, char *myhostname, } /* open the \PIPE\NETLOGON file */ - fnum = open_rpc_pipe(inbuf, outbuf, PIPE_NETLOGON, Client, cnum); + if ((fnum = open_rpc_pipe(inbuf, outbuf, PIPE_NETLOGON, Client, cnum)) == 0xffff) + { + free(inbuf); free(outbuf); + return False; + } + + fstrcpy(mach_acct, myhostname); + strlower(mach_pwd); - if (fnum != 0xffff) + fstrcpy(mach_pwd , myhostname); + strcat(mach_acct, "$"); + + clnt_chal.data[0] = 0x11111111; + clnt_chal.data[1] = 0x22222222; + + /* send a client challenge; receive a server challenge */ + if (!do_lsa_req_chal(fnum, desthost, myhostname, &clnt_chal, &srv_chal)) { - do_lsa_req_chal(fnum, desthost, myhostname, srv_chal); + cli_smb_close(inbuf, outbuf, Client, cnum, fnum); + free(inbuf); free(outbuf); + return False; + } + - /* close \PIPE\NETLOGON */ +#if 0 + /* DAMN! can't get the machine password - need become_root() to do it! */ + /* get the machine password */ + if (!get_md4pw(mach_acct, nt_owf_mach_pwd)) + { cli_smb_close(inbuf, outbuf, Client, cnum, fnum); + free(inbuf); free(outbuf); + return False; + } +#endif + { + char lm_owf_mach_pwd[16]; + nt_lm_owf_gen(mach_pwd, nt_owf_mach_pwd, lm_owf_mach_pwd); + DEBUG(5,("generating nt owf from initial machine pwd: %s\n", mach_pwd)); + dump_data(6, nt_owf_mach_pwd, 16); + } + + /* calculate the session key */ + cred_session_key(&clnt_chal, &srv_chal, nt_owf_mach_pwd, sess_key); + + /* calculate auth-2 credentials */ + cred_create(sess_key, &clnt_chal, zerotime, &auth2_clnt_chal); + + /* send client auth-2 challenge; receive an auth-2 challenge */ + if (!do_lsa_auth2(fnum, desthost, mach_acct, 2, myhostname, + &auth2_clnt_chal, 0x000001ff, &auth2_srv_chal)) + { + cli_smb_close(inbuf, outbuf, Client, cnum, fnum); free(inbuf); free(outbuf); - return True; + return False; } - return False; +#if 0 + cli_lsa_sam_logon(); + cli_lsa_sam_logoff(); +#endif + + cli_smb_close(inbuf, outbuf, Client, cnum, fnum); + free(inbuf); free(outbuf); + + return True; } +#endif diff --git a/source/include/byteorder.h b/source/include/byteorder.h index f43159ecf4e..147d20d26d6 100644 --- a/source/include/byteorder.h +++ b/source/include/byteorder.h @@ -226,15 +226,15 @@ it also defines lots of intermediate macros, just ignore those :-) #define DBG_RW_CVAL(string,depth,base,read,inbuf,outbuf) \ RW_CVAL(read,inbuf,outbuf,0) \ DEBUG(5,("%s%04x %s: %02x\n", \ - tab_depth(depth), PTR_DIFF(inbuf,base),string, *((uint8*)(inbuf)))); + tab_depth(depth), PTR_DIFF(inbuf,base),string, CVAL(inbuf, 0))); #define DBG_RW_SVAL(string,depth,base,read,inbuf,outbuf) \ RW_SVAL(read,inbuf,outbuf,0) \ DEBUG(5,("%s%04x %s: %04x\n", \ - tab_depth(depth), PTR_DIFF(inbuf,base),string, *((uint16*)(inbuf)))); + tab_depth(depth), PTR_DIFF(inbuf,base),string, SVAL(inbuf, 0))); #define DBG_RW_IVAL(string,depth,base,read,inbuf,outbuf) \ RW_IVAL(read,inbuf,outbuf,0) \ DEBUG(5,("%s%04x %s: %08x\n", \ - tab_depth(depth), PTR_DIFF(inbuf,base),string, *((uint32*)(inbuf)))); + tab_depth(depth), PTR_DIFF(inbuf,base),string, IVAL(inbuf, 0))); diff --git a/source/include/proto.h b/source/include/proto.h index 03c3eaf6a5f..5321eb4187e 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -100,6 +100,8 @@ void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, DOM_CHAL *cred); int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, UTIME timestamp); +BOOL srv_deal_with_creds(struct dcinfo *dc, DOM_CRED *clnt_cred, DOM_CRED *srv_cred); +BOOL clnt_deal_with_creds(struct dcinfo *dc, DOM_CRED *srv_cred, DOM_CRED *clnt_cred); /*The following definitions come from dir.c */ @@ -378,6 +380,9 @@ void make_q_req_chal(LSA_Q_REQ_CHAL *q_c, DOM_CHAL *clnt_chal); char* lsa_io_q_req_chal(BOOL io, LSA_Q_REQ_CHAL *q_c, char *q, char *base, int align, int depth); char* lsa_io_r_req_chal(BOOL io, LSA_R_REQ_CHAL *r_c, char *q, char *base, int align, int depth); +void make_q_auth_2(LSA_Q_AUTH_2 *q_a, + char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name, + DOM_CHAL *clnt_chal, uint32 clnt_flgs); char* lsa_io_q_auth_2(BOOL io, LSA_Q_AUTH_2 *q_a, char *q, char *base, int align, int depth); char* lsa_io_r_auth_2(BOOL io, LSA_R_AUTH_2 *r_a, char *q, char *base, int align, int depth); char* lsa_io_q_srv_pwset(BOOL io, LSA_Q_SRV_PWSET *q_s, char *q, char *base, int align, int depth); @@ -633,7 +638,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work, /*The following definitions come from ntclient.c */ -BOOL cli_lsa_req_chal(DOM_CHAL *srv_chal, char *desthost, char *myhostname, +BOOL do_nt_login(char *desthost, char *myhostname, int Client, int cnum); /*The following definitions come from params.c */ @@ -673,6 +678,7 @@ void pcap_printer_fn(void (*fn)()); /*The following definitions come from pipenetlog.c */ +BOOL get_md4pw(char *md4pw, char *mach_acct); BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, int mdrcnt,int mprcnt, char **rdata,char **rparam, @@ -884,6 +890,7 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); void E_md4hash(uchar *passwd, uchar *p16); void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); +void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]); /*The following definitions come from smbparse.c */ @@ -904,6 +911,8 @@ char* smb_io_dom_sid2(BOOL io, DOM_SID2 *sid2, char *q, char *base, int align, i void make_dom_rid2(DOM_RID2 *rid2, uint32 rid); char* smb_io_dom_rid2(BOOL io, DOM_RID2 *rid2, char *q, char *base, int align, int depth); char* smb_io_clnt_srv(BOOL io, DOM_CLNT_SRV *log, char *q, char *base, int align, int depth); +void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name, + uint16 sec_chan, char *comp_name); char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align, int depth); char* smb_io_chal(BOOL io, DOM_CHAL *chal, char *q, char *base, int align, int depth); char* smb_io_cred(BOOL io, DOM_CRED *cred, char *q, char *base, int align, int depth); @@ -1015,7 +1024,7 @@ char *ufc_crypt(char *key,char *salt); void init_uid(void); BOOL become_guest(void); -BOOL become_user(int cnum, uint16 vuid); +BOOL become_user(connection_struct *conn, int cnum, uint16 vuid); BOOL unbecome_user(void ); int smbrun(char *cmd,char *outfile,BOOL shared); void become_root(BOOL save_dir) ; diff --git a/source/include/smb.h b/source/include/smb.h index 83ed54c998f..b6b9d177a1b 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -550,7 +550,7 @@ typedef struct rpc_hdr_info uint32 alloc_hint; /* allocation hint - data size (bytes) minus header and tail. */ uint16 context_id; /* 0 - presentation context identifier */ uint8 cancel_count; /* 0 - cancel count */ - uint8 reserved; /* 0 - reserved */ + uint8 opnum; /* request: 0 - reserved. response: opnum */ } RPC_HDR; @@ -1185,8 +1185,8 @@ struct dcinfo { DOM_CHAL clnt_chal; /* Initial challenge received from client */ DOM_CHAL srv_chal; /* Initial server challenge */ - DOM_CHAL clnt_cred; /* Last client credential */ - DOM_CHAL srv_cred; /* Last server credential */ + DOM_CRED clnt_cred; /* Last client credential */ + DOM_CRED srv_cred; /* Last server credential */ uint32 sess_key[2]; /* Session key */ uchar md4pw[16]; /* md4(machine password) */ diff --git a/source/libsmb/credentials.c b/source/libsmb/credentials.c index ee7b1493e15..109a5a1b901 100644 --- a/source/libsmb/credentials.c +++ b/source/libsmb/credentials.c @@ -135,3 +135,110 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, } } + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL srv_deal_with_creds(struct dcinfo *dc, DOM_CRED *clnt_cred, DOM_CRED *srv_cred) +{ + UTIME new_clnt_time; + uint32 new_cred; + + DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + + /* check that the client credentials are valid */ + if (!cred_assert(&(clnt_cred->challenge), dc->sess_key, + &(dc->clnt_cred.challenge), clnt_cred->timestamp)) + { + return False; + } + + /* increment client time by one second */ + new_clnt_time.time = clnt_cred->timestamp.time + 1; + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(dc->clnt_cred.challenge.data, 0); + new_cred += new_clnt_time.time; + + DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred)); + + /* doesn't matter that server time is 0 */ + srv_cred->timestamp.time = 0; + + DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time)); + + /* create return credentials for inclusion in the reply */ + cred_create(dc->sess_key, &(dc->clnt_cred.challenge), new_clnt_time, + &(srv_cred->challenge)); + + DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n", + dc->clnt_cred.challenge.data[0])); + + /* store new seed in client and server credentials */ + SIVAL(dc->clnt_cred.challenge.data, 0, new_cred); + SIVAL(dc->srv_cred .challenge.data, 0, new_cred); + + return True; +} + + +#if 0 +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL clnt_deal_with_creds(struct dcinfo *dc, DOM_CRED *srv_cred, DOM_CRED *clnt_cred) +{ + UTIME new_clnt_time; + uint32 new_cred; + + DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + + /* setup new client time */ + dc->clnt_cred.timestamp.time = time(NULL); + + /* create sent credentials for inclusion in the reply */ + cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred); + + /* increment client time by one second */ + (dc->clnt_cred.timestamp.time)++; + + /* create expected return credentials to be received from server */ + cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred); + + + + /* check that the server credentials are valid */ + if (!cred_assert(&(srv_cred->challenge), dc->sess_key, + &(dc->clnt_cred), clnt_cred->timestamp)) + { + return False; + } + /* increment client time by one second */ + new_clnt_time = (dc->clnt_cred.timestamp.time += 1); + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(dc->clnt_cred.data, 0); + new_cred += new_clnt_time.time; + + DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred)); + + /* create new client credentials */ + cred_create(dc->sess_key, new_cred, new_clnt_time, clnt_cred); + + DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time)); + + /* create return credentials for inclusion in the reply + cred_create(dc->sess_key, srv_cred, new_clnt_time, + clnt_cred); + */ + DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n", + dc->clnt_cred.data[0])); + + /* store new seed in client and server credentials */ + SIVAL(dc->clnt_cred.data, 0, new_cred); + SIVAL(dc->srv_cred .data, 0, new_cred); + + return True; +} + +#endif diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c index 67e27016c31..9675401f146 100644 --- a/source/libsmb/smbdes.c +++ b/source/libsmb/smbdes.c @@ -329,7 +329,12 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; static unsigned char key2[8]; + int i; + for (i=0;i<8;i++) { + key2[i] = 0; + } + smbhash(buf, in, key); key2[0] = key[7]; smbhash(out, buf, key2); diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index 27172fd4136..517ee0f941f 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -109,3 +109,27 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) E_P24(p21, c8, p24); } +/* Does both the NT and LM owfs of a user's password */ + +void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]) +{ + char passwd[129]; + strncpy(passwd, pwd, 129); + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash((uchar *)passwd, nt_p16); + + /* Mangle the passwords into Lanman format */ + passwd[14] = '\0'; + strupper(passwd); + + /* Calculate the SMB (lanman) hash functions of the password */ + + memset(p16, '\0', 16); + E_P16((uchar *) passwd, p16); + + /* clear out local copy of user's password (just being paranoid). */ + bzero(passwd, sizeof(passwd)); +} + diff --git a/source/lsaparse.c b/source/lsaparse.c index 7b23f057f1f..eab20690133 100644 --- a/source/lsaparse.c +++ b/source/lsaparse.c @@ -298,6 +298,24 @@ char* lsa_io_r_req_chal(BOOL io, LSA_R_REQ_CHAL *r_c, char *q, char *base, int a /******************************************************************* reads or writes a structure. ********************************************************************/ +void make_q_auth_2(LSA_Q_AUTH_2 *q_a, + char *logon_srv, char *acct_name, uint16 sec_chan, char *comp_name, + DOM_CHAL *clnt_chal, uint32 clnt_flgs) +{ + if (q_a == NULL) return; + + DEBUG(5,("make_q_auth_2: %d\n", __LINE__)); + + make_log_info(&(q_a->clnt_id), logon_srv, acct_name, sec_chan, comp_name); + memcpy(q_a->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); + q_a->clnt_flgs.neg_flags = clnt_flgs; + + DEBUG(5,("make_q_auth_2: %d\n", __LINE__)); +} + +/******************************************************************* +reads or writes a structure. +********************************************************************/ char* lsa_io_q_auth_2(BOOL io, LSA_Q_AUTH_2 *q_a, char *q, char *base, int align, int depth) { if (q_a == NULL) return NULL; diff --git a/source/pipenetlog.c b/source/pipenetlog.c index 87337180c6a..30300dec3eb 100644 --- a/source/pipenetlog.c +++ b/source/pipenetlog.c @@ -46,14 +46,14 @@ static void make_lsa_r_req_chal(LSA_R_REQ_CHAL *r_c, } static int lsa_reply_req_chal(LSA_Q_REQ_CHAL *q_c, char *q, char *base, - DOM_CHAL *srv_chal) + DOM_CHAL *srv_chal, uint32 srv_time) { LSA_R_REQ_CHAL r_c; DEBUG(6,("lsa_reply_req_chal: %d\n", __LINE__)); /* set up the LSA REQUEST CHALLENGE response */ - make_lsa_r_req_chal(&r_c, srv_chal, 0); + make_lsa_r_req_chal(&r_c, srv_chal, srv_time); /* store the response in the SMB stream */ q = lsa_io_r_req_chal(False, &r_c, q, base, 4, 0); @@ -284,26 +284,23 @@ static int lsa_reply_sam_logoff(LSA_Q_SAM_LOGOFF *q_s, char *q, char *base, return PTR_DIFF(q, base); } - -static BOOL update_dcinfo(int cnum, uint16 vuid, - struct dcinfo *dc, DOM_CHAL *clnt_chal, char *mach_acct) +/**************************************************************************** + gets a machine password entry +****************************************************************************/ +BOOL get_md4pw(char *md4pw, char *mach_acct) { struct smb_passwd *smb_pass; - int i; - unbecome_user(); + become_root(True); smb_pass = get_smbpwnam(mach_acct); - if (!become_user(cnum, vuid)) - { - DEBUG(0,("update_dcinfo: become_user failed\n")); - return False; - } + unbecome_root(True); if (smb_pass != NULL) { - memcpy(dc->md4pw, smb_pass->smb_nt_passwd, sizeof(dc->md4pw)); - DEBUG(5,("dc->md4pw(%d) :", sizeof(dc->md4pw))); - dump_data(5, dc->md4pw, 16); + memcpy(md4pw, smb_pass->smb_nt_passwd, 16); + dump_data(5, md4pw, 16); + + return True; } else { @@ -312,32 +309,6 @@ static BOOL update_dcinfo(int cnum, uint16 vuid, DEBUG(1,("No account in domain for %s\n", mach_acct)); return False; } - - { - fstring foo; - for (i = 0; i < 16; i++) sprintf(foo+i*2,"%02x ", dc->md4pw[i]); - DEBUG(4,("pass %s %s\n", mach_acct, foo)); - } - - /* copy the client credentials */ - memcpy(dc->clnt_chal.data, clnt_chal->data, sizeof(clnt_chal->data)); - memcpy(dc->clnt_cred.data, clnt_chal->data, sizeof(clnt_chal->data)); - - /* create a server challenge for the client */ - /* PAXX: set these to random values. */ - /* lkcl: paul, you mentioned that it doesn't really matter much */ - dc->srv_chal.data[0] = 0x11111111; - dc->srv_chal.data[1] = 0x11111111; - dc->srv_cred.data[0] = 0x11111111; - dc->srv_cred.data[1] = 0x11111111; - - /* from client / server challenges and md4 password, generate sess key */ - cred_session_key(&(dc->clnt_chal), &(dc->srv_chal), - dc->md4pw, dc->sess_key); - - DEBUG(6,("update_dcinfo: %d\n", __LINE__)); - - return True; } static void api_lsa_req_chal( int cnum, uint16 vuid, @@ -360,11 +331,28 @@ static void api_lsa_req_chal( int cnum, uint16 vuid, DEBUG(6,("q_r.clnt_chal.data: %lx %lx\n", q_r.clnt_chal.data[0], q_r.clnt_chal.data[1])); - update_dcinfo(cnum, vuid, &(vuser->dc), &(q_r.clnt_chal), mach_acct); + if (get_md4pw(vuser->dc.md4pw, mach_acct)) + { + /* copy the client credentials */ + memcpy(vuser->dc.clnt_chal.data , q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data)); + memcpy(vuser->dc.clnt_cred.challenge.data, q_r.clnt_chal.data, sizeof(q_r.clnt_chal.data)); + + /* create a server challenge for the client */ + /* PAXX: set these to random values. */ + /* lkcl: paul, you mentioned that it doesn't really matter much */ + vuser->dc.srv_chal.data[0] = 0x11111111; + vuser->dc.srv_chal.data[1] = 0x11111111; + vuser->dc.srv_cred.challenge.data[0] = vuser->dc.srv_chal.data[0]; + vuser->dc.srv_cred.challenge.data[1] = vuser->dc.srv_chal.data[1]; + + /* from client / server challenges and md4 password, generate sess key */ + cred_session_key(&(vuser->dc.clnt_chal), &(vuser->dc.srv_chal), + vuser->dc.md4pw, vuser->dc.sess_key); + } /* construct reply. return status is always 0x0 */ *rdata_len = lsa_reply_req_chal(&q_r, *rdata + 0x18, *rdata, - &(vuser->dc.srv_chal)); + &(vuser->dc.srv_chal), 0); } @@ -384,14 +372,14 @@ static void api_lsa_auth_2( user_struct *vuser, /* check that the client credentials are valid */ cred_assert(&(q_a.clnt_chal), vuser->dc.sess_key, - &(vuser->dc.clnt_cred), srv_time); + &(vuser->dc.clnt_cred.challenge), srv_time); /* create server challenge for inclusion in the reply */ - cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred), srv_time, &srv_cred); + cred_create(vuser->dc.sess_key, &(vuser->dc.srv_cred.challenge), srv_time, &srv_cred); /* copy the received client credentials for use next time */ - memcpy(vuser->dc.clnt_cred.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data)); - memcpy(vuser->dc.srv_cred .data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data)); + memcpy(vuser->dc.clnt_cred.challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data)); + memcpy(vuser->dc.srv_cred .challenge.data, &(q_a.clnt_chal.data), sizeof(q_a.clnt_chal.data)); /* construct reply. */ *rdata_len = lsa_reply_auth_2(&q_a, *rdata + 0x18, *rdata, @@ -399,49 +387,6 @@ static void api_lsa_auth_2( user_struct *vuser, } -static BOOL deal_with_credentials(user_struct *vuser, - DOM_CRED *clnt_cred, DOM_CRED *srv_cred) -{ - UTIME new_clnt_time; - uint32 new_cred; - - DEBUG(5,("deal_with_credentials: %d\n", __LINE__)); - - /* increment client time by one second */ - new_clnt_time.time = clnt_cred->timestamp.time + 1; - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(vuser->dc.clnt_cred.data, 0); - new_cred += new_clnt_time.time; - - DEBUG(5,("deal_with_credentials: new_cred[0]=%lx\n", new_cred)); - - /* doesn't matter that server time is 0 */ - srv_cred->timestamp.time = 0; - - /* check that the client credentials are valid */ - if (!cred_assert(&(clnt_cred->challenge), vuser->dc.sess_key, - &(vuser->dc.clnt_cred), clnt_cred->timestamp)) - { - return False; - } - - DEBUG(5,("deal_with_credentials: new_clnt_time=%lx\n", new_clnt_time.time)); - - /* create server credentials for inclusion in the reply */ - cred_create(vuser->dc.sess_key, &(vuser->dc.clnt_cred), new_clnt_time, - &(srv_cred->challenge)); - - DEBUG(5,("deal_with_credentials: clnt_cred[0]=%lx\n", - vuser->dc.clnt_cred.data[0])); - - /* store new seed in client and server credentials */ - SIVAL(vuser->dc.clnt_cred.data, 0, new_cred); - SIVAL(vuser->dc.srv_cred .data, 0, new_cred); - - return True; -} - static void api_lsa_srv_pwset( user_struct *vuser, char *param, char *data, char **rdata, int *rdata_len ) @@ -454,7 +399,7 @@ static void api_lsa_srv_pwset( user_struct *vuser, lsa_io_q_srv_pwset(True, &q_a, data + 0x18, data, 4, 0); /* checks and updates credentials. creates reply credentials */ - deal_with_credentials(vuser, &(q_a.clnt_id.cred), &srv_cred); + srv_deal_with_creds(&(vuser->dc), &(q_a.clnt_id.cred), &srv_cred); DEBUG(5,("api_lsa_srv_pwset: %d\n", __LINE__)); @@ -477,7 +422,7 @@ static void api_lsa_sam_logoff( user_struct *vuser, lsa_io_q_sam_logoff(True, &q_l, data + 0x18, data, 4, 0); /* checks and updates credentials. creates reply credentials */ - deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_cred); + srv_deal_with_creds(&(vuser->dc), &(q_l.sam_id.client.cred), &srv_cred); /* construct reply. always indicate success */ *rdata_len = lsa_reply_sam_logoff(&q_l, *rdata + 0x18, *rdata, @@ -498,7 +443,7 @@ static void api_lsa_sam_logon( user_struct *vuser, lsa_io_q_sam_logon(True, &q_l, data + 0x18, data, 4, 0); /* checks and updates credentials. creates reply credentials */ - deal_with_credentials(vuser, &(q_l.sam_id.client.cred), &srv_creds); + srv_deal_with_creds(&(vuser->dc), &(q_l.sam_id.client.cred), &srv_creds); usr_info.ptr_user_info = 0; @@ -645,13 +590,13 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, return True; } - DEBUG(4,("netlogon TransactNamedPipe op %x\n",hdr.reserved)); + DEBUG(4,("netlogon TransactNamedPipe op %x\n",hdr.opnum)); if ((vuser = get_valid_user_struct(uid)) == NULL) return False; DEBUG(3,("Username of UID %d is %s\n", vuser->uid, vuser->name)); - switch (hdr.reserved) + switch (hdr.opnum) { case LSA_REQCHAL: { @@ -695,7 +640,7 @@ BOOL api_netlogrpcTNP(int cnum,int uid, char *param,char *data, default: { - DEBUG(4, ("**** netlogon, unknown code: %lx\n", hdr.reserved)); + DEBUG(4, ("**** netlogon, unknown code: %lx\n", hdr.opnum)); break; } } diff --git a/source/pipentlsa.c b/source/pipentlsa.c index 9fe60588095..05c61942634 100644 --- a/source/pipentlsa.c +++ b/source/pipentlsa.c @@ -317,9 +317,9 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, return True; } - DEBUG(4,("lsarpc TransactNamedPipe op %x\n",hdr.reserved)); + DEBUG(4,("lsarpc TransactNamedPipe op %x\n",hdr.opnum)); - switch (hdr.reserved) + switch (hdr.opnum) { case LSA_OPENPOLICY: { @@ -416,7 +416,7 @@ BOOL api_ntLsarpcTNP(int cnum,int uid, char *param,char *data, default: { - DEBUG(4, ("NTLSARPC, unknown code: %lx\n", hdr.reserved)); + DEBUG(4, ("NTLSARPC, unknown code: %lx\n", hdr.opnum)); break; } } diff --git a/source/pipesrvsvc.c b/source/pipesrvsvc.c index ee50f00b110..2e578ada10e 100644 --- a/source/pipesrvsvc.c +++ b/source/pipesrvsvc.c @@ -205,9 +205,9 @@ BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data, return True; } - DEBUG(4,("srvsvc TransactNamedPipe op %x\n",hdr.reserved)); + DEBUG(4,("srvsvc TransactNamedPipe op %x\n",hdr.opnum)); - switch (hdr.reserved) + switch (hdr.opnum) { case NETSHAREENUM: { @@ -261,7 +261,7 @@ BOOL api_srvsvcTNP(int cnum,int uid, char *param,char *data, default: { - DEBUG(4, ("srvsvc, unknown code: %lx\n", hdr.reserved)); + DEBUG(4, ("srvsvc, unknown code: %lx\n", hdr.opnum)); break; } } diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 61b282fd420..9c9c183a148 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -1606,11 +1606,12 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, if (Files[i].open && Files[i].print_file) { pstring wd; + int fcnum = Files[i].cnum; GetWd(wd); unbecome_user(); - if (!become_user(Files[i].cnum,vuid) || - !become_service(Files[i].cnum,True)) + if (!become_user(&Connections[fcnum], fcnum,vuid) || + !become_service(fcnum,True)) break; if (sys_rename(Files[i].name,name) == 0) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 3643b6eed0d..22c22ccc556 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -2614,7 +2614,7 @@ int reply_printqueue(char *inbuf,char *outbuf) DEBUG(5,("connection not open or not a printer, using cnum %d\n",cnum)); } - if (!become_user(cnum,vuid)) + if (!become_user(&Connections[cnum], cnum, vuid)) return(ERROR(ERRSRV,ERRinvnid)); { diff --git a/source/smbd/server.c b/source/smbd/server.c index 20c1a1c1b78..9b428df44ce 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -94,7 +94,7 @@ BOOL global_oplock_break = False; extern fstring remote_machine; -pstring OriginalDir; +extern pstring OriginalDir; /* these can be set by some functions to override the error codes */ int unix_ERR_class=SUCCESS; @@ -3462,7 +3462,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de smbrun(cmd,NULL,False); } - if (!become_user(cnum,pcon->vuid)) + if (!become_user(&Connections[cnum], cnum,pcon->vuid)) { DEBUG(0,("Can't become connected user!\n")); pcon->open = False; @@ -4019,7 +4019,7 @@ void close_cnum(int cnum, uint16 vuid) dptr_closecnum(cnum); /* execute any "postexec = " line */ - if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid)) + if (*lp_postexec(SNUM(cnum)) && become_user(&Connections[cnum], cnum,vuid)) { pstring cmd; strcpy(cmd,lp_postexec(SNUM(cnum))); @@ -4542,7 +4542,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize unbecome_user(); /* does this protocol need to be run as the connected user? */ - if ((flags & AS_USER) && !become_user(cnum,session_tag)) { + if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) { if (flags & AS_GUEST) flags &= ~AS_USER; else diff --git a/source/smbd/uid.c b/source/smbd/uid.c index 28bf4b421ac..645d078979c 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -23,15 +23,13 @@ extern int DEBUGLEVEL; -extern connection_struct Connections[]; - static int initial_uid; static int initial_gid; /* what user is current? */ struct current_user current_user; -extern pstring OriginalDir; +pstring OriginalDir; /**************************************************************************** initialise the uid routines @@ -183,19 +181,19 @@ BOOL become_guest(void) /******************************************************************* check if a username is OK ********************************************************************/ -static BOOL check_user_ok(int cnum,user_struct *vuser,int snum) +static BOOL check_user_ok(connection_struct *conn, user_struct *vuser,int snum) { int i; - for (i=0;i<Connections[cnum].uid_cache.entries;i++) - if (Connections[cnum].uid_cache.list[i] == vuser->uid) return(True); + for (i=0;i<conn->uid_cache.entries;i++) + if (conn->uid_cache.list[i] == vuser->uid) return(True); if (!user_ok(vuser->name,snum)) return(False); - i = Connections[cnum].uid_cache.entries % UID_CACHE_SIZE; - Connections[cnum].uid_cache.list[i] = vuser->uid; + i = conn->uid_cache.entries % UID_CACHE_SIZE; + conn->uid_cache.list[i] = vuser->uid; - if (Connections[cnum].uid_cache.entries < UID_CACHE_SIZE) - Connections[cnum].uid_cache.entries++; + if (conn->uid_cache.entries < UID_CACHE_SIZE) + conn->uid_cache.entries++; return(True); } @@ -204,7 +202,7 @@ static BOOL check_user_ok(int cnum,user_struct *vuser,int snum) /**************************************************************************** become the user of a connection number ****************************************************************************/ -BOOL become_user(int cnum, uint16 vuid) +BOOL become_user(connection_struct *conn, int cnum, uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); int snum,gid; @@ -217,23 +215,23 @@ BOOL become_user(int cnum, uint16 vuid) unbecome_user(); - if (!OPEN_CNUM(cnum)) { + if (!(VALID_CNUM(cnum) && conn->open)) { DEBUG(2,("Connection %d not open\n",cnum)); return(False); } - snum = Connections[cnum].service; + snum = conn->service; - if (Connections[cnum].force_user || + if (conn->force_user || lp_security() == SEC_SHARE || !(vuser) || (vuser->guest) || - !check_user_ok(cnum,vuser,snum)) + !check_user_ok(conn, vuser, snum)) { - uid = Connections[cnum].uid; - gid = Connections[cnum].gid; - current_user.groups = Connections[cnum].groups; - current_user.igroups = Connections[cnum].igroups; - current_user.ngroups = Connections[cnum].ngroups; + uid = conn->uid; + gid = conn->gid; + current_user.groups = conn->groups; + current_user.igroups = conn->igroups; + current_user.ngroups = conn->ngroups; current_user.attrs = vuser->attrs; } else @@ -246,7 +244,7 @@ BOOL become_user(int cnum, uint16 vuid) if(!*lp_force_group(snum)) gid = vuser->gid; else - gid = Connections[cnum].gid; + gid = conn->gid; current_user.ngroups = vuser->n_groups; current_user.groups = vuser->groups; current_user.igroups = vuser->igroups; @@ -258,7 +256,7 @@ BOOL become_user(int cnum, uint16 vuid) if (!become_gid(gid)) return(False); #ifndef NO_SETGROUPS - if (!IS_IPC(cnum)) { + if (!(VALID_CNUM(cnum) && conn->ipc)) { /* groups stuff added by ih/wreu */ if (current_user.ngroups > 0) if (setgroups(current_user.ngroups,current_user.groups)<0) @@ -266,7 +264,7 @@ BOOL become_user(int cnum, uint16 vuid) } #endif - if (!Connections[cnum].admin_user && !become_uid(uid)) + if (!conn->admin_user && !become_uid(uid)) return(False); } diff --git a/source/smbparse.c b/source/smbparse.c index 1cafef80969..175534e3c80 100644 --- a/source/smbparse.c +++ b/source/smbparse.c @@ -382,6 +382,26 @@ char* smb_io_clnt_srv(BOOL io, DOM_CLNT_SRV *log, char *q, char *base, int align } /******************************************************************* +makes a DOM_LOG_INFO structure. +********************************************************************/ +void make_log_info(DOM_LOG_INFO *log, char *logon_srv, char *acct_name, + uint16 sec_chan, char *comp_name) +{ + if (log == NULL) return; + + DEBUG(5,("make_log_info %d\n", __LINE__)); + + log->undoc_buffer = 1; + + make_unistr2(&(log->uni_logon_srv), logon_srv, strlen(logon_srv)); + make_unistr2(&(log->uni_acct_name), acct_name, strlen(acct_name)); + + log->sec_chan = sec_chan; + + make_unistr2(&(log->uni_comp_name), comp_name, strlen(comp_name)); +} + +/******************************************************************* reads or writes a DOM_LOG_INFO structure. ********************************************************************/ char* smb_io_log_info(BOOL io, DOM_LOG_INFO *log, char *q, char *base, int align, int depth) @@ -626,8 +646,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; /* reply: cancel count. request: opnum */ - hdr->reserved = 0; /* reserved */ + hdr->cancel_count = 0; /* cancel count */ + hdr->opnum = opnum; /* opnum */ } /******************************************************************* @@ -651,7 +671,7 @@ char* smb_io_rpc_hdr(BOOL io, RPC_HDR *rpc, char *q, char *base, int align, int DBG_RW_IVAL("alloc_hint", depth, base, io, q, rpc->alloc_hint); q += 4; DBG_RW_CVAL("context_id", depth, base, io, q, rpc->context_id); q++; DBG_RW_CVAL("cancel_ct ", depth, base, io, q, rpc->cancel_count); q++; - DBG_RW_CVAL("reserved ", depth, base, io, q, rpc->reserved); q++; + DBG_RW_CVAL("opnum ", depth, base, io, q, rpc->opnum); q++; return q; } |