diff options
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/include/ntdomain.h | 5 | ||||
-rw-r--r-- | source3/include/proto.h | 32 | ||||
-rw-r--r-- | source3/include/rpc_dce.h | 87 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 24 | ||||
-rw-r--r-- | source3/rpc_parse/parse_prs.c | 4 | ||||
-rw-r--r-- | source3/rpc_parse/parse_rpc.c | 188 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 80 |
8 files changed, 303 insertions, 119 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index b54ac098e0..e70f3be533 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -89,7 +89,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \ lib/membuffer.o lib/netmask.o lib/pidfile.o lib/replace.o \ lib/signal.o lib/slprintf.o lib/system.o lib/time.o lib/ufc.o \ lib/util.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \ - lib/bitmap.o + lib/bitmap.o lib/crc32.o UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \ ubiqx/ubi_dLinkList.o ubiqx/ubi_sLinkList.o diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 8362dcb73f..5fb7f8a089 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -67,6 +67,7 @@ typedef struct pipes_struct prs_struct rhdr; /* output header */ prs_struct rdata; /* output data */ prs_struct rauth; /* output authentication verifier */ + prs_struct rntlm; /* output ntlmssp */ RPC_HDR hdr; RPC_HDR_BA hdr_ba; @@ -74,7 +75,9 @@ typedef struct pipes_struct RPC_HDR_REQ hdr_req; RPC_HDR_RESP hdr_resp; - RPC_AUTH_NTLMSSP_REQ ntlmssp_req; + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; + RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal; RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; uint32 file_offset; diff --git a/source3/include/proto.h b/source3/include/proto.h index 19aa51a1b7..e5b6c0b08e 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -70,6 +70,11 @@ void charset_initialise(void); void codepage_initialise(int client_codepage); void add_char_string(char *s); +/*The following definitions come from lib/crc32.c */ + +void crc32_build_table(void); +uint32 crc32_calc_buffer( uint32 count, uchar *buffer); + /*The following definitions come from lib/debug.c */ void sig_usr2( int sig ); @@ -1495,7 +1500,7 @@ BOOL prs_uninotstr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNINOT BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str); BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str); BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str); -BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len); +BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size); /*The following definitions come from rpc_parse/parse_reg.c */ @@ -1533,15 +1538,23 @@ void smb_io_rpc_hdr_ba(char *desc, RPC_HDR_BA *rpc, prs_struct *ps, int depth); void make_rpc_hdr_req(RPC_HDR_REQ *hdr, uint32 data_len, uint16 opnum); void smb_io_rpc_hdr_req(char *desc, RPC_HDR_REQ *rpc, prs_struct *ps, int depth); void smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int depth); -void make_rpc_auth_ntlmssp_req(RPC_AUTH_NTLMSSP_REQ *req, - fstring ntlmssp_str, uint32 ntlmssp_ver, - uint32 unknown_0, fstring myname, fstring domain); -void smb_io_rpc_auth_ntlmssp_req(char *desc, RPC_AUTH_NTLMSSP_REQ *req, prs_struct *ps, int depth); +void make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg, + uint32 neg_flgs, + fstring myname, fstring domain); +void smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth); +void make_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav, + uint8 auth_type, uint8 auth_level, + uint8 stub_type_len, + char *signature, uint32 msg_type); +void smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth); +void make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl, + uint32 neg_flags, + uint8 challenge[8]); +void smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth); void make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp, - uint8 auth_type, uint8 auth_level, uint8 stub_type_len, - fstring ntlmssp_str, uint32 ntlmssp_ver, - uint32 unknown_1, uint32 unknown_2, uint32 unknown_3, - uint8 data[16]); + uchar lm_resp[24], uchar nt_resp[24], + char *domain, char *user, char *wks, + uint32 neg_flags); void smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_struct *ps, int depth); /*The following definitions come from rpc_parse/parse_samr.c */ @@ -2318,6 +2331,7 @@ int smbw_chmod(const char *fname, mode_t newmode); off_t smbw_lseek(int fd, off_t offset, int whence); int smbw_dup(int fd); int smbw_dup2(int fd, int fd2); +int smbw_fork(void); /*The following definitions come from smbwrapper/smbw_dir.c */ diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index 2e3995e43d..31964d4f37 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -41,6 +41,28 @@ enum RPC_PKT_TYPE #define RPC_FLG_FIRST 0x01 #define RPC_FLG_LAST 0x02 +/* NTLMSSP message types */ +enum NTLM_MESSAGE_TYPE +{ + NTLMSSP_NEGOTIATE = 1, + NTLMSSP_CHALLENGE = 2, + NTLMSSP_AUTH = 3, + NTLMSSP_UNKNOWN = 4, +}; + +/* NTLMSSP negotiation flags */ +#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 +#define NTLMSSP_NEGOTIATE_OEM 0x00000002 +#define NTLMSSP_REQUEST_TARGET 0x00000004 +#define NTLMSSP_NEGOTIATE_SIGN 0x00000010 +#define NTLMSSP_NEGOTIATE_SEAL 0x00000020 +#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 +#define NTLMSSP_NEGOTIATE_NTLM 0x00000200 +#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 +#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000 +#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 +#define NTLMSSP_NEGOTIATE_128 0x20000000 +#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 /* RPC_IFACE */ typedef struct rpc_iface_info @@ -161,57 +183,76 @@ typedef struct rpc_hdr_ba_info /* RPC_AUTH_VERIFIER */ typedef struct rpc_auth_verif_info { - fstring ssp_str; - uint32 ssp_ver; + uint8 auth_type; /* 0x0a */ + uint8 auth_level; /* 0x06 */ + uint8 stub_type_len; /* don't know */ + uint8 padding; /* padding */ + + uint32 ptr_0; /* non-zero pointer to something */ + + fstring signature; /* "NTLMSSP" */ + uint32 msg_type; /* NTLMSSP_MESSAGE_TYPE (1,2,3) */ } RPC_AUTH_VERIFIER; /* this is TEMPORARILY coded up as a specific structure */ /* this structure comes after the bind request */ -/* RPC_AUTH_NTLMSSP_REQ */ -typedef struct rpc_auth_ntlmssp_req_info +/* RPC_AUTH_NTLMSSP_NEG */ +typedef struct rpc_auth_ntlmssp_neg_info { - fstring ntlmssp_str; /* "NTLMSSP" */ - uint32 ntlmssp_ver; /* 0x0000 0001 */ + uint32 neg_flgs; /* 0x0000 b2b3 */ - uint32 unknown_0; /* 0x00b2b3 */ STRHDR hdr_myname; /* offset is against START of this structure */ STRHDR hdr_domain; /* offset is against START of this structure */ fstring myname; /* calling workstation's name */ fstring domain; /* calling workstations's domain */ -} RPC_AUTH_NTLMSSP_REQ; +} RPC_AUTH_NTLMSSP_NEG; /* this is TEMPORARILY coded up as a specific structure */ /* this structure comes after the bind acknowledgement */ -/* RPC_AUTH_NTLMSSP_RESP */ -typedef struct rpc_auth_ntlmssp_resp_info +/* RPC_AUTH_NTLMSSP_CHAL */ +typedef struct rpc_auth_ntlmssp_chal_info { - uint8 auth_type; /* 0x0a */ - uint8 auth_level; /* 0x06 */ - uint8 stub_type_len; /* don't know */ - uint8 padding; /* padding */ + uint32 unknown_1; /* 0x0000 0000 */ + uint32 unknown_2; /* 0x0000 0028 */ + uint32 neg_flags; /* 0x0000 82b1 */ - uint32 ptr_0; /* non-zero pointer to something */ + uint8 challenge[8]; /* ntlm challenge */ + uint8 reserved [8]; /* zeros */ - fstring ntlmssp_str; /* "NTLMSSP" */ - uint32 ntlmssp_ver; /* 0x0000 0002 */ +} RPC_AUTH_NTLMSSP_CHAL; - uint32 unknown_1; /* 0x0000 0000 */ - uint32 unknown_2; /* 0x00b2b3 */ - uint32 unknown_3; /* 0x0082b1 */ - uint8 data[16]; /* 0x10 bytes of something */ +/* RPC_AUTH_NTLMSSP_RESP */ +typedef struct rpc_auth_ntlmssp_resp_info +{ + STRHDR hdr_lm_resp; /* 24 byte response */ + STRHDR hdr_nt_resp; /* 24 byte response */ + STRHDR hdr_domain; + UNIHDR hdr_usr; + UNIHDR hdr_wks; + UNIHDR hdr_sess_key; /* NULL unless negotiated */ + uint32 neg_flags; /* 0x0000 82b1 */ + + fstring uni_sess_key; + fstring uni_wks; + fstring uni_usr; + fstring uni_domain; + fstring str_nt_resp; + fstring str_lm_resp; } RPC_AUTH_NTLMSSP_RESP; + /* attached to the end of encrypted rpc requests and responses */ /* RPC_AUTH_NTLMSSP_CHK */ typedef struct rpc_auth_ntlmssp_chk_info { - uint32 ver; /* 0x1 */ - uint8 data[12]; + uint32 ver; /* 0x0000 0001 */ + uint8 crc32[8]; /* checksum using 0xEDB8 8320 as a polynomial */ + uint32 seq_num; } RPC_AUTH_NTLMSSP_CHK; diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 0258c1a0e7..392877f2dc 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -293,9 +293,10 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, RPC_IFACE *abstract, RPC_IFACE *transfer, char *my_name, char *domain) { - RPC_HDR_RB hdr_rb; - RPC_HDR hdr; - RPC_AUTH_NTLMSSP_REQ ntlmssp_req; + RPC_HDR_RB hdr_rb; + RPC_HDR hdr; + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; /* create the bind request RPC_HDR_RB */ make_rpc_hdr_rb(&hdr_rb, 0x1630, 0x1630, 0x0, @@ -307,12 +308,17 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr, if (auth_req != NULL) { - /* - * I have a feeling this is broken right now... JRA. - */ - make_rpc_auth_ntlmssp_req(&ntlmssp_req, "NTLMSSP", 0x1, - 0x0000b2b3, my_name, domain); - smb_io_rpc_auth_ntlmssp_req("", &ntlmssp_req, auth_req, 0); + make_rpc_auth_verifier(&auth_verifier, + 0x0a, 0x06, 0x00, + "NTLMSSP", NTLMSSP_NEGOTIATE); + + smb_io_rpc_auth_verifier("auth_verifier", &auth_verifier, auth_req, 0); + mem_realloc_data(auth_req->data, auth_req->offset); + + make_rpc_auth_ntlmssp_neg(&ntlmssp_neg, + 0x0000b2b3, my_name, domain); + + smb_io_rpc_auth_ntlmssp_neg("ntlmssp_neg", &ntlmssp_neg, auth_req, 0); mem_realloc_data(auth_req->data, auth_req->offset); } diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 024ac88b18..f166bbd704 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -241,7 +241,7 @@ BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str) (up to max size of pstring - 1024 chars). ********************************************************************/ -BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len) +BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len, uint16 max_buf_size) { char *q = mem_data(&(ps->data), ps->offset); uint8 *start = (uint8*)q; @@ -265,7 +265,7 @@ BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, uint16 len) q++; - } while (i < sizeof(pstring) && (len == 0 ? str[i] != 0 : i < len) ); + } while (i < max_buf_size && (len == 0 ? str[i] != 0 : i < len) ); ps->offset += i+1; diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index ac01e7f0b1..2e7b950810 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -416,75 +416,155 @@ void smb_io_rpc_hdr_resp(char *desc, RPC_HDR_RESP *rpc, prs_struct *ps, int dep } /******************************************************************* -creates an RPC_AUTH_NTLMSSP_REQ structure. +creates an RPC_AUTH_NTLMSSP_NEG structure. ********************************************************************/ -void make_rpc_auth_ntlmssp_req(RPC_AUTH_NTLMSSP_REQ *req, - fstring ntlmssp_str, uint32 ntlmssp_ver, - uint32 unknown_0, fstring myname, fstring domain) +void make_rpc_auth_ntlmssp_neg(RPC_AUTH_NTLMSSP_NEG *neg, + uint32 neg_flgs, + fstring myname, fstring domain) { int len_myname = strlen(myname); int len_domain = strlen(domain); - if (req == NULL) return; + if (neg == NULL) return; - fstrcpy(req->ntlmssp_str, ntlmssp_str); /* "NTLMSSP" */ - req->ntlmssp_ver = ntlmssp_ver; /* 0x0000 0001 */ + neg->neg_flgs = neg_flgs ; /* 0x00b2b3 */ - req->unknown_0 = unknown_0 ; /* 0x00b2b3 */ - make_str_hdr(&req->hdr_myname, len_myname, len_myname, 1); - make_str_hdr(&req->hdr_domain, len_domain, len_domain, 1); + make_str_hdr(&neg->hdr_myname, len_myname, len_myname, 1); + make_str_hdr(&neg->hdr_domain, len_domain, len_domain, 1); - fstrcpy(req->myname, myname); - fstrcpy(req->domain, domain); + fstrcpy(neg->myname, myname); + fstrcpy(neg->domain, domain); } /******************************************************************* -reads or writes an RPC_AUTH_NTLMSSP_REQ structure. +reads or writes an RPC_AUTH_NTLMSSP_NEG structure. ********************************************************************/ -void smb_io_rpc_auth_ntlmssp_req(char *desc, RPC_AUTH_NTLMSSP_REQ *req, prs_struct *ps, int depth) +void smb_io_rpc_auth_ntlmssp_neg(char *desc, RPC_AUTH_NTLMSSP_NEG *neg, prs_struct *ps, int depth) { - if (req == NULL) return; + if (neg == NULL) return; - prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_req"); + prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_neg"); depth++; - prs_string("ntlmssp_str", ps, depth, req->ntlmssp_str, 0); /* "NTLMSSP" */ - prs_uint32("ntlmssp_ver", ps, depth, &(req->ntlmssp_ver )); + prs_uint32("neg_flgs ", ps, depth, &(neg->neg_flgs)); - prs_uint32("unknown_0 ", ps, depth, &(req->unknown_0 )); - smb_io_strhdr("hdr_myname", &(req->hdr_myname), ps, depth); - smb_io_strhdr("hdr_domain", &(req->hdr_domain), ps, depth); + smb_io_strhdr("hdr_myname", &(neg->hdr_myname), ps, depth); + smb_io_strhdr("hdr_domain", &(neg->hdr_domain), ps, depth); - prs_string("myname", ps, depth, req->myname, req->hdr_myname.str_str_len); - prs_string("domain", ps, depth, req->domain, req->hdr_domain.str_str_len); + prs_string("myname", ps, depth, neg->myname, neg->hdr_myname.str_str_len, sizeof(neg->myname)); + prs_string("domain", ps, depth, neg->domain, neg->hdr_domain.str_str_len, sizeof(neg->domain)); +} + +/******************************************************************* +creates an RPC_AUTH_VERIFIER structure. +********************************************************************/ +void make_rpc_auth_verifier(RPC_AUTH_VERIFIER *rav, + uint8 auth_type, uint8 auth_level, + uint8 stub_type_len, + char *signature, uint32 msg_type) +{ + if (rav == NULL) return; + + rav->auth_type = auth_type; /* nt lm ssp 0x0a */ + rav->auth_level = auth_level; /* 0x06 */ + rav->stub_type_len = stub_type_len; /* 0x00 */ + rav->padding = 0; /* padding 0x00 */ + + rav->ptr_0 = 1; /* non-zero pointer to something */ + + fstrcpy(rav->signature, signature); /* "NTLMSSP" */ + rav->msg_type = msg_type; /* NTLMSSP_MESSAGE_TYPE */ +} + +/******************************************************************* +reads or writes an RPC_AUTH_VERIFIER structure. +********************************************************************/ +void smb_io_rpc_auth_verifier(char *desc, RPC_AUTH_VERIFIER *rav, prs_struct *ps, int depth) +{ + if (rav == NULL) return; + + prs_debug(ps, depth, desc, "smb_io_rpc_auth_verifier"); + depth++; + + prs_uint8("auth_type ", ps, depth, &(rav->auth_type)); /* nt lm ssp 0x0a */ + prs_uint8("auth_level ", ps, depth, &(rav->auth_level));/* 0x06 */ + prs_uint8("stub_type_len", ps, depth, &(rav->stub_type_len)); + prs_uint8("padding ", ps, depth, &(rav->padding)); + + prs_uint32("ptr_0", ps, depth, &(rav->ptr_0 )); /* non-zero pointer to something */ + + prs_string("signature", ps, depth, rav->signature, 0, sizeof(rav->signature)); /* "NTLMSSP" */ + prs_uint32("msg_type ", ps, depth, &(rav->msg_type )); /* NTLMSSP_MESSAGE_TYPE */ +} + +/******************************************************************* +creates an RPC_AUTH_NTLMSSP_CHAL structure. +********************************************************************/ +void make_rpc_auth_ntlmssp_chal(RPC_AUTH_NTLMSSP_CHAL *chl, + uint32 neg_flags, + uint8 challenge[8]) +{ + if (chl == NULL) return; + + chl->unknown_1 = 0x0; + chl->unknown_2 = 0x00000028; + chl->neg_flags = neg_flags; /* 0x0082b1 */ + + memcpy(chl->challenge, challenge, sizeof(chl->challenge)); + bzero (chl->reserved , sizeof(chl->reserved)); +} + +/******************************************************************* +reads or writes an RPC_AUTH_NTLMSSP_CHAL structure. +********************************************************************/ +void smb_io_rpc_auth_ntlmssp_chal(char *desc, RPC_AUTH_NTLMSSP_CHAL *chl, prs_struct *ps, int depth) +{ + if (chl == NULL) return; + + prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_chal"); + depth++; + + prs_uint32("unknown_1", ps, depth, &(chl->unknown_1)); /* 0x0000 0000 */ + prs_uint32("unknown_2", ps, depth, &(chl->unknown_2)); /* 0x0000 b2b3 */ + prs_uint32("neg_flags", ps, depth, &(chl->neg_flags)); /* 0x0000 82b1 */ + + prs_uint8s (False, "challenge", ps, depth, chl->challenge, sizeof(chl->challenge)); + prs_uint8s (False, "reserved ", ps, depth, chl->reserved , sizeof(chl->reserved )); } /******************************************************************* creates an RPC_AUTH_NTLMSSP_RESP structure. ********************************************************************/ void make_rpc_auth_ntlmssp_resp(RPC_AUTH_NTLMSSP_RESP *rsp, - uint8 auth_type, uint8 auth_level, uint8 stub_type_len, - fstring ntlmssp_str, uint32 ntlmssp_ver, - uint32 unknown_1, uint32 unknown_2, uint32 unknown_3, - uint8 data[16]) + uchar lm_resp[24], uchar nt_resp[24], + char *domain, char *user, char *wks, + uint32 neg_flags) { - if (rsp == NULL) return; + int dom_len = strlen(domain) * 2; + int wks_len = strlen(wks ) * 2; + int usr_len = strlen(user ) * 2; + int lm_len = lm_resp != NULL ? 24 : 0; + int nt_len = nt_resp != NULL ? 24 : 0; - rsp->auth_type = auth_type; /* nt lm ssp 0x0a */ - rsp->auth_level = auth_level; /* 0x06 */ - rsp->stub_type_len = stub_type_len; /* dunno. */ - rsp->padding = 0; /* padding */ + if (rsp == NULL) return; - rsp->ptr_0 = 1; /* non-zero pointer to something */ + make_str_hdr(&rsp->hdr_lm_resp, lm_len, lm_len, 1); + make_str_hdr(&rsp->hdr_nt_resp, nt_len, nt_len, 1); + make_str_hdr(&rsp->hdr_domain , dom_len, dom_len, 1); + make_str_hdr(&rsp->hdr_usr , usr_len, usr_len, 1); + make_str_hdr(&rsp->hdr_wks , wks_len, wks_len, 1); + make_str_hdr(&rsp->hdr_sess_key, 0, 0, 1); - fstrcpy(rsp->ntlmssp_str, ntlmssp_str); /* "NTLMSSP" */ - rsp->ntlmssp_ver = ntlmssp_ver; /* 0x0000 0002 */ + rsp->neg_flags = neg_flags; - rsp->unknown_1 = unknown_1; /* 0x0000 0000 */ - rsp->unknown_2 = unknown_2; /* 0x00b2b3 */ - rsp->unknown_3 = unknown_3; /* 0x0082b1 */ + memcpy(&rsp->lm_resp, lm_resp, 24); + memcpy(&rsp->nt_resp, nt_resp, 24); + fstrcpy(rsp->domain, domain); + fstrcpy(rsp->user , user ); + fstrcpy(rsp->wks , wks ); + rsp->sess_key[0] = 0; - memcpy(rsp->data, data, sizeof(rsp->data)); /* 0x10 bytes of something, 8 of which are zeros */ + } /******************************************************************* @@ -497,21 +577,21 @@ void smb_io_rpc_auth_ntlmssp_resp(char *desc, RPC_AUTH_NTLMSSP_RESP *rsp, prs_st prs_debug(ps, depth, desc, "smb_io_rpc_auth_ntlmssp_resp"); depth++; - prs_uint8("auth_type", ps, depth, &(rsp->auth_type)); /* nt lm ssp 0x0a */ - prs_uint8("auth_level", ps, depth, &(rsp->auth_level));/* 0x06 */ - prs_uint8("stub_type_len", ps, depth, &(rsp->stub_type_len)); - prs_uint8("padding", ps, depth, &(rsp->padding)); - - prs_uint32("ptr_0", ps, depth, &(rsp->ptr_0 )); /* non-zero pointer to something */ - - prs_string("ntlmssp_str", ps, depth, rsp->ntlmssp_str, 0); /* "NTLMSSP" */ - prs_uint32("ntlmssp_ver", ps, depth, &(rsp->ntlmssp_ver )); /* 0x0000 0002 */ - - prs_uint32("unknown_1", ps, depth, &(rsp->unknown_1)); /* 0x0000 0000 */ - prs_uint32("unknown_2", ps, depth, &(rsp->unknown_2)); /* 0x00b2b3 */ - prs_uint32("unknown_3", ps, depth, &(rsp->unknown_3)); /* 0x0082b1 */ - - prs_uint8s (False, "data", ps, depth, rsp->data, sizeof(rsp->data)); + smb_io_strhdr("hdr_lm_resp ", &rsp->hdr_lm_resp , ps, depth); + smb_io_strhdr("hdr_nt_resp ", &rsp->hdr_nt_resp , ps, depth); + smb_io_strhdr("hdr_domain ", &rsp->hdr_domain , ps, depth); + smb_io_strhdr("hdr_user ", &rsp->hdr_usr , ps, depth); + smb_io_strhdr("hdr_wks ", &rsp->hdr_wks , ps, depth); + smb_io_strhdr("hdr_sess_key", &rsp->hdr_sess_key, ps, depth); + + prs_uint32("neg_flags", ps, depth, &(rsp->neg_flags)); /* 0x0000 82b1 */ + + prs_string("sess_key", ps, depth, rsp->sess_key, rsp->hdr_sess_key.str_str_len, sizeof(rsp->sess_key)); + prs_string("wks ", ps, depth, rsp->wks , rsp->hdr_wks .str_str_len, sizeof(rsp->wks )); + prs_string("user ", ps, depth, rsp->user , rsp->hdr_usr .str_str_len, sizeof(rsp->user )); + prs_string("domain ", ps, depth, rsp->domain , rsp->hdr_domain .str_str_len, sizeof(rsp->domain )); + prs_string("nt_resp ", ps, depth, rsp->nt_resp , rsp->hdr_nt_resp .str_str_len, sizeof(rsp->nt_resp )); + prs_string("lm_resp ", ps, depth, rsp->lm_resp , rsp->hdr_lm_resp .str_str_len, sizeof(rsp->lm_resp )); } #if 0 diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index db6ee62f91..ebb3c11da8 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -3110,6 +3110,34 @@ static BOOL api_WPrintPortEnum(connection_struct *conn,uint16 vuid, char *param, return(True); } +static BOOL api_pipe_ntlmssp(pipes_struct *p, prs_struct *pd) +{ + /* receive a negotiate; send a challenge; receive a response */ + switch (p->auth_verifier.msg_type) + { + case NTLMSSP_NEGOTIATE: + { + smb_io_rpc_auth_ntlmssp_neg("", &p->ntlmssp_neg, pd, 0); + break; + } + case NTLMSSP_AUTH: + { + smb_io_rpc_auth_ntlmssp_resp("", &p->ntlmssp_resp, pd, 0); + break; + } + default: + { + /* NTLMSSP expected: unexpected message type */ + DEBUG(3,("unexpected message type in NTLMSSP %d\n", + p->auth_verifier.msg_type)); + return False; + break; + } + } + + return (pd->offset != 0); +} + struct api_cmd { char * pipe_clnt_name; @@ -3159,12 +3187,16 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) if (p->hdr.auth_len != 0) { /* decode the authentication verifier */ - smb_io_rpc_auth_ntlmssp_req("", &p->ntlmssp_req, pd, 0); + smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0); if (pd->offset == 0) return False; - /* ignore the version number for now */ - ntlmssp_auth = strequal(p->ntlmssp_req.ntlmssp_str, "NTLMSSP"); + ntlmssp_auth = strequal(p->auth_verifier.signature, "NTLMSSP"); + + if (ntlmssp_auth) + { + if (!api_pipe_ntlmssp(p, pd)) return False; + } } /* name has to be \PIPE\xxxxx */ @@ -3176,18 +3208,19 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) prs_init(&(p->rdata), 1024, 4, 0, False); prs_init(&(p->rhdr ), 0x10, 4, 0, False); prs_init(&(p->rauth), 1024, 4, 0, False); + prs_init(&(p->rntlm), 1024, 4, 0, False); /***/ /*** do the bind ack first ***/ /***/ make_rpc_hdr_ba(&p->hdr_ba, - p->hdr_rb.bba.max_tsize, + p->hdr_rb.bba.max_tsize, p->hdr_rb.bba.max_rsize, p->hdr_rb.bba.assoc_gid, - ack_pipe_name, - 0x1, 0x0, 0x0, - &(p->hdr_rb.transfer)); + ack_pipe_name, + 0x1, 0x0, 0x0, + &(p->hdr_rb.transfer)); smb_io_rpc_hdr_ba("", &p->hdr_ba, &p->rdata, 0); mem_realloc_data(p->rdata.data, p->rdata.offset); @@ -3198,16 +3231,19 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) if (ntlmssp_auth) { - uint8 data[16]; - bzero(data, sizeof(data)); /* first 8 bytes are non-zero */ - - make_rpc_auth_ntlmssp_resp(&p->ntlmssp_resp, - 0x0a, 0x06, 0, - "NTLMSSP", 2, - 0x00000000, 0x0000b2b3, 0x000082b1, - data); - smb_io_rpc_auth_ntlmssp_resp("", &p->ntlmssp_resp, &p->rauth, 0); + uint8 challenge[8]; + generate_random_buffer(challenge, 8, False); + + make_rpc_auth_verifier(&p->auth_verifier, + 0x0a, 0x06, 0, + "NTLMSSP", NTLMSSP_CHALLENGE); + smb_io_rpc_auth_verifier("", &p->auth_verifier, &p->rauth, 0); mem_realloc_data(p->rauth.data, p->rauth.offset); + + make_rpc_auth_ntlmssp_chal(&p->ntlmssp_chal, + 0x000082b1, challenge); + smb_io_rpc_auth_ntlmssp_chal("", &p->ntlmssp_chal, &p->rntlm, 0); + mem_realloc_data(p->rntlm.data, p->rntlm.offset); } /***/ @@ -3216,8 +3252,8 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, p->hdr.call_id, - p->rdata.offset + p->rauth.offset + 0x10, - p->rauth.offset); + p->rdata.offset + p->rauth.offset + p->rntlm.offset + 0x10, + p->rauth.offset + p->rntlm.offset); smb_io_rpc_hdr("", &p->hdr, &p->rhdr, 0); mem_realloc_data(p->rhdr.data, p->rdata.offset); @@ -3237,8 +3273,12 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) p->rdata.data->next = p->rauth.data; p->rauth.data->offset.start = p->rhdr.offset + p->rdata.offset; - p->rauth.data->offset.end = p->rhdr.offset + p->rauth.offset + p->rdata.offset; - p->rauth.data->next = NULL; + p->rauth.data->offset.end = p->rhdr.offset + p->rdata.offset + p->rauth.offset; + p->rauth.data->next = p->rntlm.data; + + p->rntlm.data->offset.start = p->rhdr.offset + p->rdata.offset + p->rauth.offset; + p->rntlm.data->offset.end = p->rhdr.offset + p->rdata.offset + p->rauth.offset + p->rntlm.offset; + p->rntlm.data->next = NULL; } else { |