From 390c1f3c4d3136b454fa5eb8681fa9ca34eaacc2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 25 Oct 1997 10:58:18 +0000 Subject: Makefile : adding bits for new nt domain code byteorder.h : trying to get macros right, and not to crash on SUNOS5... client.c : added #ifdef NTDOMAIN, and created do_nt_login() function. don't want to have to recompile client.c unless absolutely necessary. credentials.c : moved deal_with_creds() [possibly inappropriately] into credentials.c ipc.c reply.c server.c uid.c : attempting to make (un)become_root() functions calleable from smbclient. this is a little tricky: smbclient might have to be another setuid root program, immediately setuid'ing to non-root, so that we can reset-uid to root to get at the smbpasswd file. or, have a secure pipe mechanism to smbd to grab smbpasswd entries. or the like. smbdes.c smbencrypt.c : created a function to generate lm and nt owf hashes. lsaparse.c ntclient.c smbparse.c : added nt client LSA_AUTH2 code. it works, too! pipenetlog.c pipentlsa.c pipesrvsvc.c : simplification. code-shuffling. getting that damn offset right for the opcode in RPC_HDR. smb.h : changed dcinfo xxx_creds to DOM_CRED structures instead of DOM_CHAL. we might need to store the server times as well. proto.h : the usual. (This used to be commit 82436a3d99d4bdce249ce9ff27fd2ca4b2447e07) --- source3/client/client.c | 16 +-- source3/client/ntclient.c | 272 +++++++++++++++++++++++++++++++++++++--------- 2 files changed, 228 insertions(+), 60 deletions(-) (limited to 'source3/client') diff --git a/source3/client/client.c b/source3/client/client.c index 5dbb2f3b1c..68cd930cf9 100644 --- a/source3/client/client.c +++ b/source3/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/source3/client/ntclient.c b/source3/client/ntclient.c index decc2e34d6..9fa64bd2ef 100644 --- a/source3/client/ntclient.c +++ b/source3/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 -- cgit