From 5b863af4c0179f0bee17e77690d99a54cc762531 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 12 Nov 1998 16:07:00 +0000 Subject: cleaning up conflicts between group code not yet committed and changes from yesterday by me, jeremy and andrew. jeremy, your ACB_PWNOTREQ mod would have caused a crash if the user didn't exist (first check should be for smb_pass != NULL) (This used to be commit cbac0f165d351ba9497c222e55e453d781376e58) --- source3/rpc_server/srv_pipe.c | 731 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 731 insertions(+) create mode 100644 source3/rpc_server/srv_pipe.c (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c new file mode 100644 index 0000000000..94a7ebc838 --- /dev/null +++ b/source3/rpc_server/srv_pipe.c @@ -0,0 +1,731 @@ + +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-1998 + * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, + * Copyright (C) Paul Ashton 1997-1998. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* this module apparently provides an implementation of DCE/RPC over a + * named pipe (IPC$ connection using SMBtrans). details of DCE/RPC + * documentation are available (in on-line form) from the X-Open group. + * + * this module should provide a level of abstraction between SMB + * and DCE/RPC, while minimising the amount of mallocs, unnecessary + * data copies, and network traffic. + * + * in this version, which takes a "let's learn what's going on and + * get something running" approach, there is additional network + * traffic generated, but the code should be easier to understand... + * + * ... if you read the docs. or stare at packets for weeks on end. + * + */ + +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) +{ + unsigned char *hash = p->ntlmssp_hash; + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; + + for( ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + +/******************************************************************* + turns a DCE/RPC request into a DCE/RPC reply + + this is where the data really should be split up into an array of + headers and data sections. + + ********************************************************************/ +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)); + + auth_len = p->hdr.auth_len; + + 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.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */ + + /* set up rpc header (fragmentation issues) */ + if (data_start == 0) + { + p->hdr.flags = RPC_FLG_FIRST; + } + else + { + 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; + p->hdr.frag_len = p->hdr_resp.alloc_hint + 0x18; + } + else + { + p->hdr.frag_len = p->hdr_ba.bba.max_tsize; + } + + if (p->ntlmssp_auth) + { + p->hdr_resp.alloc_hint -= auth_len + 8; + } + + if (p->ntlmssp_auth) + { + data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; + } + else + { + data_len = p->hdr.frag_len - 0x18; + } + + p->rhdr.data->offset.start = 0; + p->rhdr.data->offset.end = 0x18; + + /* store the header in the data stream */ + smb_io_rpc_hdr ("hdr" , &(p->hdr ), &(p->rhdr), 0); + smb_io_rpc_hdr_resp("resp", &(p->hdr_resp), &(p->rhdr), 0); + + /* don't use rdata: use rdata_i instead, which moves... */ + /* 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, 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) + { + crc32 = crc32_calc_buffer(data_len, data); + NTLMSSPcalc_p(p, (uchar*)data, data_len); + } + + 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; + p->ntlmssp_seq_num++; + 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 = mem_data(&p->rverf.data, 4); + NTLMSSPcalc_p(p, (uchar*)auth_data, 12); + } + } + + /* set up the data chain */ + 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; +} + +static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) +{ + uchar lm_owf[24]; + uchar nt_owf[24]; + struct smb_passwd *smb_pass = NULL; + + DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); + + if (p->ntlmssp_resp.hdr_lm_resp.str_str_len == 0) return False; + if (p->ntlmssp_resp.hdr_nt_resp.str_str_len == 0) return False; + if (p->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; + if (p->ntlmssp_resp.hdr_domain .str_str_len == 0) return False; + if (p->ntlmssp_resp.hdr_wks .str_str_len == 0) return False; + + memset(p->user_name, 0, sizeof(p->user_name)); + memset(p->domain , 0, sizeof(p->domain )); + memset(p->wks , 0, sizeof(p->wks )); + + if (IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) + { + fstrcpy(p->user_name, unistrn2((uint16*)p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); + fstrcpy(p->domain , unistrn2((uint16*)p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); + fstrcpy(p->wks , unistrn2((uint16*)p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); + } + else + { + fstrcpy(p->user_name, p->ntlmssp_resp.user ); + fstrcpy(p->domain , p->ntlmssp_resp.domain); + fstrcpy(p->wks , p->ntlmssp_resp.wks ); + } + + DEBUG(5,("user: %s domain: %s wks: %s\n", p->user_name, p->domain, p->wks)); + + memcpy(lm_owf, p->ntlmssp_resp.lm_resp, sizeof(lm_owf)); + memcpy(nt_owf, p->ntlmssp_resp.nt_resp, sizeof(nt_owf)); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm, nt owfs, chal\n")); + dump_data(100, lm_owf, sizeof(lm_owf)); + dump_data(100, nt_owf, sizeof(nt_owf)); + dump_data(100, p->ntlmssp_chal.challenge, 8); +#endif + become_root(True); + p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain, + (uchar*)p->ntlmssp_chal.challenge, + lm_owf, nt_owf, NULL); + smb_pass = getsmbpwnam(p->user_name); + unbecome_root(True); + + if (p->ntlmssp_validated && smb_pass != NULL && smb_pass->smb_passwd) + { + uchar p24[24]; + NTLMSSPOWFencrypt(smb_pass->smb_passwd, lm_owf, p24); + { + unsigned char j = 0; + int ind; + + unsigned char k2[8]; + + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + for (ind = 0; ind < 256; ind++) + { + p->ntlmssp_hash[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (p->ntlmssp_hash[ind] + k2[ind%8]); + + tc = p->ntlmssp_hash[ind]; + p->ntlmssp_hash[ind] = p->ntlmssp_hash[j]; + p->ntlmssp_hash[j] = tc; + } + + p->ntlmssp_hash[256] = 0; + p->ntlmssp_hash[257] = 0; + } +/* NTLMSSPhash(p->ntlmssp_hash, p24); */ + p->ntlmssp_seq_num = 0; + } + else + { + p->ntlmssp_validated = False; + } + + return p->ntlmssp_validated; +} + +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); + if (!api_pipe_ntlmssp_verify(p)) + { + pd->offset = 0; + } + break; + } + default: + { + /* NTLMSSP expected: unexpected message type */ + DEBUG(3,("unexpected message type in NTLMSSP %d\n", + p->auth_verifier.msg_type)); + return False; + } + } + + return (pd->offset != 0); +} + +struct api_cmd +{ + char * pipe_clnt_name; + char * pipe_srv_name; + BOOL (*fn) (pipes_struct *, prs_struct *); +}; + +static struct api_cmd api_fd_commands[] = +{ + { "lsarpc", "lsass", api_ntlsa_rpc }, + { "samr", "lsass", api_samr_rpc }, + { "srvsvc", "ntsvcs", api_srvsvc_rpc }, + { "wkssvc", "ntsvcs", api_wkssvc_rpc }, + { "NETLOGON", "lsass", api_netlog_rpc }, + { "winreg", "winreg", api_reg_rpc }, + { NULL, NULL, NULL } +}; + +static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) +{ + DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); + + if (p->hdr.auth_len == 0) return False; + + /* decode the authentication verifier response */ + smb_io_rpc_hdr_autha("", &p->autha_info, pd, 0); + if (pd->offset == 0) return False; + + if (!rpc_hdr_auth_chk(&(p->auth_info))) return False; + + smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0); + if (pd->offset == 0) return False; + + if (!rpc_auth_verifier_chk(&(p->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False; + + return api_pipe_ntlmssp(p, pd); +} + +static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +{ + uint16 assoc_gid; + fstring ack_pipe_name; + int i = 0; + + p->ntlmssp_auth = False; + + DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); + + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) + { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) + { + DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + api_fd_commands[i].pipe_clnt_name, + api_fd_commands[i].pipe_srv_name)); + fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name); + break; + } + } + + if (api_fd_commands[i].fn == NULL) return False; + + /* decode the bind request */ + smb_io_rpc_hdr_rb("", &p->hdr_rb, pd, 0); + + if (pd->offset == 0) return False; + + if (p->hdr.auth_len != 0) + { + /* decode the authentication verifier */ + smb_io_rpc_hdr_auth ("", &p->auth_info , pd, 0); + if (pd->offset == 0) return False; + + p->ntlmssp_auth = p->auth_info.auth_type = 0x0a; + + if (p->ntlmssp_auth) + { + smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0); + if (pd->offset == 0) return False; + + p->ntlmssp_auth = strequal(p->auth_verifier.signature, "NTLMSSP"); + } + + if (p->ntlmssp_auth) + { + if (!api_pipe_ntlmssp(p, pd)) return False; + } + } + + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, p->pipe_srv_name); + + DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); + + prs_init(&(p->rdata), 1024, 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); + + /***/ + /*** do the bind ack first ***/ + /***/ + + if (p->ntlmssp_auth) + { + assoc_gid = 0x7a77; + } + else + { + assoc_gid = p->hdr_rb.bba.assoc_gid; + } + + make_rpc_hdr_ba(&p->hdr_ba, + p->hdr_rb.bba.max_tsize, + p->hdr_rb.bba.max_rsize, + assoc_gid, + 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); + + /***/ + /*** now the authentication ***/ + /***/ + + if (p->ntlmssp_auth) + { + uint8 challenge[8]; + generate_random_buffer(challenge, 8, False); + + /*** authentication info ***/ + + make_rpc_hdr_auth(&p->auth_info, 0x0a, 0x06, 0, 1); + smb_io_rpc_hdr_auth("", &p->auth_info, &p->rverf, 0); + mem_realloc_data(p->rverf.data, p->rverf.offset); + + /*** NTLMSSP verifier ***/ + + make_rpc_auth_verifier(&p->auth_verifier, + "NTLMSSP", NTLMSSP_CHALLENGE); + smb_io_rpc_auth_verifier("", &p->auth_verifier, &p->rauth, 0); + mem_realloc_data(p->rauth.data, p->rauth.offset); + + /* NTLMSSP challenge ***/ + + 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); + } + + /***/ + /*** then do the header, now we know the length ***/ + /***/ + + make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, + p->rdata.offset + p->rverf.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); + + /***/ + /*** link rpc header, bind acknowledgment and authentication responses ***/ + /***/ + + if (p->ntlmssp_auth) + { + prs_link(NULL , &p->rhdr , &p->rdata); + prs_link(&p->rhdr , &p->rdata, &p->rverf); + prs_link(&p->rdata, &p->rverf, &p->rauth); + prs_link(&p->rverf, &p->rauth, &p->rntlm); + prs_link(&p->rauth, &p->rntlm, NULL ); + } + else + { + prs_link(NULL , &p->rhdr , &p->rdata); + prs_link(&p->rhdr, &p->rdata, NULL ); + } + + return True; +} + + +static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd) +{ + 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); + int data_len; + int auth_len; + uint32 old_offset; + uint32 crc32; + + auth_len = p->hdr.auth_len; + + if (auth_len != 16 && auth_verify) + { + return False; + } + + data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; + + DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n", + BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); + + if (auth_seal) + { + char *data = mem_data(&pd->data, pd->offset); + DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset)); + NTLMSSPcalc_p(p, (uchar*)data, data_len); + crc32 = crc32_calc_buffer(data_len, data); + } + + /*** skip the data, record the offset so we can restore it again */ + old_offset = pd->offset; + + if (auth_seal || auth_verify) + { + pd->offset += data_len; + smb_io_rpc_hdr_auth("hdr_auth", &p->auth_info, pd, 0); + } + + if (auth_verify) + { + char *req_data = mem_data(&pd->data, pd->offset + 4); + DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4)); + NTLMSSPcalc_p(p, (uchar*)req_data, 12); + smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p->ntlmssp_chk), pd, 0); + + if (!rpc_auth_ntlmssp_chk(&(p->ntlmssp_chk), crc32, + p->ntlmssp_seq_num)) + { + return False; + } + } + + pd->offset = old_offset; + + return True; +} + +static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd) +{ + int i = 0; + + if (p->ntlmssp_auth && p->ntlmssp_validated) + { + if (!api_pipe_auth_process(p, pd)) return False; + + DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n")); +#if 0 + become_user(); +#endif + } + + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) + { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) + { + DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); + return api_fd_commands[i].fn(p, pd); + } + } + return False; +} + +BOOL rpc_command(pipes_struct *p, prs_struct *pd) +{ + BOOL reply = False; + if (pd->data == NULL) return False; + + /* process the rpc header */ + smb_io_rpc_hdr("", &p->hdr, pd, 0); + + if (pd->offset == 0) return False; + + switch (p->hdr.pkt_type) + { + case RPC_BIND : + { + reply = api_pipe_bind_req(p, pd); + break; + } + case RPC_REQUEST: + { + if (p->ntlmssp_auth && !p->ntlmssp_validated) + { + /* authentication _was_ requested + and it failed. sorry, no deal! + */ + reply = False; + } + else + { + /* read the rpc header */ + smb_io_rpc_hdr_req("req", &(p->hdr_req), pd, 0); + reply = api_pipe_request(p, pd); + } + break; + } + case RPC_BINDRESP: /* not the real name! */ + { + reply = api_pipe_bind_auth_resp(p, pd); + p->ntlmssp_auth = reply; + break; + } + } + + if (!reply) + { + DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n")); + } + + return reply; +} + + +/******************************************************************* + receives a netlogon pipe and responds. + ********************************************************************/ +static BOOL api_rpc_command(pipes_struct *p, + char *rpc_name, struct api_struct *api_rpc_cmds, + prs_struct *data) +{ + int fn_num; + DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); + + for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) + { + if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) + { + DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name)); + break; + } + } + + if (api_rpc_cmds[fn_num].name == NULL) + { + DEBUG(4, ("unknown\n")); + return False; + } + + /* start off with 1024 bytes, and a large safety margin too */ + prs_init(&p->rdata, 1024, 4, SAFETY_MARGIN, False); + + /* do the actual command */ + api_rpc_cmds[fn_num].fn(p->vuid, data, &(p->rdata)); + + if (p->rdata.data == NULL || p->rdata.offset == 0) + { + mem_free_data(p->rdata.data); + return False; + } + + mem_realloc_data(p->rdata.data, p->rdata.offset); + + DEBUG(10,("called %s\n", rpc_name)); + + return True; +} + + +/******************************************************************* + receives a netlogon pipe and responds. + ********************************************************************/ +BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds, + prs_struct *data) +{ + if (data == NULL || data->data == NULL) + { + DEBUG(2,("%s: NULL data received\n", rpc_name)); + return False; + } + + /* interpret the command */ + if (!api_rpc_command(p, rpc_name, api_rpc_cmds, data)) + { + return False; + } + + /* create the rpc header */ + if (!create_rpc_reply(p, 0, p->rdata.offset + (p->ntlmssp_auth ? (16 + 8) : 0))) + { + return False; + } + + return True; +} -- cgit From 8fc1504ff8204dd1ca735f31c769f6dadf0f88cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Nov 1998 21:41:01 +0000 Subject: Makefile.in configure configure.in include/config.h.in: Changes for DGUX and UNIXWARE. groupdb/aliasdb.c groupdb/aliasfile.c groupdb/groupfile.c: Don't use snprinf, use slprintf. include/includes.h: Fix YP problem. include/smb.h: Fix ZERO_STRUCTP. lib/util_sock.c: Added strerror() in debugs. passdb/ldap.c: Don't use snprinf, use slprintf. rpc_client/cli_lsarpc.c rpc_client/cli_pipe.c rpc_parse/parse_sec.c rpc_server/srv_pipe.c: Don't use snprinf, use slprintf. script/installman.sh: DGUX changes. smbd/open.c smbd/oplock.c: Fixed gcc warnings. web/swat.c: Changes USER to SWAT_USER. (This used to be commit 4c2b5a00983501e5d4aad1456ba8b5ab0dfd9b4c) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 94a7ebc838..1ad4cb6b9e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -160,7 +160,7 @@ BOOL create_rpc_reply(pipes_struct *p, if (auth_len > 0) { - uint32 crc32; + uint32 crc32 = 0; DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n", BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); @@ -531,7 +531,7 @@ static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd) int data_len; int auth_len; uint32 old_offset; - uint32 crc32; + uint32 crc32 = 0; auth_len = p->hdr.auth_len; -- cgit From 8308c000b2022769644ed8ea1fc772776257c99b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 8 Dec 1998 00:25:04 +0000 Subject: adding srvsvc pipe. (This used to be commit d06d6369942828ec89e90f99bd0d0d3f91d61d13) --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1ad4cb6b9e..d9483deb86 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -347,6 +347,7 @@ static struct api_cmd api_fd_commands[] = { "samr", "lsass", api_samr_rpc }, { "srvsvc", "ntsvcs", api_srvsvc_rpc }, { "wkssvc", "ntsvcs", api_wkssvc_rpc }, + { "svcctl", "ntsvcs", api_svcctl_rpc }, { "NETLOGON", "lsass", api_netlog_rpc }, { "winreg", "winreg", api_reg_rpc }, { NULL, NULL, NULL } -- cgit From fe609d810e145d5491968fee5d691d6eee41e152 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 3 Feb 1999 00:48:27 +0000 Subject: multiple dce/rpc PDUs failed to work after ntlmssp update was added. (This used to be commit f082f07e764c04b75b6880f852b80faec86f1b1c) --- source3/rpc_server/srv_pipe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index d9483deb86..9e03188af5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -203,7 +203,6 @@ BOOL create_rpc_reply(pipes_struct *p, } /* 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; -- cgit From f61fc8923d4eceab8c82ff9c49745f9c6bed44e7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 3 Feb 1999 01:58:52 +0000 Subject: corrections to get data stream for 2nd and subsequent pdus copied from right place (forgot to subtract 0x18 header bytes) (This used to be commit 5b9a7278da4a25ea217f914c8daae31238fa5cfe) --- source3/rpc_server/srv_pipe.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9e03188af5..f8d882cd0c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -202,9 +202,6 @@ BOOL create_rpc_reply(pipes_struct *p, prs_link(&p->rhdr, &p->rdata_i, NULL ); } - /* indicate to subsequent data reads where we are up to */ - p->next_frag_start = p->hdr.frag_len; - return p->rhdr.data != NULL && p->rhdr.offset == 0x18; } -- cgit From 99a9b0f7c4f85f46102457cf4707e8948b77fb3f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 8 Feb 1999 23:40:49 +0000 Subject: UNICODE byte ordering issue: typecast to uint16* replaced with SSVAL() (This used to be commit 9084b7e33dfe717bd8d5604ee71d137e3baef0f5) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index f8d882cd0c..5908fe06b5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -225,9 +225,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) if (IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) { - fstrcpy(p->user_name, unistrn2((uint16*)p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); - fstrcpy(p->domain , unistrn2((uint16*)p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); - fstrcpy(p->wks , unistrn2((uint16*)p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); + fstrcpy(p->user_name, unistrn2(p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); + fstrcpy(p->domain , unistrn2(p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); + fstrcpy(p->wks , unistrn2(p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); } else { -- cgit From 8b6b6b57b54aeafb915cf99e5610941ee1d464b8 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 10 Feb 1999 22:30:47 +0000 Subject: use jeremy's versions of the UNICODE routines. (This used to be commit c5109ff782be8774db47a92b48ca6335ec8d6065) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5908fe06b5..f8d882cd0c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -225,9 +225,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) if (IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) { - fstrcpy(p->user_name, unistrn2(p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); - fstrcpy(p->domain , unistrn2(p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); - fstrcpy(p->wks , unistrn2(p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); + fstrcpy(p->user_name, unistrn2((uint16*)p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); + fstrcpy(p->domain , unistrn2((uint16*)p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); + fstrcpy(p->wks , unistrn2((uint16*)p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); } else { -- cgit From f38bfc7d9aa07c4e21448aa846956bd89a259a65 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 11 Feb 1999 22:12:49 +0000 Subject: UNICODE issues. (This used to be commit 6a437cfb33f24913e0c1f8484c0b08ef317e513b) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index f8d882cd0c..5908fe06b5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -225,9 +225,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) if (IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) { - fstrcpy(p->user_name, unistrn2((uint16*)p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); - fstrcpy(p->domain , unistrn2((uint16*)p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); - fstrcpy(p->wks , unistrn2((uint16*)p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); + fstrcpy(p->user_name, unistrn2(p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); + fstrcpy(p->domain , unistrn2(p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); + fstrcpy(p->wks , unistrn2(p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); } else { -- cgit From fd96929ec1fa27e0affd4c4e9ba307c4ee30b978 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Fri, 12 Feb 1999 00:16:09 +0000 Subject: UNICODE cleanup (see lib/util_unistr.c). No more ugly static library buffers and all functions take a destination string length (especially unistrcpy was rather dangerous; we were only saved by the fact that datagrams are limited in size). (This used to be commit a1d39af1ce1d451b811dbd7c2ba391214851b87e) --- source3/rpc_server/srv_pipe.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5908fe06b5..07e16c7e5d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -225,9 +225,15 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) if (IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) { - fstrcpy(p->user_name, unistrn2(p->ntlmssp_resp.user , p->ntlmssp_resp.hdr_usr .str_str_len/2)); - fstrcpy(p->domain , unistrn2(p->ntlmssp_resp.domain, p->ntlmssp_resp.hdr_domain.str_str_len/2)); - fstrcpy(p->wks , unistrn2(p->ntlmssp_resp.wks , p->ntlmssp_resp.hdr_wks .str_str_len/2)); + unibuf_to_ascii(p->user_name, p->ntlmssp_resp.user, + MIN(p->ntlmssp_resp.hdr_usr .str_str_len/2, + sizeof(p->user_name))); + unibuf_to_ascii(p->domain , p->ntlmssp_resp.domain, + MIN(p->ntlmssp_resp.hdr_domain.str_str_len/2, + sizeof(p->domain ))); + unibuf_to_ascii(p->wks , p->ntlmssp_resp.wks, + MIN(p->ntlmssp_resp.hdr_wks .str_str_len/2, + sizeof(p->wks ))); } else { -- cgit From 2737f26ad64ee32d6ef7365dcce0a3eb881f99db Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Mon, 15 Feb 1999 05:33:30 +0000 Subject: Always null-terminate strings. Also some string length and sizeof(pointer) corrections. (This used to be commit ce24191939b82985d09eabe945199f38b0fea486) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 07e16c7e5d..e619797f6e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -227,13 +227,13 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) { unibuf_to_ascii(p->user_name, p->ntlmssp_resp.user, MIN(p->ntlmssp_resp.hdr_usr .str_str_len/2, - sizeof(p->user_name))); + sizeof(p->user_name)-1)); unibuf_to_ascii(p->domain , p->ntlmssp_resp.domain, MIN(p->ntlmssp_resp.hdr_domain.str_str_len/2, - sizeof(p->domain ))); + sizeof(p->domain )-1)); unibuf_to_ascii(p->wks , p->ntlmssp_resp.wks, MIN(p->ntlmssp_resp.hdr_wks .str_str_len/2, - sizeof(p->wks ))); + sizeof(p->wks )-1)); } else { -- cgit From 7f02de406d4a59fdaaa646ca6e28fdcb3e40a13d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 17 Mar 1999 19:49:14 +0000 Subject: Stefan Walters: purify spotted rverf should be alloc'd to 16 bytes not 8. (This used to be commit 4bb74fcc714fccac791ce86c8882d19d704b17a1) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e619797f6e..ec5b547c86 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -102,7 +102,7 @@ BOOL create_rpc_reply(pipes_struct *p, 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->rverf, 0x10, 4, 0, False); p->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */ -- cgit From 43a460075a39148060d4193fcb9c62bfa4acc737 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 25 Mar 1999 13:54:31 +0000 Subject: SAM database "set user info". ---------------------------- - removed DOM_RID4 - removed SAMR_UNKNOWN_32 - added SAMR_SET_USERINFO (opcode 0x32) - added level 0x1 to SAMR_QUERY_DOM_INFO (needed for create user) - fixed pwdb_gethexpwd() it was failing on XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - added mod_sam21pwd_entry() - preparing to call mod_sam21pwd_entry() - added "user session key" to user_struct.dc. this is md4(nt#) and is needed to decode user's clear-text passwords in SAMR_SET_USERINFO. - split code out in chgpasswd.c to decode 516 byte password buffers. (This used to be commit 2e58ed742435befe419aa366c4052019fede8c23) --- source3/rpc_server/srv_pipe.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ec5b547c86..54d26650e9 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -211,8 +211,16 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) uchar nt_owf[24]; struct smb_passwd *smb_pass = NULL; + user_struct *vuser = get_valid_user_struct(p->vuid); + DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); + if (vuser == NULL) + { + DEBUG(0,("get user struct %d failed\n", p->vuid)); + return False; + } + if (p->ntlmssp_resp.hdr_lm_resp.str_str_len == 0) return False; if (p->ntlmssp_resp.hdr_nt_resp.str_str_len == 0) return False; if (p->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; @@ -256,7 +264,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) become_root(True); p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain, (uchar*)p->ntlmssp_chal.challenge, - lm_owf, nt_owf, NULL); + lm_owf, nt_owf, NULL, vuser->dc.user_sess_key); smb_pass = getsmbpwnam(p->user_name); unbecome_root(True); -- cgit From be552ca3504ebd98da37e70bac1f10b248cf860b Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Tue, 27 Apr 1999 10:43:32 +0000 Subject: rpc_parse/parse_misc.c : defined a new BUFFER5 struct include/ntdomain.h : added rpc_spoolss.h include statement include/proto.h include/rpc_dce.h : added definition of RPC_ALTER_CONTEXT request & reply param/loadparm.c : 2 new options for NT printing support and some changes to initial values in the LPRNG case. rpc_parse/parse_prs.c : added prs_uint16s() rpc_parse/parse_rpc.c : added SYNT_SPOOLSS_V1 and code for the alter-context support. rpc_server/srv_pipe.c : alter-context support smbd/nttrans.c smbd/server.c include/rpc_misc.h Makefile.in include/smb.h Jean Francois (This used to be commit 4c515804b70254248e378a3f90f47e4c32639d29) --- source3/rpc_server/srv_pipe.c | 51 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 54d26650e9..466d56b67a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -360,6 +360,7 @@ static struct api_cmd api_fd_commands[] = { "svcctl", "ntsvcs", api_svcctl_rpc }, { "NETLOGON", "lsass", api_netlog_rpc }, { "winreg", "winreg", api_reg_rpc }, + { "spoolss", "spoolss", api_spoolss_rpc }, { NULL, NULL, NULL } }; @@ -383,7 +384,7 @@ static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) return api_pipe_ntlmssp(p, pd); } -static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type) { uint16 assoc_gid; fstring ack_pipe_name; @@ -435,9 +436,29 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) } } - /* name has to be \PIPE\xxxxx */ - fstrcpy(ack_pipe_name, "\\PIPE\\"); - fstrcat(ack_pipe_name, p->pipe_srv_name); + switch (pkt_type) + { + case RPC_BINDACK: + { + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, p->pipe_srv_name); + break; + } + case RPC_ALTCONTRESP: + { + /* secondary address CAN be NULL + * as the specs says it's ignored. + * It MUST NULL to have the spoolss working. + */ + fstrcpy(ack_pipe_name, ""); + break; + } + default: + { + return False; + } + } DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); @@ -505,7 +526,7 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) /*** then do the header, now we know the length ***/ /***/ - make_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, + make_rpc_hdr(&p->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, p->hdr.call_id, p->rdata.offset + p->rverf.offset + p->rauth.offset + p->rntlm.offset + 0x10, p->rauth.offset + p->rntlm.offset); @@ -534,6 +555,21 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) return True; } +/* + * The RPC Alter-Context call is used only by the spoolss pipe + * simply because there is a bug (?) in the MS unmarshalling code + * or in the marshalling code. If it's in the later, then Samba + * have the same bug. + */ +static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +{ + return api_pipe_bind_and_alt_req(p, pd, RPC_BINDACK); +} + +static BOOL api_pipe_alt_req(pipes_struct *p, prs_struct *pd) +{ + return api_pipe_bind_and_alt_req(p, pd, RPC_ALTCONTRESP); +} static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd) { @@ -635,6 +671,11 @@ BOOL rpc_command(pipes_struct *p, prs_struct *pd) reply = api_pipe_bind_req(p, pd); break; } + case RPC_ALTCONT: + { + reply = api_pipe_alt_req(p, pd); + break; + } case RPC_REQUEST: { if (p->ntlmssp_auth && !p->ntlmssp_validated) -- cgit From 4e5bf481fba36655e8fc8e04f6f67ba17dcb9844 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 3 May 1999 22:04:02 +0000 Subject: last part of RPC api change. and of rpcclient eventlog funtion Jean Francois (This used to be commit 7fc8659e83bf0269df297016beac6793ff0bdf32) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 466d56b67a..d98fecbc1f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -739,7 +739,7 @@ static BOOL api_rpc_command(pipes_struct *p, prs_init(&p->rdata, 1024, 4, SAFETY_MARGIN, False); /* do the actual command */ - api_rpc_cmds[fn_num].fn(p->vuid, data, &(p->rdata)); + api_rpc_cmds[fn_num].fn(p, data, &(p->rdata)); if (p->rdata.data == NULL || p->rdata.offset == 0) { -- cgit From 73891ca8e4f6cca6aa8bb0ae043f660a64baa056 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Jun 1999 18:47:06 +0000 Subject: improving authentication code (tidyup). (This used to be commit ab1a6aa42db5217f025941fb5107436556bc23b7) --- source3/rpc_server/srv_pipe.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index d98fecbc1f..3e5d986935 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -208,7 +208,9 @@ BOOL create_rpc_reply(pipes_struct *p, static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) { uchar lm_owf[24]; - uchar nt_owf[24]; + uchar nt_owf[128]; + size_t lm_owf_len; + size_t nt_owf_len; struct smb_passwd *smb_pass = NULL; user_struct *vuser = get_valid_user_struct(p->vuid); @@ -221,12 +223,29 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) return False; } - if (p->ntlmssp_resp.hdr_lm_resp.str_str_len == 0) return False; - if (p->ntlmssp_resp.hdr_nt_resp.str_str_len == 0) return False; + lm_owf_len = p->ntlmssp_resp.hdr_lm_resp.str_str_len; + nt_owf_len = p->ntlmssp_resp.hdr_nt_resp.str_str_len; + + + if (lm_owf_len == 0) return False; + if (nt_owf_len == 0) return False; if (p->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; if (p->ntlmssp_resp.hdr_domain .str_str_len == 0) return False; if (p->ntlmssp_resp.hdr_wks .str_str_len == 0) return False; + if (lm_owf_len > sizeof(lm_owf)) return False; + if (nt_owf_len > sizeof(nt_owf)) return False; + + memcpy(lm_owf, p->ntlmssp_resp.lm_resp, sizeof(lm_owf)); + memcpy(nt_owf, p->ntlmssp_resp.nt_resp, sizeof(nt_owf)); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm, nt owfs, chal\n")); + dump_data(100, lm_owf, sizeof(lm_owf)); + dump_data(100, nt_owf, sizeof(nt_owf)); + dump_data(100, p->ntlmssp_chal.challenge, 8); +#endif + memset(p->user_name, 0, sizeof(p->user_name)); memset(p->domain , 0, sizeof(p->domain )); memset(p->wks , 0, sizeof(p->wks )); @@ -252,19 +271,12 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) DEBUG(5,("user: %s domain: %s wks: %s\n", p->user_name, p->domain, p->wks)); - memcpy(lm_owf, p->ntlmssp_resp.lm_resp, sizeof(lm_owf)); - memcpy(nt_owf, p->ntlmssp_resp.nt_resp, sizeof(nt_owf)); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("lm, nt owfs, chal\n")); - dump_data(100, lm_owf, sizeof(lm_owf)); - dump_data(100, nt_owf, sizeof(nt_owf)); - dump_data(100, p->ntlmssp_chal.challenge, 8); -#endif become_root(True); p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain, (uchar*)p->ntlmssp_chal.challenge, - lm_owf, nt_owf, NULL, vuser->dc.user_sess_key); + lm_owf, lm_owf_len, + nt_owf, nt_owf_len, + NULL, vuser->dc.user_sess_key); smb_pass = getsmbpwnam(p->user_name); unbecome_root(True); -- cgit From f2e0bbffb5e40df4850b6bd0eae73a8fb0edc6d7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 26 Jul 1999 21:47:23 +0000 Subject: renaming AUTH VERIFIER to AUTH NTLMSSP VERIFIER. ready for adding another RPC authentication system. (This used to be commit 1a211bafebad8c63d98b5ef275a6272013527c65) --- source3/rpc_server/srv_pipe.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3e5d986935..458d7e883c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -388,10 +388,10 @@ static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) if (!rpc_hdr_auth_chk(&(p->auth_info))) return False; - smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0); + smb_io_rpc_auth_ntlmssp_verifier("", &p->auth_verifier, pd, 0); if (pd->offset == 0) return False; - if (!rpc_auth_verifier_chk(&(p->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False; + if (!rpc_auth_ntlmssp_verifier_chk(&(p->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False; return api_pipe_ntlmssp(p, pd); } @@ -436,7 +436,7 @@ static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_ if (p->ntlmssp_auth) { - smb_io_rpc_auth_verifier("", &p->auth_verifier, pd, 0); + smb_io_rpc_auth_ntlmssp_verifier("", &p->auth_verifier, pd, 0); if (pd->offset == 0) return False; p->ntlmssp_auth = strequal(p->auth_verifier.signature, "NTLMSSP"); @@ -521,9 +521,9 @@ static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_ /*** NTLMSSP verifier ***/ - make_rpc_auth_verifier(&p->auth_verifier, + make_rpc_auth_ntlmssp_verifier(&p->auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE); - smb_io_rpc_auth_verifier("", &p->auth_verifier, &p->rauth, 0); + smb_io_rpc_auth_ntlmssp_verifier("", &p->auth_verifier, &p->rauth, 0); mem_realloc_data(p->rauth.data, p->rauth.offset); /* NTLMSSP challenge ***/ -- cgit From b231d2fafaff8dc67ef2dbaec778f716524d4f6a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 15 Nov 1999 22:11:10 +0000 Subject: - added DCE/RPC "fault" PDU support. - disabled (AGAIN) the GETDC "if (MAILSLOT\NTLOGON)" code that will get NT5rc2 to work but WILL break win95 (AGAIN). this needs _not_ to be re-enabled but to be replaced with a better mechanism. - added SMBwrite support (note: SMBwriteX already existed) as NT5rc2 is sending DCE/RPC over SMBwrite not SMBwriteX. (This used to be commit 25c70e3c984c4fed19763ed405741e83fe14f87e) --- source3/rpc_server/srv_pipe.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 458d7e883c..1073ba2179 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -396,6 +396,45 @@ static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) return api_pipe_ntlmssp(p, pd); } +static BOOL api_pipe_fault_resp(pipes_struct *p, prs_struct *pd, uint32 status) +{ + DEBUG(5,("api_pipe_fault_resp: make response\n")); + + prs_init(&(p->rhdr ), 0x18, 4, 0, False); + prs_init(&(p->rfault ), 0x8 , 4, 0, False); + + /***/ + /*** set up the header, response header and fault status ***/ + /***/ + + p->hdr_fault.status = status; + p->hdr_fault.reserved = 0x0; + + p->hdr_resp.alloc_hint = 0x0; + p->hdr_resp.cancel_count = 0x0; + p->hdr_resp.reserved = 0x0; + + make_rpc_hdr(&p->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, + 0x20, + 0); + + smb_io_rpc_hdr ("hdr" , &(p->hdr ), &(p->rhdr), 0); + smb_io_rpc_hdr_resp ("resp" , &(p->hdr_resp ), &(p->rhdr), 0); + smb_io_rpc_hdr_fault("fault", &(p->hdr_fault), &(p->rfault), 0); + mem_realloc_data(p->rhdr.data, p->rhdr.offset); + mem_realloc_data(p->rfault.data, p->rfault.offset); + + /***/ + /*** link rpc header and fault together ***/ + /***/ + + prs_link(NULL , &p->rhdr , &p->rfault); + prs_link(&p->rhdr, &p->rfault, NULL ); + + return True; +} + static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type) { uint16 assoc_gid; @@ -669,6 +708,8 @@ static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd) BOOL rpc_command(pipes_struct *p, prs_struct *pd) { BOOL reply = False; + DEBUG(10,("rpc_command\n")); + if (pd->data == NULL) return False; /* process the rpc header */ @@ -715,7 +756,7 @@ BOOL rpc_command(pipes_struct *p, prs_struct *pd) if (!reply) { - DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n")); + reply = api_pipe_fault_resp(p, pd, 0x1c010002); } return reply; -- cgit From 774d2d73666b7deca79ae90dd10397e2e1f8e6d9 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 16 Nov 1999 15:39:09 +0000 Subject: Shirish Kalele noticed that NT workstations are sending anonymous NTLMSSP user credentials to set up \PIPE\samr. added anonymous NTLMSSP sessions. (This used to be commit df5ee2bd427ccd5fcf27fd3c366e06e037bc4f1e) --- source3/rpc_server/srv_pipe.c | 69 ++++++++++++++++++++++++++++++++----------- 1 file changed, 51 insertions(+), 18 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1073ba2179..c6d9cf070e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -207,14 +207,23 @@ BOOL create_rpc_reply(pipes_struct *p, static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) { + uchar *pwd = NULL; + uchar null_pwd[16]; uchar lm_owf[24]; uchar nt_owf[128]; size_t lm_owf_len; size_t nt_owf_len; + size_t usr_len; + size_t dom_len; + size_t wks_len; + BOOL anonymous = False; + struct smb_passwd *smb_pass = NULL; user_struct *vuser = get_valid_user_struct(p->vuid); + memset(null_pwd, 0, sizeof(null_pwd)); + DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); if (vuser == NULL) @@ -225,13 +234,23 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) lm_owf_len = p->ntlmssp_resp.hdr_lm_resp.str_str_len; nt_owf_len = p->ntlmssp_resp.hdr_nt_resp.str_str_len; + usr_len = p->ntlmssp_resp.hdr_usr .str_str_len; + dom_len = p->ntlmssp_resp.hdr_domain .str_str_len; + wks_len = p->ntlmssp_resp.hdr_wks .str_str_len; - - if (lm_owf_len == 0) return False; - if (nt_owf_len == 0) return False; - if (p->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; - if (p->ntlmssp_resp.hdr_domain .str_str_len == 0) return False; - if (p->ntlmssp_resp.hdr_wks .str_str_len == 0) return False; + if (lm_owf_len == 0 && nt_owf_len == 0 && + usr_len == 0 && dom_len == 0 && wks_len == 0) + { + anonymous = True; + } + else + { + if (lm_owf_len == 0) return False; + if (nt_owf_len == 0) return False; + if (p->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; + if (p->ntlmssp_resp.hdr_domain .str_str_len == 0) return False; + if (p->ntlmssp_resp.hdr_wks .str_str_len == 0) return False; + } if (lm_owf_len > sizeof(lm_owf)) return False; if (nt_owf_len > sizeof(nt_owf)) return False; @@ -269,21 +288,36 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) fstrcpy(p->wks , p->ntlmssp_resp.wks ); } - DEBUG(5,("user: %s domain: %s wks: %s\n", p->user_name, p->domain, p->wks)); - become_root(True); - p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain, - (uchar*)p->ntlmssp_chal.challenge, - lm_owf, lm_owf_len, - nt_owf, nt_owf_len, - NULL, vuser->dc.user_sess_key); - smb_pass = getsmbpwnam(p->user_name); - unbecome_root(True); + if (anonymous) + { + DEBUG(5,("anonymous user session\n")); + mdfour(vuser->dc.user_sess_key, null_pwd, 16); + pwd = null_pwd; + p->ntlmssp_validated = True; + } + else + { + DEBUG(5,("user: %s domain: %s wks: %s\n", p->user_name, p->domain, p->wks)); + become_root(True); + p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain, + (uchar*)p->ntlmssp_chal.challenge, + lm_owf, lm_owf_len, + nt_owf, nt_owf_len, + NULL, vuser->dc.user_sess_key); + smb_pass = getsmbpwnam(p->user_name); + unbecome_root(True); + + if (smb_pass != NULL) + { + pwd = smb_pass->smb_passwd; + } + } - if (p->ntlmssp_validated && smb_pass != NULL && smb_pass->smb_passwd) + if (p->ntlmssp_validated && pwd != NULL) { uchar p24[24]; - NTLMSSPOWFencrypt(smb_pass->smb_passwd, lm_owf, p24); + NTLMSSPOWFencrypt(pwd, lm_owf, p24); { unsigned char j = 0; int ind; @@ -314,7 +348,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) p->ntlmssp_hash[256] = 0; p->ntlmssp_hash[257] = 0; } -/* NTLMSSPhash(p->ntlmssp_hash, p24); */ p->ntlmssp_seq_num = 0; } else -- cgit From 161c11e4bcd408064493c063b228aab589fd2a19 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 19 Nov 1999 01:01:07 +0000 Subject: - bug in nmbd registering DOMAIN_NAME<1c> to WINS server; recursion desired flag MUST be set in any NBT UDP packets sent to a WINS server, else they will go to the WINS client side of the NT NetBIOS kernel instead, and will get trashed. - added \PIPE\browser server-side code. (This used to be commit 8e406c1fa296c3f97b1cd7ddde7b5aeb9232b26e) --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index c6d9cf070e..075c9b0d37 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -402,6 +402,7 @@ static struct api_cmd api_fd_commands[] = { "samr", "lsass", api_samr_rpc }, { "srvsvc", "ntsvcs", api_srvsvc_rpc }, { "wkssvc", "ntsvcs", api_wkssvc_rpc }, + { "browser", "ntsvcs", api_brs_rpc }, { "svcctl", "ntsvcs", api_svcctl_rpc }, { "NETLOGON", "lsass", api_netlog_rpc }, { "winreg", "winreg", api_reg_rpc }, -- cgit From 4081147c31919a973ce1859394d0f5a49a0c2f39 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 17:11:00 +0000 Subject: adding user session key into network netlogon response. (This used to be commit c73f6b0d02fa7700319ba696f54296006167e5d1) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 075c9b0d37..c4664f7d7b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -300,12 +300,12 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) { DEBUG(5,("user: %s domain: %s wks: %s\n", p->user_name, p->domain, p->wks)); become_root(True); - p->ntlmssp_validated = pass_check_smb(p->user_name, p->domain, + smb_pass = getsmbpwnam(p->user_name); + p->ntlmssp_validated = pass_check_smb(smb_pass, p->domain, (uchar*)p->ntlmssp_chal.challenge, lm_owf, lm_owf_len, nt_owf, nt_owf_len, NULL, vuser->dc.user_sess_key); - smb_pass = getsmbpwnam(p->user_name); unbecome_root(True); if (smb_pass != NULL) -- cgit From a0ba234cf9b40adf6b5390e4e67730163a42883f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 6 Dec 1999 00:44:32 +0000 Subject: the first independent msrpc daemon - lsarpcd. one horrible cut / paste job from smbd, plus a code split of shared components between the two. the job is not _yet_ complete, as i need to be able to do a become_user() call for security reasons. i picked lsarpcd first because you don't _need_ security on it (microsoft botched so badly on this one, it's not real. at least they fixed this in nt5 with restrictanonymous=0x2). fixing this involves sending the current smb and unix credentials down the unix pipe so that the daemon it eventually goes to can pick them up at the other end. i can't believe this all worked!!! (This used to be commit 2245b0c6d13c7c5886e81f9137b05df883598c26) --- source3/rpc_server/srv_pipe.c | 120 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 13 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index c4664f7d7b..04fa0955ea 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -396,7 +396,69 @@ struct api_cmd BOOL (*fn) (pipes_struct *, prs_struct *); }; -static struct api_cmd api_fd_commands[] = +static struct api_cmd **api_fd_commands = NULL; +uint32 num_cmds = 0; + +static void api_cmd_free(struct api_cmd *item) +{ + if (item != NULL) + { + if (item->pipe_clnt_name != NULL) + { + free(item->pipe_clnt_name); + } + if (item->pipe_srv_name != NULL) + { + free(item->pipe_srv_name); + } + free(item); + } +} + +static struct api_cmd *api_cmd_dup(const struct api_cmd *from) +{ + struct api_cmd *copy = NULL; + if (from == NULL) + { + return NULL; + } + copy = (struct api_cmd *) malloc(sizeof(struct api_cmd)); + if (copy != NULL) + { + ZERO_STRUCTP(copy); + if (from->pipe_clnt_name != NULL) + { + copy->pipe_clnt_name = strdup(from->pipe_clnt_name ); + } + if (from->pipe_srv_name != NULL) + { + copy->pipe_srv_name = strdup(from->pipe_srv_name); + } + if (from->fn != NULL) + { + copy->fn = from->fn; + } + } + return copy; +} + +static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries) +{ + void(*fn)(void*) = (void(*)(void*))&api_cmd_free; + free_void_array(num_entries, (void**)entries, *fn); +} + +static struct api_cmd* add_api_cmd_to_array(uint32 *len, + struct api_cmd ***array, + const struct api_cmd *name) +{ + void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup; + return (struct api_cmd*)add_copy_to_array(len, + (void***)array, (const void*)name, *fn, False); + +} + +#if 0 { { "lsarpc", "lsass", api_ntlsa_rpc }, { "samr", "lsass", api_samr_rpc }, @@ -409,6 +471,20 @@ static struct api_cmd api_fd_commands[] = { "spoolss", "spoolss", api_spoolss_rpc }, { NULL, NULL, NULL } }; +#endif + +void close_msrpc_command_processor(void) +{ + free_api_cmd_array(num_cmds, api_fd_commands); +} + +void add_msrpc_command_processor(char* pipe_name, + char* process_name, + BOOL (*fn) (pipes_struct *, prs_struct *)) +{ + struct api_cmd cmd = { pipe_name, process_name, fn }; + add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd); +} static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) { @@ -479,20 +555,20 @@ static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_ DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); - for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) + for (i = 0; i < num_cmds; i++) { - if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && - api_fd_commands[i].fn != NULL) + if (strequal(api_fd_commands[i]->pipe_clnt_name, p->name) && + api_fd_commands[i]->fn != NULL) { DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", - api_fd_commands[i].pipe_clnt_name, - api_fd_commands[i].pipe_srv_name)); - fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name); + api_fd_commands[i]->pipe_clnt_name, + api_fd_commands[i]->pipe_srv_name)); + fstrcpy(p->pipe_srv_name, api_fd_commands[i]->pipe_srv_name); break; } } - if (api_fd_commands[i].fn == NULL) return False; + if (api_fd_commands[i]->fn == NULL) return False; /* decode the bind request */ smb_io_rpc_hdr_rb("", &p->hdr_rb, pd, 0); @@ -727,13 +803,13 @@ static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd) #endif } - for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) + for (i = 0; i < num_cmds; i++) { - if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && - api_fd_commands[i].fn != NULL) + if (strequal(api_fd_commands[i]->pipe_clnt_name, p->name) && + api_fd_commands[i]->fn != NULL) { - DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); - return api_fd_commands[i].fn(p, pd); + DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name)); + return api_fd_commands[i]->fn(p, pd); } } return False; @@ -744,6 +820,24 @@ BOOL rpc_command(pipes_struct *p, prs_struct *pd) BOOL reply = False; DEBUG(10,("rpc_command\n")); + if (p->m != NULL) + { + DEBUG(10,("msrpc redirect\n")); + if (!msrpc_send_prs(p->m, pd)) + { + DEBUG(2,("msrpc redirect send failed\n")); + return False; + } + if (!msrpc_receive_prs(p->m, &p->rhdr)) + { + DEBUG(2,("msrpc redirect receive failed\n")); + return False; + } + prs_link(NULL, &p->rhdr, NULL); + prs_debug_out(&p->rhdr, 10); + return True; + } + if (pd->data == NULL) return False; /* process the rpc header */ -- cgit From 4ab9d91428b66bd2fe407b0dba94f4130160b576 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 8 Dec 1999 21:43:03 +0000 Subject: ABOUT TIME!!!!!!!! damn, this one is bad. started, at least two days ago, to add an authentication mechanism to the smbd<->msrpc redirector/relay, such that sufficient unix / nt information could be transferred across the unix socket to do a become_user() on the other side of the socket. it is necessary that the msrpc daemon inherit the same unix and nt credentials as the smbd process from which it was spawned, until such time as the msrpc daemon receives an authentication request of its own, whereupon the msrpc daemon is responsible for authenticating the new credentials and doing yet another become_user() etc sequence. (This used to be commit 30c7fdd6ef10ecd35594311c1b250b95ff895489) --- source3/rpc_server/srv_pipe.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 04fa0955ea..ca87cafcf7 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -482,7 +482,11 @@ void add_msrpc_command_processor(char* pipe_name, char* process_name, BOOL (*fn) (pipes_struct *, prs_struct *)) { - struct api_cmd cmd = { pipe_name, process_name, fn }; + struct api_cmd cmd; + cmd.pipe_clnt_name = pipe_name; + cmd.pipe_srv_name = process_name; + cmd.fn = fn; + add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd); } -- cgit From 0ce128e3550794d4dbbd1def00e87c020f72c992 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 01:25:49 +0000 Subject: delineation between smb and msrpc more marked. smbd now constructs pdus, and then feeds them over either a "local" function call or a "remote" function call to an msrpc service. the "remote" msrpc daemon, on the other side of a unix socket, then calls the same "local" function that smbd would, if the msrpc service were being run from inside smbd. this allows a transition from local msrpc services (inside the same smbd process) to remote (over a unix socket). removed reference to pipes_struct in msrpc services. all msrpc processing functions take rpcsrv_struct which is a structure containing state info for the msrpc functions to decode and create pdus. created become_vuser() which does everything not related to connection_struct that become_user() does. removed, as best i could, connection_struct dependencies from the nt spoolss printing code. todo: remove dcinfo from rpcsrv_struct because this stores NETLOGON-specific info on a per-connection basis, and if the connection dies then so does the info, and that's a fairly serious problem. had to put pretty much everything that is in user_struct into parse_creds.c to feed unix user info over to the msrpc daemons. why? because it's expensive to do unix password/group database lookups, and it's definitely expensive to do nt user profile lookups, not to mention pretty difficult and if you did either of these it would introduce a complication / unnecessary interdependency. so, send uid/gid/num_groups/gid_t* + SID+num_rids+domain_group_rids* + unix username + nt username + nt domain + user session key etc. this is the MINIMUM info identified so far that's actually implemented. missing bits include the called and calling netbios names etc. (basically, anything that can be loaded into standard_sub() and standard_sub_basic()...) (This used to be commit aa3c659a8dba0437c17c60055a6ed30fdfecdb6d) --- source3/rpc_server/srv_pipe.c | 703 +++++++++++++++++++++++++----------------- 1 file changed, 422 insertions(+), 281 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ca87cafcf7..73a06b208c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -43,7 +43,7 @@ extern int DEBUGLEVEL; -static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) +static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len) { unsigned char *hash = p->ntlmssp_hash; unsigned char index_i = hash[256]; @@ -70,6 +70,19 @@ static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) hash[257] = index_j; } +/******************************************************************* + frees all temporary data used in construction of pdu + ********************************************************************/ +void rpcsrv_free_temp(rpcsrv_struct *l) +{ + mem_free_data(l->rhdr .data); + mem_free_data(l->rfault .data); + mem_free_data(l->rdata_i.data); + mem_free_data(l->rauth .data); + mem_free_data(l->rverf .data); + mem_free_data(l->rntlm .data); +} + /******************************************************************* turns a DCE/RPC request into a DCE/RPC reply @@ -77,21 +90,21 @@ static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) headers and data sections. ********************************************************************/ -BOOL create_rpc_reply(pipes_struct *p, - uint32 data_start, uint32 data_end) +BOOL create_rpc_reply(rpcsrv_struct *l, uint32 data_start) { 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); + BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN); + BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL); uint32 data_len; uint32 auth_len; + uint32 data_end = l->rdata.offset + (l->ntlmssp_auth ? (8 + 16) : 0); 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)); + data_start, data_end, l->hdr_ba.bba.max_tsize)); - auth_len = p->hdr.auth_len; + auth_len = l->hdr.auth_len; - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { DEBUG(10,("create_rpc_reply: auth\n")); if (auth_len != 16) @@ -100,63 +113,63 @@ BOOL create_rpc_reply(pipes_struct *p, } } - prs_init(&p->rhdr , 0x18, 4, 0, False); - prs_init(&p->rauth, 1024, 4, 0, False); - prs_init(&p->rverf, 0x10, 4, 0, False); + prs_init(&l->rhdr , 0x18, 4, 0, False); + prs_init(&l->rauth, 1024, 4, 0, False); + prs_init(&l->rverf, 0x10, 4, 0, False); - p->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */ + l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */ /* set up rpc header (fragmentation issues) */ if (data_start == 0) { - p->hdr.flags = RPC_FLG_FIRST; + l->hdr.flags = RPC_FLG_FIRST; } else { - p->hdr.flags = 0; + l->hdr.flags = 0; } - p->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */ + l->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) + if (l->hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize) { - p->hdr.flags |= RPC_FLG_LAST; - p->hdr.frag_len = p->hdr_resp.alloc_hint + 0x18; + l->hdr.flags |= RPC_FLG_LAST; + l->hdr.frag_len = l->hdr_resp.alloc_hint + 0x18; } else { - p->hdr.frag_len = p->hdr_ba.bba.max_tsize; + l->hdr.frag_len = l->hdr_ba.bba.max_tsize; } - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { - p->hdr_resp.alloc_hint -= auth_len + 8; + l->hdr_resp.alloc_hint -= auth_len + 8; } - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { - data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; + data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; } else { - data_len = p->hdr.frag_len - 0x18; + data_len = l->hdr.frag_len - 0x18; } - p->rhdr.data->offset.start = 0; - p->rhdr.data->offset.end = 0x18; + l->rhdr.data->offset.start = 0; + l->rhdr.data->offset.end = 0x18; /* store the header in the data stream */ - smb_io_rpc_hdr ("hdr" , &(p->hdr ), &(p->rhdr), 0); - smb_io_rpc_hdr_resp("resp", &(p->hdr_resp), &(p->rhdr), 0); + smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0); + smb_io_rpc_hdr_resp("resp", &(l->hdr_resp), &(l->rhdr), 0); /* don't use rdata: use rdata_i instead, which moves... */ /* 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, 0, data_len, 0, False); - p->rdata_i.offset = data_len; + l->rdata_i.data = NULL; + prs_init(&l->rdata_i, 0, l->rdata.align, l->rdata.data->margin, l->rdata.io); + data = mem_data(&(l->rdata.data), data_start); + mem_create(l->rdata_i.data, data, 0, data_len, 0, False); + l->rdata_i.offset = data_len; if (auth_len > 0) { @@ -168,44 +181,44 @@ BOOL create_rpc_reply(pipes_struct *p, if (auth_seal) { crc32 = crc32_calc_buffer(data_len, data); - NTLMSSPcalc_p(p, (uchar*)data, data_len); + NTLMSSPcalc_p(l, (uchar*)data, data_len); } 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); + make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0)); + smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, &l->rauth, 0); } if (auth_verify) { char *auth_data; - p->ntlmssp_seq_num++; - 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 = mem_data(&p->rverf.data, 4); - NTLMSSPcalc_p(p, (uchar*)auth_data, 12); + l->ntlmssp_seq_num++; + make_rpc_auth_ntlmssp_chk(&l->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, l->ntlmssp_seq_num++); + smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), &l->rverf, 0); + auth_data = mem_data(&l->rverf.data, 4); + NTLMSSPcalc_p(l, (uchar*)auth_data, 12); } } /* set up the data chain */ - if (p->ntlmssp_auth) + if (l->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 ); + prs_link(NULL , &l->rhdr , &l->rdata_i); + prs_link(&l->rhdr , &l->rdata_i, &l->rauth ); + prs_link(&l->rdata_i, &l->rauth , &l->rverf ); + prs_link(&l->rauth , &l->rverf , NULL ); } else { - prs_link(NULL , &p->rhdr , &p->rdata_i); - prs_link(&p->rhdr, &p->rdata_i, NULL ); + prs_link(NULL , &l->rhdr , &l->rdata_i); + prs_link(&l->rhdr, &l->rdata_i, NULL ); } - return p->rhdr.data != NULL && p->rhdr.offset == 0x18; + return l->rhdr.data != NULL && l->rhdr.offset == 0x18; } -static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) +static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l) { uchar *pwd = NULL; uchar null_pwd[16]; @@ -220,23 +233,15 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) struct smb_passwd *smb_pass = NULL; - user_struct *vuser = get_valid_user_struct(p->vuid); - memset(null_pwd, 0, sizeof(null_pwd)); DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); - if (vuser == NULL) - { - DEBUG(0,("get user struct %d failed\n", p->vuid)); - return False; - } - - lm_owf_len = p->ntlmssp_resp.hdr_lm_resp.str_str_len; - nt_owf_len = p->ntlmssp_resp.hdr_nt_resp.str_str_len; - usr_len = p->ntlmssp_resp.hdr_usr .str_str_len; - dom_len = p->ntlmssp_resp.hdr_domain .str_str_len; - wks_len = p->ntlmssp_resp.hdr_wks .str_str_len; + lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len; + nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len; + usr_len = l->ntlmssp_resp.hdr_usr .str_str_len; + dom_len = l->ntlmssp_resp.hdr_domain .str_str_len; + wks_len = l->ntlmssp_resp.hdr_wks .str_str_len; if (lm_owf_len == 0 && nt_owf_len == 0 && usr_len == 0 && dom_len == 0 && wks_len == 0) @@ -247,65 +252,65 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) { if (lm_owf_len == 0) return False; if (nt_owf_len == 0) return False; - if (p->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; - if (p->ntlmssp_resp.hdr_domain .str_str_len == 0) return False; - if (p->ntlmssp_resp.hdr_wks .str_str_len == 0) return False; + if (l->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; + if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False; + if (l->ntlmssp_resp.hdr_wks .str_str_len == 0) return False; } if (lm_owf_len > sizeof(lm_owf)) return False; if (nt_owf_len > sizeof(nt_owf)) return False; - memcpy(lm_owf, p->ntlmssp_resp.lm_resp, sizeof(lm_owf)); - memcpy(nt_owf, p->ntlmssp_resp.nt_resp, sizeof(nt_owf)); + memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf)); + memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf)); #ifdef DEBUG_PASSWORD DEBUG(100,("lm, nt owfs, chal\n")); dump_data(100, lm_owf, sizeof(lm_owf)); dump_data(100, nt_owf, sizeof(nt_owf)); - dump_data(100, p->ntlmssp_chal.challenge, 8); + dump_data(100, l->ntlmssp_chal.challenge, 8); #endif - memset(p->user_name, 0, sizeof(p->user_name)); - memset(p->domain , 0, sizeof(p->domain )); - memset(p->wks , 0, sizeof(p->wks )); + memset(l->user_name, 0, sizeof(l->user_name)); + memset(l->domain , 0, sizeof(l->domain )); + memset(l->wks , 0, sizeof(l->wks )); - if (IS_BITS_SET_ALL(p->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) + if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) { - unibuf_to_ascii(p->user_name, p->ntlmssp_resp.user, - MIN(p->ntlmssp_resp.hdr_usr .str_str_len/2, - sizeof(p->user_name)-1)); - unibuf_to_ascii(p->domain , p->ntlmssp_resp.domain, - MIN(p->ntlmssp_resp.hdr_domain.str_str_len/2, - sizeof(p->domain )-1)); - unibuf_to_ascii(p->wks , p->ntlmssp_resp.wks, - MIN(p->ntlmssp_resp.hdr_wks .str_str_len/2, - sizeof(p->wks )-1)); + unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user, + MIN(l->ntlmssp_resp.hdr_usr .str_str_len/2, + sizeof(l->user_name)-1)); + unibuf_to_ascii(l->domain , l->ntlmssp_resp.domain, + MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2, + sizeof(l->domain )-1)); + unibuf_to_ascii(l->wks , l->ntlmssp_resp.wks, + MIN(l->ntlmssp_resp.hdr_wks .str_str_len/2, + sizeof(l->wks )-1)); } else { - fstrcpy(p->user_name, p->ntlmssp_resp.user ); - fstrcpy(p->domain , p->ntlmssp_resp.domain); - fstrcpy(p->wks , p->ntlmssp_resp.wks ); + fstrcpy(l->user_name, l->ntlmssp_resp.user ); + fstrcpy(l->domain , l->ntlmssp_resp.domain); + fstrcpy(l->wks , l->ntlmssp_resp.wks ); } if (anonymous) { DEBUG(5,("anonymous user session\n")); - mdfour(vuser->dc.user_sess_key, null_pwd, 16); + mdfour(l->user_sess_key, null_pwd, 16); pwd = null_pwd; - p->ntlmssp_validated = True; + l->ntlmssp_validated = True; } else { - DEBUG(5,("user: %s domain: %s wks: %s\n", p->user_name, p->domain, p->wks)); + DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks)); become_root(True); - smb_pass = getsmbpwnam(p->user_name); - p->ntlmssp_validated = pass_check_smb(smb_pass, p->domain, - (uchar*)p->ntlmssp_chal.challenge, + smb_pass = getsmbpwnam(l->user_name); + l->ntlmssp_validated = pass_check_smb(smb_pass, l->domain, + (uchar*)l->ntlmssp_chal.challenge, lm_owf, lm_owf_len, nt_owf, nt_owf_len, - NULL, vuser->dc.user_sess_key); + NULL, l->user_sess_key); unbecome_root(True); if (smb_pass != NULL) @@ -314,7 +319,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) } } - if (p->ntlmssp_validated && pwd != NULL) + if (l->ntlmssp_validated && pwd != NULL) { uchar p24[24]; NTLMSSPOWFencrypt(pwd, lm_owf, p24); @@ -331,47 +336,47 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p) for (ind = 0; ind < 256; ind++) { - p->ntlmssp_hash[ind] = (unsigned char)ind; + l->ntlmssp_hash[ind] = (unsigned char)ind; } for( ind = 0; ind < 256; ind++) { unsigned char tc; - j += (p->ntlmssp_hash[ind] + k2[ind%8]); + j += (l->ntlmssp_hash[ind] + k2[ind%8]); - tc = p->ntlmssp_hash[ind]; - p->ntlmssp_hash[ind] = p->ntlmssp_hash[j]; - p->ntlmssp_hash[j] = tc; + tc = l->ntlmssp_hash[ind]; + l->ntlmssp_hash[ind] = l->ntlmssp_hash[j]; + l->ntlmssp_hash[j] = tc; } - p->ntlmssp_hash[256] = 0; - p->ntlmssp_hash[257] = 0; + l->ntlmssp_hash[256] = 0; + l->ntlmssp_hash[257] = 0; } - p->ntlmssp_seq_num = 0; + l->ntlmssp_seq_num = 0; } else { - p->ntlmssp_validated = False; + l->ntlmssp_validated = False; } - return p->ntlmssp_validated; + return l->ntlmssp_validated; } -static BOOL api_pipe_ntlmssp(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd) { /* receive a negotiate; send a challenge; receive a response */ - switch (p->auth_verifier.msg_type) + switch (l->auth_verifier.msg_type) { case NTLMSSP_NEGOTIATE: { - smb_io_rpc_auth_ntlmssp_neg("", &p->ntlmssp_neg, pd, 0); + smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0); break; } case NTLMSSP_AUTH: { - smb_io_rpc_auth_ntlmssp_resp("", &p->ntlmssp_resp, pd, 0); - if (!api_pipe_ntlmssp_verify(p)) + smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0); + if (!api_pipe_ntlmssp_verify(l)) { pd->offset = 0; } @@ -381,7 +386,7 @@ static BOOL api_pipe_ntlmssp(pipes_struct *p, prs_struct *pd) { /* NTLMSSP expected: unexpected message type */ DEBUG(3,("unexpected message type in NTLMSSP %d\n", - p->auth_verifier.msg_type)); + l->auth_verifier.msg_type)); return False; } } @@ -393,7 +398,7 @@ struct api_cmd { char * pipe_clnt_name; char * pipe_srv_name; - BOOL (*fn) (pipes_struct *, prs_struct *); + BOOL (*fn) (rpcsrv_struct *, prs_struct *); }; static struct api_cmd **api_fd_commands = NULL; @@ -480,7 +485,7 @@ void close_msrpc_command_processor(void) void add_msrpc_command_processor(char* pipe_name, char* process_name, - BOOL (*fn) (pipes_struct *, prs_struct *)) + BOOL (*fn) (rpcsrv_struct *, prs_struct *)) { struct api_cmd cmd; cmd.pipe_clnt_name = pipe_name; @@ -490,269 +495,281 @@ void add_msrpc_command_processor(char* pipe_name, add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd); } -static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd) { DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); - if (p->hdr.auth_len == 0) return False; + if (l->hdr.auth_len == 0) return False; /* decode the authentication verifier response */ - smb_io_rpc_hdr_autha("", &p->autha_info, pd, 0); + smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0); if (pd->offset == 0) return False; - if (!rpc_hdr_auth_chk(&(p->auth_info))) return False; + if (!rpc_hdr_auth_chk(&(l->auth_info))) return False; - smb_io_rpc_auth_ntlmssp_verifier("", &p->auth_verifier, pd, 0); + smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0); if (pd->offset == 0) return False; - if (!rpc_auth_ntlmssp_verifier_chk(&(p->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False; + if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False; - return api_pipe_ntlmssp(p, pd); + return api_pipe_ntlmssp(l, pd); } -static BOOL api_pipe_fault_resp(pipes_struct *p, prs_struct *pd, uint32 status) +static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status) { DEBUG(5,("api_pipe_fault_resp: make response\n")); - prs_init(&(p->rhdr ), 0x18, 4, 0, False); - prs_init(&(p->rfault ), 0x8 , 4, 0, False); + prs_init(&(l->rhdr ), 0x18, 4, 0, False); + prs_init(&(l->rfault ), 0x8 , 4, 0, False); /***/ /*** set up the header, response header and fault status ***/ /***/ - p->hdr_fault.status = status; - p->hdr_fault.reserved = 0x0; + l->hdr_fault.status = status; + l->hdr_fault.reserved = 0x0; - p->hdr_resp.alloc_hint = 0x0; - p->hdr_resp.cancel_count = 0x0; - p->hdr_resp.reserved = 0x0; + l->hdr_resp.alloc_hint = 0x0; + l->hdr_resp.cancel_count = 0x0; + l->hdr_resp.reserved = 0x0; - make_rpc_hdr(&p->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST, - p->hdr.call_id, + make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST, + l->hdr.call_id, 0x20, 0); - smb_io_rpc_hdr ("hdr" , &(p->hdr ), &(p->rhdr), 0); - smb_io_rpc_hdr_resp ("resp" , &(p->hdr_resp ), &(p->rhdr), 0); - smb_io_rpc_hdr_fault("fault", &(p->hdr_fault), &(p->rfault), 0); - mem_realloc_data(p->rhdr.data, p->rhdr.offset); - mem_realloc_data(p->rfault.data, p->rfault.offset); + smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0); + smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0); + smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0); + mem_realloc_data(l->rhdr.data, l->rhdr.offset); + mem_realloc_data(l->rfault.data, l->rfault.offset); /***/ /*** link rpc header and fault together ***/ /***/ - prs_link(NULL , &p->rhdr , &p->rfault); - prs_link(&p->rhdr, &p->rfault, NULL ); + prs_link(NULL , &l->rhdr , &l->rfault); + prs_link(&l->rhdr, &l->rfault, NULL ); return True; } -static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type) +static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd, + const char* ack_pipe_name, + enum RPC_PKT_TYPE pkt_type) { uint16 assoc_gid; - fstring ack_pipe_name; - int i = 0; - - p->ntlmssp_auth = False; - - DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); - - for (i = 0; i < num_cmds; i++) - { - if (strequal(api_fd_commands[i]->pipe_clnt_name, p->name) && - api_fd_commands[i]->fn != NULL) - { - DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", - api_fd_commands[i]->pipe_clnt_name, - api_fd_commands[i]->pipe_srv_name)); - fstrcpy(p->pipe_srv_name, api_fd_commands[i]->pipe_srv_name); - break; - } - } - if (api_fd_commands[i]->fn == NULL) return False; + l->ntlmssp_auth = False; /* decode the bind request */ - smb_io_rpc_hdr_rb("", &p->hdr_rb, pd, 0); + smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0); if (pd->offset == 0) return False; - if (p->hdr.auth_len != 0) + if (l->hdr.auth_len != 0) { /* decode the authentication verifier */ - smb_io_rpc_hdr_auth ("", &p->auth_info , pd, 0); + smb_io_rpc_hdr_auth ("", &l->auth_info , pd, 0); if (pd->offset == 0) return False; - p->ntlmssp_auth = p->auth_info.auth_type = 0x0a; + l->ntlmssp_auth = l->auth_info.auth_type = 0x0a; - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { - smb_io_rpc_auth_ntlmssp_verifier("", &p->auth_verifier, pd, 0); + smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0); if (pd->offset == 0) return False; - p->ntlmssp_auth = strequal(p->auth_verifier.signature, "NTLMSSP"); + l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP"); } - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { - if (!api_pipe_ntlmssp(p, pd)) return False; - } - } - - switch (pkt_type) - { - case RPC_BINDACK: - { - /* name has to be \PIPE\xxxxx */ - fstrcpy(ack_pipe_name, "\\PIPE\\"); - fstrcat(ack_pipe_name, p->pipe_srv_name); - break; - } - case RPC_ALTCONTRESP: - { - /* secondary address CAN be NULL - * as the specs says it's ignored. - * It MUST NULL to have the spoolss working. - */ - fstrcpy(ack_pipe_name, ""); - break; - } - default: - { - return False; + if (!api_pipe_ntlmssp(l, pd)) return False; } } DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); - prs_init(&(p->rdata), 1024, 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); + prs_init(&(l->rdata), 1024, 4, 0, False); + prs_init(&(l->rhdr ), 0x18, 4, 0, False); + prs_init(&(l->rauth), 1024, 4, 0, False); + prs_init(&(l->rverf), 0x08, 4, 0, False); + prs_init(&(l->rntlm), 1024, 4, 0, False); /***/ /*** do the bind ack first ***/ /***/ - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { assoc_gid = 0x7a77; } else { - assoc_gid = p->hdr_rb.bba.assoc_gid; + assoc_gid = l->hdr_rb.bba.assoc_gid; } - make_rpc_hdr_ba(&p->hdr_ba, - p->hdr_rb.bba.max_tsize, - p->hdr_rb.bba.max_rsize, + make_rpc_hdr_ba(&l->hdr_ba, + l->hdr_rb.bba.max_tsize, + l->hdr_rb.bba.max_rsize, assoc_gid, ack_pipe_name, 0x1, 0x0, 0x0, - &(p->hdr_rb.transfer)); + &(l->hdr_rb.transfer)); - smb_io_rpc_hdr_ba("", &p->hdr_ba, &p->rdata, 0); - mem_realloc_data(p->rdata.data, p->rdata.offset); + smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0); + mem_realloc_data(l->rdata.data, l->rdata.offset); /***/ /*** now the authentication ***/ /***/ - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { uint8 challenge[8]; generate_random_buffer(challenge, 8, False); /*** authentication info ***/ - make_rpc_hdr_auth(&p->auth_info, 0x0a, 0x06, 0, 1); - smb_io_rpc_hdr_auth("", &p->auth_info, &p->rverf, 0); - mem_realloc_data(p->rverf.data, p->rverf.offset); + make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1); + smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0); + mem_realloc_data(l->rverf.data, l->rverf.offset); /*** NTLMSSP verifier ***/ - make_rpc_auth_ntlmssp_verifier(&p->auth_verifier, + make_rpc_auth_ntlmssp_verifier(&l->auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE); - smb_io_rpc_auth_ntlmssp_verifier("", &p->auth_verifier, &p->rauth, 0); - mem_realloc_data(p->rauth.data, p->rauth.offset); + smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0); + mem_realloc_data(l->rauth.data, l->rauth.offset); /* NTLMSSP challenge ***/ - make_rpc_auth_ntlmssp_chal(&p->ntlmssp_chal, + make_rpc_auth_ntlmssp_chal(&l->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); + smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0); + mem_realloc_data(l->rntlm.data, l->rntlm.offset); } /***/ /*** then do the header, now we know the length ***/ /***/ - make_rpc_hdr(&p->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, - p->hdr.call_id, - p->rdata.offset + p->rverf.offset + p->rauth.offset + p->rntlm.offset + 0x10, - p->rauth.offset + p->rntlm.offset); + make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, + l->hdr.call_id, + l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10, + l->rauth.offset + l->rntlm.offset); - smb_io_rpc_hdr("", &p->hdr, &p->rhdr, 0); - mem_realloc_data(p->rhdr.data, p->rdata.offset); + smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0); + mem_realloc_data(l->rhdr.data, l->rdata.offset); /***/ /*** link rpc header, bind acknowledgment and authentication responses ***/ /***/ - if (p->ntlmssp_auth) + if (l->ntlmssp_auth) { - prs_link(NULL , &p->rhdr , &p->rdata); - prs_link(&p->rhdr , &p->rdata, &p->rverf); - prs_link(&p->rdata, &p->rverf, &p->rauth); - prs_link(&p->rverf, &p->rauth, &p->rntlm); - prs_link(&p->rauth, &p->rntlm, NULL ); + prs_link(NULL , &l->rhdr , &l->rdata); + prs_link(&l->rhdr , &l->rdata, &l->rverf); + prs_link(&l->rdata, &l->rverf, &l->rauth); + prs_link(&l->rverf, &l->rauth, &l->rntlm); + prs_link(&l->rauth, &l->rntlm, NULL ); } else { - prs_link(NULL , &p->rhdr , &p->rdata); - prs_link(&p->rhdr, &p->rdata, NULL ); + prs_link(NULL , &l->rhdr , &l->rdata); + prs_link(&l->rhdr, &l->rdata, NULL ); } return True; } +static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd, + const char* name, + enum RPC_PKT_TYPE pkt_type) +{ + fstring ack_pipe_name; + fstring pipe_srv_name; + int i = 0; + + DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); + + for (i = 0; i < num_cmds; i++) + { + if (strequal(api_fd_commands[i]->pipe_clnt_name, name) && + api_fd_commands[i]->fn != NULL) + { + DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + api_fd_commands[i]->pipe_clnt_name, + api_fd_commands[i]->pipe_srv_name)); + fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name); + break; + } + } + + if (api_fd_commands[i]->fn == NULL) return False; + + switch (pkt_type) + { + case RPC_BINDACK: + { + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, pipe_srv_name); + break; + } + case RPC_ALTCONTRESP: + { + /* secondary address CAN be NULL + * as the specs says it's ignored. + * It MUST NULL to have the spoolss working. + */ + fstrcpy(ack_pipe_name, ""); + break; + } + default: + { + return False; + } + } + return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type); +} + /* * The RPC Alter-Context call is used only by the spoolss pipe * simply because there is a bug (?) in the MS unmarshalling code * or in the marshalling code. If it's in the later, then Samba * have the same bug. */ -static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd, + const char* name) { - return api_pipe_bind_and_alt_req(p, pd, RPC_BINDACK); + return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK); } -static BOOL api_pipe_alt_req(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd, + const char* name) { - return api_pipe_bind_and_alt_req(p, pd, RPC_ALTCONTRESP); + return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP); } -static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd) { - 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); + BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN); + BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL); int data_len; int auth_len; uint32 old_offset; uint32 crc32 = 0; - auth_len = p->hdr.auth_len; + auth_len = l->hdr.auth_len; if (auth_len != 16 && auth_verify) { return False; } - data_len = p->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; + data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n", BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); @@ -761,7 +778,7 @@ static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd) { char *data = mem_data(&pd->data, pd->offset); DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset)); - NTLMSSPcalc_p(p, (uchar*)data, data_len); + NTLMSSPcalc_p(l, (uchar*)data, data_len); crc32 = crc32_calc_buffer(data_len, data); } @@ -771,18 +788,18 @@ static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd) if (auth_seal || auth_verify) { pd->offset += data_len; - smb_io_rpc_hdr_auth("hdr_auth", &p->auth_info, pd, 0); + smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0); } if (auth_verify) { char *req_data = mem_data(&pd->data, pd->offset + 4); DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4)); - NTLMSSPcalc_p(p, (uchar*)req_data, 12); - smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(p->ntlmssp_chk), pd, 0); + NTLMSSPcalc_p(l, (uchar*)req_data, 12); + smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0); - if (!rpc_auth_ntlmssp_chk(&(p->ntlmssp_chk), crc32, - p->ntlmssp_seq_num)) + if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32, + l->ntlmssp_seq_num)) { return False; } @@ -793,13 +810,13 @@ static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *pd) return True; } -static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name) { int i = 0; - if (p->ntlmssp_auth && p->ntlmssp_validated) + if (l->ntlmssp_auth && l->ntlmssp_validated) { - if (!api_pipe_auth_process(p, pd)) return False; + if (!api_pipe_auth_process(l, pd)) return False; DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n")); #if 0 @@ -809,61 +826,116 @@ static BOOL api_pipe_request(pipes_struct *p, prs_struct *pd) for (i = 0; i < num_cmds; i++) { - if (strequal(api_fd_commands[i]->pipe_clnt_name, p->name) && + if (strequal(api_fd_commands[i]->pipe_clnt_name, name) && api_fd_commands[i]->fn != NULL) { DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name)); - return api_fd_commands[i]->fn(p, pd); + return api_fd_commands[i]->fn(l, pd); } } return False; } -BOOL rpc_command(pipes_struct *p, prs_struct *pd) +BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len) { - BOOL reply = False; - DEBUG(10,("rpc_command\n")); + int prev_size; + int new_size; + char *to = NULL; - if (p->m != NULL) + ps->offset = 0; + + if (ps->data == NULL) { - DEBUG(10,("msrpc redirect\n")); - if (!msrpc_send_prs(p->m, pd)) + DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len)); + prs_init(ps, len, 4, 0, True); + prev_size = 0; + new_size = len; + if (ps->data == NULL) { - DEBUG(2,("msrpc redirect send failed\n")); return False; } - if (!msrpc_receive_prs(p->m, &p->rhdr)) + } + else + { + prev_size = ps->data->data_used; + new_size = prev_size + len; + DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n", + prev_size, new_size)); + if (!mem_realloc_data(ps->data, new_size)) { - DEBUG(2,("msrpc redirect receive failed\n")); return False; } - prs_link(NULL, &p->rhdr, NULL); - prs_debug_out(&p->rhdr, 10); - return True; } - if (pd->data == NULL) return False; + DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start)); + ps->data->offset.start = 0x0; + + to = mem_data(&ps->data, prev_size); + if (to == NULL) + { + DEBUG(10,("rpc_add_to_pdu: data could not be found\n")); + return False; + } + if (ps->data->data_used != new_size) + { + DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n", + ps->data->data_used, new_size)); + return False; + } + memcpy(to, data, len); + return True; +} + +static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp) +{ + DEBUG(10,("rpc_redirect\n")); + + if (!msrpc_send_prs(p->m, req)) + { + DEBUG(2,("msrpc redirect send failed\n")); + return False; + } + if (!msrpc_receive_prs(p->m, resp)) + { + DEBUG(2,("msrpc redirect receive failed\n")); + return False; + } + prs_link(NULL, resp, NULL); + prs_debug_out(resp, "redirect", 100); + return True; +} +static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp, + const char* name) +{ + BOOL reply = False; + + if (req->data == NULL) return False; + + /* lkclXXXX still assume that the first complete PDU is always + in a single request!!! + */ /* process the rpc header */ - smb_io_rpc_hdr("", &p->hdr, pd, 0); + req->offset = 0x0; + smb_io_rpc_hdr("", &l->hdr, req, 0); - if (pd->offset == 0) return False; + if (req->offset == 0) return False; - switch (p->hdr.pkt_type) + switch (l->hdr.pkt_type) { case RPC_BIND : { - reply = api_pipe_bind_req(p, pd); + reply = api_pipe_bind_req(l, req, name); break; } case RPC_ALTCONT: { - reply = api_pipe_alt_req(p, pd); + reply = api_pipe_alt_req(l, req, name); break; } case RPC_REQUEST: { - if (p->ntlmssp_auth && !p->ntlmssp_validated) + if (l->ntlmssp_auth && !l->ntlmssp_validated) { /* authentication _was_ requested and it failed. sorry, no deal! @@ -873,41 +945,87 @@ BOOL rpc_command(pipes_struct *p, prs_struct *pd) else { /* read the rpc header */ - smb_io_rpc_hdr_req("req", &(p->hdr_req), pd, 0); - reply = api_pipe_request(p, pd); + smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0); + reply = api_pipe_request(l, req, name); } break; } case RPC_BINDRESP: /* not the real name! */ { - reply = api_pipe_bind_auth_resp(p, pd); - p->ntlmssp_auth = reply; + reply = api_pipe_bind_auth_resp(l, req); + l->ntlmssp_auth = reply; break; } } if (!reply) { - reply = api_pipe_fault_resp(p, pd, 0x1c010002); + reply = api_pipe_fault_resp(l, req, 0x1c010002); + } + + if (reply) + { + /* flatten the data into a single pdu */ + reply = prs_copy(resp, &l->rhdr); } + /* delete intermediate data used to set up the pdu. leave + rdata alone because that's got the rest of the data in it */ + rpcsrv_free_temp(l); + return reply; } +BOOL rpc_send_and_rcv_pdu(pipes_struct *p) +{ + DEBUG(10,("rpc_send_and_rcv_pdu\n")); + + if (p->m != NULL) + { + return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu); + } + else if (p->l != NULL) + { + return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu, + p->name); + } + return False; +} + +/******************************************************************* + entry point from msrpc to smb. adds data received to pdu; checks + pdu; hands pdu off to msrpc, which gets a pdu back (except in the + case of the RPC_BINDCONT pdu). + ********************************************************************/ +BOOL rpc_to_smb(pipes_struct *p, char *data, int len) +{ + BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len); + + if (reply && is_complete_pdu(&p->smb_pdu)) + { + p->smb_pdu.offset = p->smb_pdu.data->data_size; + prs_link(NULL, &p->smb_pdu, NULL); + reply = rpc_send_and_rcv_pdu(p); + mem_free_data(p->smb_pdu.data); + prs_init(&p->smb_pdu, 0, 4, 0, True); + + } + return reply; +} /******************************************************************* receives a netlogon pipe and responds. ********************************************************************/ -static BOOL api_rpc_command(pipes_struct *p, +static BOOL api_rpc_command(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds, prs_struct *data) { int fn_num; - DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); + DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum)); for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { - if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) + if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name)); break; @@ -921,18 +1039,18 @@ static BOOL api_rpc_command(pipes_struct *p, } /* start off with 1024 bytes, and a large safety margin too */ - prs_init(&p->rdata, 1024, 4, SAFETY_MARGIN, False); + prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False); /* do the actual command */ - api_rpc_cmds[fn_num].fn(p, data, &(p->rdata)); + api_rpc_cmds[fn_num].fn(l, data, &(l->rdata)); - if (p->rdata.data == NULL || p->rdata.offset == 0) + if (l->rdata.data == NULL || l->rdata.offset == 0) { - mem_free_data(p->rdata.data); + mem_free_data(l->rdata.data); return False; } - mem_realloc_data(p->rdata.data, p->rdata.offset); + mem_realloc_data(l->rdata.data, l->rdata.offset); DEBUG(10,("called %s\n", rpc_name)); @@ -943,7 +1061,7 @@ static BOOL api_rpc_command(pipes_struct *p, /******************************************************************* receives a netlogon pipe and responds. ********************************************************************/ -BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds, +BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds, prs_struct *data) { if (data == NULL || data->data == NULL) @@ -953,16 +1071,39 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds } /* interpret the command */ - if (!api_rpc_command(p, rpc_name, api_rpc_cmds, data)) + if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data)) { return False; } /* create the rpc header */ - if (!create_rpc_reply(p, 0, p->rdata.offset + (p->ntlmssp_auth ? (16 + 8) : 0))) + if (!create_rpc_reply(l, 0)) { return False; } return True; } + +BOOL is_complete_pdu(prs_struct *ps) +{ + RPC_HDR hdr; + int len = ps->data->data_size; + + DEBUG(10,("is_complete_pdu - len %d\n", len)); + ps->offset = 0x0; + + if (!ps->io) + { + /* writing. oops!! */ + DEBUG(4,("is_complete_pdu: write set, not read!\n")); + return False; + } + + if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0)) + { + return False; + } + /* check that the fragment length is equal to the data length so far */ + return hdr.frag_len == len; +} -- cgit From 4f8a24522c683761c6f2ee23dba56f6c7913377b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 20:03:42 +0000 Subject: final part of "first" phase converting over to msrpc daemon architecture. done a minimal amout of clean-up in the Makefile, removing unnecessary modules from the link stage. this is not complete, yet, and will involve some changes, for example to smbd, to remove dependencies on the password database API that shouldn't be there. for example, smbd should not ever call getsmbpwXXX() it should call the Samr or Lsa API. this first implementation has minor problems with not reinstantiating the same services as the caller. the "homes" service is a good example. (This used to be commit caa50525220b0d0250fa139367593c2de2c12135) --- source3/rpc_server/srv_pipe.c | 30 ++++-------------------------- 1 file changed, 4 insertions(+), 26 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 73a06b208c..d15cc1248c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -231,8 +231,6 @@ static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l) size_t wks_len; BOOL anonymous = False; - struct smb_passwd *smb_pass = NULL; - memset(null_pwd, 0, sizeof(null_pwd)); DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); @@ -304,19 +302,13 @@ static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l) else { DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks)); - become_root(True); - smb_pass = getsmbpwnam(l->user_name); - l->ntlmssp_validated = pass_check_smb(smb_pass, l->domain, + become_root(False); + l->ntlmssp_validated = check_domain_security(l->user_name, l->domain, (uchar*)l->ntlmssp_chal.challenge, lm_owf, lm_owf_len, nt_owf, nt_owf_len, - NULL, l->user_sess_key); - unbecome_root(True); - - if (smb_pass != NULL) - { - pwd = smb_pass->smb_passwd; - } + l->user_sess_key); + unbecome_root(False); } if (l->ntlmssp_validated && pwd != NULL) @@ -463,20 +455,6 @@ static struct api_cmd* add_api_cmd_to_array(uint32 *len, } -#if 0 -{ - { "lsarpc", "lsass", api_ntlsa_rpc }, - { "samr", "lsass", api_samr_rpc }, - { "srvsvc", "ntsvcs", api_srvsvc_rpc }, - { "wkssvc", "ntsvcs", api_wkssvc_rpc }, - { "browser", "ntsvcs", api_brs_rpc }, - { "svcctl", "ntsvcs", api_svcctl_rpc }, - { "NETLOGON", "lsass", api_netlog_rpc }, - { "winreg", "winreg", api_reg_rpc }, - { "spoolss", "spoolss", api_spoolss_rpc }, - { NULL, NULL, NULL } -}; -#endif void close_msrpc_command_processor(void) { -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/rpc_server/srv_pipe.c | 1510 ++++++++++++++++++++--------------------- 1 file changed, 750 insertions(+), 760 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index d15cc1248c..236558ba70 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,4 +1,3 @@ - /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -6,6 +5,7 @@ * Copyright (C) Andrew Tridgell 1992-1998 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1997-1998. + * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,15 +43,14 @@ extern int DEBUGLEVEL; -static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len) +static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) { unsigned char *hash = p->ntlmssp_hash; unsigned char index_i = hash[256]; unsigned char index_j = hash[257]; int ind; - for( ind = 0; ind < len; ind++) - { + for( ind = 0; ind < len; ind++) { unsigned char tc; unsigned char t; @@ -71,250 +70,332 @@ static void NTLMSSPcalc_p( rpcsrv_struct *p, unsigned char *data, int len) } /******************************************************************* - frees all temporary data used in construction of pdu + Generate the next PDU to be returned from the data in p->rdata. + We cheat here as this function doesn't handle the special auth + footers of the authenticated bind response reply. ********************************************************************/ -void rpcsrv_free_temp(rpcsrv_struct *l) + +BOOL create_next_pdu(pipes_struct *p) { - mem_free_data(l->rhdr .data); - mem_free_data(l->rfault .data); - mem_free_data(l->rdata_i.data); - mem_free_data(l->rauth .data); - mem_free_data(l->rverf .data); - mem_free_data(l->rntlm .data); -} + RPC_HDR_RESP hdr_resp; + BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); + BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); + uint32 data_len; + uint32 data_space_available; + uint32 data_len_left; + prs_struct outgoing_pdu; + char *data; + char *data_from; + uint32 data_pos; -/******************************************************************* - turns a DCE/RPC request into a DCE/RPC reply + memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); - this is where the data really should be split up into an array of - headers and data sections. + /* Change the incoming request header to a response. */ + p->hdr.pkt_type = RPC_RESPONSE; - ********************************************************************/ -BOOL create_rpc_reply(rpcsrv_struct *l, uint32 data_start) -{ - char *data; - BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN); - BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL); - uint32 data_len; - uint32 auth_len; - uint32 data_end = l->rdata.offset + (l->ntlmssp_auth ? (8 + 16) : 0); + /* Set up rpc header flags. */ + if (p->data_sent_length == 0) + p->hdr.flags = RPC_FLG_FIRST; + else + p->hdr.flags = 0; - DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n", - data_start, data_end, l->hdr_ba.bba.max_tsize)); + /* + * Work out how much we can fit in a sigle PDU. + */ - auth_len = l->hdr.auth_len; + data_space_available = sizeof(p->current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + if(p->ntlmssp_auth_validated) + data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); - if (l->ntlmssp_auth) - { - DEBUG(10,("create_rpc_reply: auth\n")); - if (auth_len != 16) - { - return False; - } - } + /* + * The amount we send is the minimum of the available + * space and the amount left to send. + */ - prs_init(&l->rhdr , 0x18, 4, 0, False); - prs_init(&l->rauth, 1024, 4, 0, False); - prs_init(&l->rverf, 0x10, 4, 0, False); + data_len_left = prs_offset(&p->rdata) - p->data_sent_length; - l->hdr.pkt_type = RPC_RESPONSE; /* mark header as an rpc response */ + /* + * Ensure there really is data left to send. + */ - /* set up rpc header (fragmentation issues) */ - if (data_start == 0) - { - l->hdr.flags = RPC_FLG_FIRST; - } - else - { - l->hdr.flags = 0; + if(!data_len_left) { + DEBUG(0,("create_next_pdu: no data left to send !\n")); + return False; } - l->hdr_resp.alloc_hint = data_end - data_start; /* calculate remaining data to be sent */ + data_len = MIN(data_len_left, data_space_available); - if (l->hdr_resp.alloc_hint + 0x18 <= l->hdr_ba.bba.max_tsize) - { - l->hdr.flags |= RPC_FLG_LAST; - l->hdr.frag_len = l->hdr_resp.alloc_hint + 0x18; - } - else - { - l->hdr.frag_len = l->hdr_ba.bba.max_tsize; - } + /* + * Set up the alloc hint. This should be the data left to + * send. + */ - if (l->ntlmssp_auth) - { - l->hdr_resp.alloc_hint -= auth_len + 8; + hdr_resp.alloc_hint = data_len_left; + + /* + * Set up the header lengths. + */ + + if (p->ntlmssp_auth_validated) { + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + + RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN; + p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; + } else { + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; + p->hdr.auth_len = 0; } - if (l->ntlmssp_auth) - { - data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; + /* + * Work out if this PDU will be the last. + */ + + if(p->data_sent_length + data_len >= prs_offset(&p->rdata)) + p->hdr.flags |= RPC_FLG_LAST; + + /* + * Init the parse struct to point at the outgoing + * data. + */ + + prs_init( &outgoing_pdu, 0, 4, MARSHALL); + prs_give_memory( &outgoing_pdu, (char *)p->current_pdu, sizeof(p->current_pdu), False); + + /* Store the header in the data stream. */ + if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n")); + return False; } - else - { - data_len = l->hdr.frag_len - 0x18; + + if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n")); + return False; } - l->rhdr.data->offset.start = 0; - l->rhdr.data->offset.end = 0x18; + /* Store the current offset. */ + data_pos = prs_offset(&outgoing_pdu); - /* store the header in the data stream */ - smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0); - smb_io_rpc_hdr_resp("resp", &(l->hdr_resp), &(l->rhdr), 0); + /* Copy the data into the PDU. */ + data_from = prs_data_p(&p->rdata) + p->data_sent_length; + + if(!prs_append_data(&outgoing_pdu, data_from, data_len)) { + DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len)); + return False; + } - /* don't use rdata: use rdata_i instead, which moves... */ - /* make a pointer to the rdata data, NOT A COPY */ + /* + * Set data to point to where we copied the data into. + */ - l->rdata_i.data = NULL; - prs_init(&l->rdata_i, 0, l->rdata.align, l->rdata.data->margin, l->rdata.io); - data = mem_data(&(l->rdata.data), data_start); - mem_create(l->rdata_i.data, data, 0, data_len, 0, False); - l->rdata_i.offset = data_len; + data = prs_data_p(&outgoing_pdu) + data_pos; - if (auth_len > 0) - { + if (p->hdr.auth_len > 0) { uint32 crc32 = 0; - DEBUG(5,("create_rpc_reply: sign: %s seal: %s data %d auth %d\n", - BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); + DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n", + BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len)); - if (auth_seal) - { - crc32 = crc32_calc_buffer(data_len, data); - NTLMSSPcalc_p(l, (uchar*)data, data_len); + if (auth_seal) { + crc32 = crc32_calc_buffer(data, data_len); + NTLMSSPcalc_p(p, (uchar*)data, data_len); } - if (auth_seal || auth_verify) - { - make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0x08, (auth_verify ? 1 : 0)); - smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, &l->rauth, 0); + if (auth_seal || auth_verify) { + RPC_HDR_AUTH auth_info; + + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, + (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0)); + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); + return False; + } } - if (auth_verify) - { - char *auth_data; - l->ntlmssp_seq_num++; - make_rpc_auth_ntlmssp_chk(&l->ntlmssp_chk, NTLMSSP_SIGN_VERSION, crc32, l->ntlmssp_seq_num++); - smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), &l->rverf, 0); - auth_data = mem_data(&l->rverf.data, 4); - NTLMSSPcalc_p(l, (uchar*)auth_data, 12); + if (auth_verify) { + RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; + char *auth_data = prs_data_p(&outgoing_pdu); + + p->ntlmssp_seq_num++; + init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION, + crc32, p->ntlmssp_seq_num++); + auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4; + if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n")); + return False; + } + NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); } } - /* set up the data chain */ - if (l->ntlmssp_auth) - { - prs_link(NULL , &l->rhdr , &l->rdata_i); - prs_link(&l->rhdr , &l->rdata_i, &l->rauth ); - prs_link(&l->rdata_i, &l->rauth , &l->rverf ); - prs_link(&l->rauth , &l->rverf , NULL ); - } - else - { - prs_link(NULL , &l->rhdr , &l->rdata_i); - prs_link(&l->rhdr, &l->rdata_i, NULL ); - } + /* + * Setup the counts for this PDU. + */ - return l->rhdr.data != NULL && l->rhdr.offset == 0x18; + p->data_sent_length += data_len; + p->current_pdu_len = p->hdr.frag_len; + p->current_pdu_sent = 0; + + return True; } -static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l) +/******************************************************************* + Process an NTLMSSP authentication response. + If this function succeeds, the user has been authenticated + and their domain, name and calling workstation stored in + the pipe struct. + The initial challenge is stored in p->challenge. + *******************************************************************/ + +static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp) { - uchar *pwd = NULL; - uchar null_pwd[16]; uchar lm_owf[24]; - uchar nt_owf[128]; - size_t lm_owf_len; - size_t nt_owf_len; - size_t usr_len; - size_t dom_len; - size_t wks_len; - BOOL anonymous = False; + uchar nt_owf[24]; + fstring user_name; + fstring unix_user_name; + fstring domain; + fstring wks; + BOOL guest_user = False; + struct smb_passwd *smb_pass = NULL; + struct passwd *pass = NULL; + uchar null_smb_passwd[16]; + uchar *smb_passwd_ptr = NULL; + + DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); - memset(null_pwd, 0, sizeof(null_pwd)); + memset(p->user_name, '\0', sizeof(p->user_name)); + memset(p->unix_user_name, '\0', sizeof(p->unix_user_name)); + memset(p->domain, '\0', sizeof(p->domain)); + memset(p->wks, '\0', sizeof(p->wks)); - DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); + /* + * Setup an empty password for a guest user. + */ - lm_owf_len = l->ntlmssp_resp.hdr_lm_resp.str_str_len; - nt_owf_len = l->ntlmssp_resp.hdr_nt_resp.str_str_len; - usr_len = l->ntlmssp_resp.hdr_usr .str_str_len; - dom_len = l->ntlmssp_resp.hdr_domain .str_str_len; - wks_len = l->ntlmssp_resp.hdr_wks .str_str_len; + memset(null_smb_passwd,0,16); - if (lm_owf_len == 0 && nt_owf_len == 0 && - usr_len == 0 && dom_len == 0 && wks_len == 0) - { - anonymous = True; - } - else - { - if (lm_owf_len == 0) return False; - if (nt_owf_len == 0) return False; - if (l->ntlmssp_resp.hdr_usr .str_str_len == 0) return False; - if (l->ntlmssp_resp.hdr_domain .str_str_len == 0) return False; - if (l->ntlmssp_resp.hdr_wks .str_str_len == 0) return False; + /* + * We always negotiate UNICODE. + */ + + if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) { + fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); + fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); + fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); + } else { + fstrcpy(user_name, ntlmssp_resp->user); + fstrcpy(domain, ntlmssp_resp->domain); + fstrcpy(wks, ntlmssp_resp->wks); } - if (lm_owf_len > sizeof(lm_owf)) return False; - if (nt_owf_len > sizeof(nt_owf)) return False; + DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks)); - memcpy(lm_owf, l->ntlmssp_resp.lm_resp, sizeof(lm_owf)); - memcpy(nt_owf, l->ntlmssp_resp.nt_resp, sizeof(nt_owf)); + memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf)); + memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf)); #ifdef DEBUG_PASSWORD DEBUG(100,("lm, nt owfs, chal\n")); - dump_data(100, lm_owf, sizeof(lm_owf)); - dump_data(100, nt_owf, sizeof(nt_owf)); - dump_data(100, l->ntlmssp_chal.challenge, 8); + dump_data(100, (char *)lm_owf, sizeof(lm_owf)); + dump_data(100, (char *)nt_owf, sizeof(nt_owf)); + dump_data(100, (char *)p->challenge, 8); #endif - memset(l->user_name, 0, sizeof(l->user_name)); - memset(l->domain , 0, sizeof(l->domain )); - memset(l->wks , 0, sizeof(l->wks )); + /* + * Allow guest access. Patch from Shirish Kalele . + */ + + if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_lm_resp.str_str_len==0) && + (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) { + + guest_user = True; + + fstrcpy(unix_user_name, lp_guestaccount(-1)); + DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name)); + + smb_passwd_ptr = null_smb_passwd; + + } else { + + /* + * Pass the user through the NT -> unix user mapping + * function. + */ + + fstrcpy(unix_user_name, user_name); + (void)map_username(unix_user_name); + + /* + * Do the length checking only if user is not NULL. + */ + + if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_usr.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_domain.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_wks.str_str_len == 0) + return False; - if (IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_UNICODE)) - { - unibuf_to_ascii(l->user_name, l->ntlmssp_resp.user, - MIN(l->ntlmssp_resp.hdr_usr .str_str_len/2, - sizeof(l->user_name)-1)); - unibuf_to_ascii(l->domain , l->ntlmssp_resp.domain, - MIN(l->ntlmssp_resp.hdr_domain.str_str_len/2, - sizeof(l->domain )-1)); - unibuf_to_ascii(l->wks , l->ntlmssp_resp.wks, - MIN(l->ntlmssp_resp.hdr_wks .str_str_len/2, - sizeof(l->wks )-1)); - } - else - { - fstrcpy(l->user_name, l->ntlmssp_resp.user ); - fstrcpy(l->domain , l->ntlmssp_resp.domain); - fstrcpy(l->wks , l->ntlmssp_resp.wks ); } + /* + * Find the user in the unix password db. + */ - if (anonymous) - { - DEBUG(5,("anonymous user session\n")); - mdfour(l->user_sess_key, null_pwd, 16); - pwd = null_pwd; - l->ntlmssp_validated = True; + if(!(pass = Get_Pwnam(unix_user_name,True))) { + DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name)); + return(False); } - else - { - DEBUG(5,("user: %s domain: %s wks: %s\n", l->user_name, l->domain, l->wks)); - become_root(False); - l->ntlmssp_validated = check_domain_security(l->user_name, l->domain, - (uchar*)l->ntlmssp_chal.challenge, - lm_owf, lm_owf_len, - nt_owf, nt_owf_len, - l->user_sess_key); - unbecome_root(False); + + if(!guest_user) { + + become_root(True); + + if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain, + (uchar*)p->challenge, lm_owf, nt_owf, NULL))) { + DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ +failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name )); + unbecome_root(True); + return False; + } + + if(!(smb_pass = getsmbpwnam(unix_user_name))) { + DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", + unix_user_name)); + unbecome_root(True); + return False; + } + + unbecome_root(True); + + if (smb_pass == NULL) { + DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", + unix_user_name)); + return(False); + } + + /* Quit if the account was disabled. */ + if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) { + DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name)); + return(False); + } + + if(!smb_pass->smb_nt_passwd) { + DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name)); + return(False); + } + + smb_passwd_ptr = smb_pass->smb_passwd; } - if (l->ntlmssp_validated && pwd != NULL) + /* + * Set up the sign/seal data. + */ + { uchar p24[24]; - NTLMSSPOWFencrypt(pwd, lm_owf, p24); + NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24); { unsigned char j = 0; int ind; @@ -327,761 +408,670 @@ static BOOL api_pipe_ntlmssp_verify(rpcsrv_struct *l) k2[7] = 0xb0; for (ind = 0; ind < 256; ind++) - { - l->ntlmssp_hash[ind] = (unsigned char)ind; - } + p->ntlmssp_hash[ind] = (unsigned char)ind; - for( ind = 0; ind < 256; ind++) - { + for( ind = 0; ind < 256; ind++) { unsigned char tc; - j += (l->ntlmssp_hash[ind] + k2[ind%8]); + j += (p->ntlmssp_hash[ind] + k2[ind%8]); - tc = l->ntlmssp_hash[ind]; - l->ntlmssp_hash[ind] = l->ntlmssp_hash[j]; - l->ntlmssp_hash[j] = tc; + tc = p->ntlmssp_hash[ind]; + p->ntlmssp_hash[ind] = p->ntlmssp_hash[j]; + p->ntlmssp_hash[j] = tc; } - l->ntlmssp_hash[256] = 0; - l->ntlmssp_hash[257] = 0; + p->ntlmssp_hash[256] = 0; + p->ntlmssp_hash[257] = 0; } - l->ntlmssp_seq_num = 0; - } - else - { - l->ntlmssp_validated = False; +/* NTLMSSPhash(p->ntlmssp_hash, p24); */ + p->ntlmssp_seq_num = 0; + } - return l->ntlmssp_validated; -} + fstrcpy(p->user_name, user_name); + fstrcpy(p->unix_user_name, unix_user_name); + fstrcpy(p->domain, domain); + fstrcpy(p->wks, wks); -static BOOL api_pipe_ntlmssp(rpcsrv_struct *l, prs_struct *pd) -{ - /* receive a negotiate; send a challenge; receive a response */ - switch (l->auth_verifier.msg_type) - { - case NTLMSSP_NEGOTIATE: - { - smb_io_rpc_auth_ntlmssp_neg("", &l->ntlmssp_neg, pd, 0); - break; - } - case NTLMSSP_AUTH: - { - smb_io_rpc_auth_ntlmssp_resp("", &l->ntlmssp_resp, pd, 0); - if (!api_pipe_ntlmssp_verify(l)) - { - pd->offset = 0; - } - break; - } - default: - { - /* NTLMSSP expected: unexpected message type */ - DEBUG(3,("unexpected message type in NTLMSSP %d\n", - l->auth_verifier.msg_type)); - return False; - } - } + /* + * Store the UNIX credential data (uid/gid pair) in the pipe structure. + */ + + p->uid = pass->pw_uid; + p->gid = pass->pw_gid; - return (pd->offset != 0); + p->ntlmssp_auth_validated = True; + return True; } +/******************************************************************* + The switch table for the pipe names and the functions to handle them. + *******************************************************************/ + struct api_cmd { char * pipe_clnt_name; char * pipe_srv_name; - BOOL (*fn) (rpcsrv_struct *, prs_struct *); + BOOL (*fn) (pipes_struct *, prs_struct *); }; -static struct api_cmd **api_fd_commands = NULL; -uint32 num_cmds = 0; - -static void api_cmd_free(struct api_cmd *item) -{ - if (item != NULL) - { - if (item->pipe_clnt_name != NULL) - { - free(item->pipe_clnt_name); - } - if (item->pipe_srv_name != NULL) - { - free(item->pipe_srv_name); - } - free(item); - } -} - -static struct api_cmd *api_cmd_dup(const struct api_cmd *from) +static struct api_cmd api_fd_commands[] = { - struct api_cmd *copy = NULL; - if (from == NULL) - { - return NULL; - } - copy = (struct api_cmd *) malloc(sizeof(struct api_cmd)); - if (copy != NULL) - { - ZERO_STRUCTP(copy); - if (from->pipe_clnt_name != NULL) - { - copy->pipe_clnt_name = strdup(from->pipe_clnt_name ); - } - if (from->pipe_srv_name != NULL) - { - copy->pipe_srv_name = strdup(from->pipe_srv_name); - } - if (from->fn != NULL) - { - copy->fn = from->fn; - } - } - return copy; -} + { "lsarpc", "lsass", api_ntlsa_rpc }, + { "samr", "lsass", api_samr_rpc }, + { "srvsvc", "ntsvcs", api_srvsvc_rpc }, + { "wkssvc", "ntsvcs", api_wkssvc_rpc }, + { "NETLOGON", "lsass", api_netlog_rpc }, +#if DISABLED_IN_2_0 + { "winreg", "winreg", api_reg_rpc }, +#endif + { NULL, NULL, NULL } +}; -static void free_api_cmd_array(uint32 num_entries, struct api_cmd **entries) -{ - void(*fn)(void*) = (void(*)(void*))&api_cmd_free; - free_void_array(num_entries, (void**)entries, *fn); -} +/******************************************************************* + This is the client reply to our challenge for an authenticated + bind request. The challenge we sent is in p->challenge. +*******************************************************************/ -static struct api_cmd* add_api_cmd_to_array(uint32 *len, - struct api_cmd ***array, - const struct api_cmd *name) +static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) { - void*(*fn)(const void*) = (void*(*)(const void*))&api_cmd_dup; - return (struct api_cmd*)add_copy_to_array(len, - (void***)array, (const void*)name, *fn, False); - -} + RPC_HDR_AUTHA autha_info; + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; + DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); -void close_msrpc_command_processor(void) -{ - free_api_cmd_array(num_cmds, api_fd_commands); -} + if (p->hdr.auth_len == 0) { + DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n")); + return False; + } -void add_msrpc_command_processor(char* pipe_name, - char* process_name, - BOOL (*fn) (rpcsrv_struct *, prs_struct *)) -{ - struct api_cmd cmd; - cmd.pipe_clnt_name = pipe_name; - cmd.pipe_srv_name = process_name; - cmd.fn = fn; + /* + * Decode the authentication verifier response. + */ - add_api_cmd_to_array(&num_cmds, &api_fd_commands, &cmd); -} + if(!smb_io_rpc_hdr_autha("", &autha_info, pd, 0)) { + DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n")); + return False; + } -static BOOL api_pipe_bind_auth_resp(rpcsrv_struct *l, prs_struct *pd) -{ - DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); + if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) { + DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n", + (int)autha_info.auth_type, (int)autha_info.auth_level )); + return False; + } - if (l->hdr.auth_len == 0) return False; + if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) { + DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n")); + return False; + } - /* decode the authentication verifier response */ - smb_io_rpc_hdr_autha("", &l->autha_info, pd, 0); - if (pd->offset == 0) return False; + /* + * Ensure this is a NTLMSSP_AUTH packet type. + */ - if (!rpc_hdr_auth_chk(&(l->auth_info))) return False; + if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) { + DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n")); + return False; + } - smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0); - if (pd->offset == 0) return False; + if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, pd, 0)) { + DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n")); + return False; + } - if (!rpc_auth_ntlmssp_verifier_chk(&(l->auth_verifier), "NTLMSSP", NTLMSSP_AUTH)) return False; + /* + * The following call actually checks the challenge/response data. + * for correctness against the given DOMAIN\user name. + */ - return api_pipe_ntlmssp(l, pd); + if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp)) + return False; + + return True; } -static BOOL api_pipe_fault_resp(rpcsrv_struct *l, prs_struct *pd, uint32 status) +/******************************************************************* + Marshall a bind_nak pdu. +*******************************************************************/ + +static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd) { - DEBUG(5,("api_pipe_fault_resp: make response\n")); + prs_struct outgoing_rpc; + RPC_HDR nak_hdr; + uint16 zero = 0; + + /* + * Marshall directly into the outgoing PDU space. We + * must do this as we need to set to the bind response + * header and are never sending more than one PDU here. + */ - prs_init(&(l->rhdr ), 0x18, 4, 0, False); - prs_init(&(l->rfault ), 0x8 , 4, 0, False); + prs_init( &outgoing_rpc, 0, 4, MARSHALL); + prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False); - /***/ - /*** set up the header, response header and fault status ***/ - /***/ - l->hdr_fault.status = status; - l->hdr_fault.reserved = 0x0; + /* + * Initialize a bind_nak header. + */ - l->hdr_resp.alloc_hint = 0x0; - l->hdr_resp.cancel_count = 0x0; - l->hdr_resp.reserved = 0x0; + init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0); - make_rpc_hdr(&l->hdr, RPC_FAULT, RPC_FLG_NOCALL | RPC_FLG_FIRST | RPC_FLG_LAST, - l->hdr.call_id, - 0x20, - 0); + /* + * Marshall the header into the outgoing PDU. + */ - smb_io_rpc_hdr ("hdr" , &(l->hdr ), &(l->rhdr), 0); - smb_io_rpc_hdr_resp ("resp" , &(l->hdr_resp ), &(l->rhdr), 0); - smb_io_rpc_hdr_fault("fault", &(l->hdr_fault), &(l->rfault), 0); - mem_realloc_data(l->rhdr.data, l->rhdr.offset); - mem_realloc_data(l->rfault.data, l->rfault.offset); + if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) { + DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n")); + return False; + } - /***/ - /*** link rpc header and fault together ***/ - /***/ + /* + * Now add the reject reason. + */ - prs_link(NULL , &l->rhdr , &l->rfault); - prs_link(&l->rhdr, &l->rfault, NULL ); + if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) + return False; + + p->data_sent_length = 0; + p->current_pdu_len = prs_offset(&outgoing_rpc); + p->current_pdu_sent = 0; return True; } -static BOOL srv_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd, - const char* ack_pipe_name, - enum RPC_PKT_TYPE pkt_type) +/******************************************************************* + Respond to a pipe bind request. +*******************************************************************/ + +static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) { + RPC_HDR_BA hdr_ba; + RPC_HDR_RB hdr_rb; + RPC_HDR_AUTH auth_info; uint16 assoc_gid; + fstring ack_pipe_name; + prs_struct out_hdr_ba; + prs_struct out_auth; + prs_struct outgoing_rpc; + int i = 0; + int auth_len = 0; + + p->ntlmssp_auth_requested = False; + + DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); + + /* + * Try and find the correct pipe name to ensure + * that this is a pipe name we support. + */ - l->ntlmssp_auth = False; + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) { + DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + api_fd_commands[i].pipe_clnt_name, + api_fd_commands[i].pipe_srv_name)); + fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name); + break; + } + } + + if (api_fd_commands[i].fn == NULL) { + DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", + p->name )); + if(!setup_bind_nak(p, pd)) + return False; + return True; + } /* decode the bind request */ - smb_io_rpc_hdr_rb("", &l->hdr_rb, pd, 0); + if(!smb_io_rpc_hdr_rb("", &hdr_rb, pd, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); + return False; + } - if (pd->offset == 0) return False; + /* + * Check if this is an authenticated request. + */ - if (l->hdr.auth_len != 0) - { - /* decode the authentication verifier */ - smb_io_rpc_hdr_auth ("", &l->auth_info , pd, 0); - if (pd->offset == 0) return False; + if (p->hdr.auth_len != 0) { + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; - l->ntlmssp_auth = l->auth_info.auth_type = 0x0a; + /* + * Decode the authentication verifier. + */ - if (l->ntlmssp_auth) - { - smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, pd, 0); - if (pd->offset == 0) return False; + if(!smb_io_rpc_hdr_auth("", &auth_info, pd, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); + return False; + } - l->ntlmssp_auth = strequal(l->auth_verifier.signature, "NTLMSSP"); + /* + * We only support NTLMSSP_AUTH_TYPE requests. + */ + + if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) { + DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", + auth_info.auth_type )); + return False; } - if (l->ntlmssp_auth) - { - if (!api_pipe_ntlmssp(l, pd)) return False; + if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); + return False; + } + + if(!strequal(auth_verifier.signature, "NTLMSSP")) { + DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n")); + return False; + } + + if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { + DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", + auth_verifier.msg_type)); + return False; } + + if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, pd, 0)) { + DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); + return False; + } + + p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; + p->ntlmssp_auth_requested = True; } + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, p->pipe_srv_name); + DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); - prs_init(&(l->rdata), 1024, 4, 0, False); - prs_init(&(l->rhdr ), 0x18, 4, 0, False); - prs_init(&(l->rauth), 1024, 4, 0, False); - prs_init(&(l->rverf), 0x08, 4, 0, False); - prs_init(&(l->rntlm), 1024, 4, 0, False); + /* + * Marshall directly into the outgoing PDU space. We + * must do this as we need to set to the bind response + * header and are never sending more than one PDU here. + */ - /***/ - /*** do the bind ack first ***/ - /***/ + prs_init( &outgoing_rpc, 0, 4, MARSHALL); + prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False); - if (l->ntlmssp_auth) - { - assoc_gid = 0x7a77; + /* + * Setup the memory to marshall the ba header, and the + * auth footers. + */ + + if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) { + DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); + return False; } - else - { - assoc_gid = l->hdr_rb.bba.assoc_gid; + + if(!prs_init(&out_auth, 1024, 4, MARSHALL)) { + DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n")); + prs_mem_free(&out_hdr_ba); + return False; } - make_rpc_hdr_ba(&l->hdr_ba, - l->hdr_rb.bba.max_tsize, - l->hdr_rb.bba.max_rsize, + if (p->ntlmssp_auth_requested) + assoc_gid = 0x7a77; + else + assoc_gid = hdr_rb.bba.assoc_gid; + + /* + * Create the bind response struct. + */ + + init_rpc_hdr_ba(&hdr_ba, + hdr_rb.bba.max_tsize, + hdr_rb.bba.max_rsize, assoc_gid, ack_pipe_name, 0x1, 0x0, 0x0, - &(l->hdr_rb.transfer)); + &hdr_rb.transfer); + + /* + * and marshall it. + */ - smb_io_rpc_hdr_ba("", &l->hdr_ba, &l->rdata, 0); - mem_realloc_data(l->rdata.data, l->rdata.offset); + if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n")); + goto err_exit; + } - /***/ - /*** now the authentication ***/ - /***/ + /* + * Now the authentication. + */ - if (l->ntlmssp_auth) - { - uint8 challenge[8]; - generate_random_buffer(challenge, 8, False); + if (p->ntlmssp_auth_requested) { + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal; - /*** authentication info ***/ + generate_random_buffer(p->challenge, 8, False); - make_rpc_hdr_auth(&l->auth_info, 0x0a, 0x06, 0, 1); - smb_io_rpc_hdr_auth("", &l->auth_info, &l->rverf, 0); - mem_realloc_data(l->rverf.data, l->rverf.offset); + /*** Authentication info ***/ + + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1); + if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); + goto err_exit; + } /*** NTLMSSP verifier ***/ - make_rpc_auth_ntlmssp_verifier(&l->auth_verifier, - "NTLMSSP", NTLMSSP_CHALLENGE); - smb_io_rpc_auth_ntlmssp_verifier("", &l->auth_verifier, &l->rauth, 0); - mem_realloc_data(l->rauth.data, l->rauth.offset); + init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE); + if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n")); + goto err_exit; + } /* NTLMSSP challenge ***/ - make_rpc_auth_ntlmssp_chal(&l->ntlmssp_chal, - 0x000082b1, challenge); - smb_io_rpc_auth_ntlmssp_chal("", &l->ntlmssp_chal, &l->rntlm, 0); - mem_realloc_data(l->rntlm.data, l->rntlm.offset); - } + init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge); + if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n")); + goto err_exit; + } - /***/ - /*** then do the header, now we know the length ***/ - /***/ + /* Auth len in the rpc header doesn't include auth_header. */ + auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; + } - make_rpc_hdr(&l->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, - l->hdr.call_id, - l->rdata.offset + l->rverf.offset + l->rauth.offset + l->rntlm.offset + 0x10, - l->rauth.offset + l->rntlm.offset); + /* + * Create the header, now we know the length. + */ - smb_io_rpc_hdr("", &l->hdr, &l->rhdr, 0); - mem_realloc_data(l->rhdr.data, l->rdata.offset); + init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, + RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), + auth_len); - /***/ - /*** link rpc header, bind acknowledgment and authentication responses ***/ - /***/ + /* + * Marshall the header into the outgoing PDU. + */ - if (l->ntlmssp_auth) - { - prs_link(NULL , &l->rhdr , &l->rdata); - prs_link(&l->rhdr , &l->rdata, &l->rverf); - prs_link(&l->rdata, &l->rverf, &l->rauth); - prs_link(&l->rverf, &l->rauth, &l->rntlm); - prs_link(&l->rauth, &l->rntlm, NULL ); + if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) { + DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n")); + goto err_exit; } - else - { - prs_link(NULL , &l->rhdr , &l->rdata); - prs_link(&l->rhdr, &l->rdata, NULL ); + + /* + * Now add the RPC_HDR_BA and any auth needed. + */ + + if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) { + DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n")); + goto err_exit; } - return True; -} + if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) { + DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n")); + goto err_exit; + } -static BOOL api_pipe_bind_and_alt_req(rpcsrv_struct *l, prs_struct *pd, - const char* name, - enum RPC_PKT_TYPE pkt_type) -{ - fstring ack_pipe_name; - fstring pipe_srv_name; - int i = 0; + /* + * Setup the lengths for the initial reply. + */ - DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); + p->data_sent_length = 0; + p->current_pdu_len = prs_offset(&outgoing_rpc); + p->current_pdu_sent = 0; - for (i = 0; i < num_cmds; i++) - { - if (strequal(api_fd_commands[i]->pipe_clnt_name, name) && - api_fd_commands[i]->fn != NULL) - { - DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", - api_fd_commands[i]->pipe_clnt_name, - api_fd_commands[i]->pipe_srv_name)); - fstrcpy(pipe_srv_name, api_fd_commands[i]->pipe_srv_name); - break; - } - } + prs_mem_free(&out_hdr_ba); + prs_mem_free(&out_auth); - if (api_fd_commands[i]->fn == NULL) return False; + return True; - switch (pkt_type) - { - case RPC_BINDACK: - { - /* name has to be \PIPE\xxxxx */ - fstrcpy(ack_pipe_name, "\\PIPE\\"); - fstrcat(ack_pipe_name, pipe_srv_name); - break; - } - case RPC_ALTCONTRESP: - { - /* secondary address CAN be NULL - * as the specs says it's ignored. - * It MUST NULL to have the spoolss working. - */ - fstrcpy(ack_pipe_name, ""); - break; - } - default: - { - return False; - } - } - return srv_pipe_bind_and_alt_req(l, pd, ack_pipe_name, pkt_type); -} + err_exit: -/* - * The RPC Alter-Context call is used only by the spoolss pipe - * simply because there is a bug (?) in the MS unmarshalling code - * or in the marshalling code. If it's in the later, then Samba - * have the same bug. - */ -static BOOL api_pipe_bind_req(rpcsrv_struct *l, prs_struct *pd, - const char* name) -{ - return api_pipe_bind_and_alt_req(l, pd, name, RPC_BINDACK); + prs_mem_free(&out_hdr_ba); + prs_mem_free(&out_auth); + return False; } -static BOOL api_pipe_alt_req(rpcsrv_struct *l, prs_struct *pd, - const char* name) -{ - return api_pipe_bind_and_alt_req(l, pd, name, RPC_ALTCONTRESP); -} +/**************************************************************************** + Deal with sign & seal processing on an RPC request. +****************************************************************************/ -static BOOL api_pipe_auth_process(rpcsrv_struct *l, prs_struct *pd) +static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) { - BOOL auth_verify = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SIGN); - BOOL auth_seal = IS_BITS_SET_ALL(l->ntlmssp_chal.neg_flags, NTLMSSP_NEGOTIATE_SEAL); + /* + * We always negotiate the following two bits.... + */ + BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); + BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); int data_len; int auth_len; uint32 old_offset; uint32 crc32 = 0; - auth_len = l->hdr.auth_len; + auth_len = p->hdr.auth_len; - if (auth_len != 16 && auth_verify) - { + if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) { + DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len )); return False; } - data_len = l->hdr.frag_len - auth_len - (auth_verify ? 8 : 0) - 0x18; + /* + * The following is that length of the data we must verify or unseal. + * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN + * preceeding the auth_data. + */ + + data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - + (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len; DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n", BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); - if (auth_seal) - { - char *data = mem_data(&pd->data, pd->offset); - DEBUG(5,("api_pipe_auth_process: data %d\n", pd->offset)); - NTLMSSPcalc_p(l, (uchar*)data, data_len); - crc32 = crc32_calc_buffer(data_len, data); + if (auth_seal) { + char *data = prs_data_p(rpc_in) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; + NTLMSSPcalc_p(p, (uchar*)data, data_len); + crc32 = crc32_calc_buffer(data, data_len); } - /*** skip the data, record the offset so we can restore it again */ - old_offset = pd->offset; + old_offset = prs_offset(rpc_in); - if (auth_seal || auth_verify) - { - pd->offset += data_len; - smb_io_rpc_hdr_auth("hdr_auth", &l->auth_info, pd, 0); - } + if (auth_seal || auth_verify) { + RPC_HDR_AUTH auth_info; - if (auth_verify) - { - char *req_data = mem_data(&pd->data, pd->offset + 4); - DEBUG(5,("api_pipe_auth_process: auth %d\n", pd->offset + 4)); - NTLMSSPcalc_p(l, (uchar*)req_data, 12); - smb_io_rpc_auth_ntlmssp_chk("auth_sign", &(l->ntlmssp_chk), pd, 0); + if(!prs_set_offset(rpc_in, old_offset + data_len)) { + DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n", + (unsigned int)old_offset + data_len )); + return False; + } - if (!rpc_auth_ntlmssp_chk(&(l->ntlmssp_chk), crc32, - l->ntlmssp_seq_num)) - { + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { + DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n")); return False; } } - pd->offset = old_offset; - - return True; -} - -static BOOL api_pipe_request(rpcsrv_struct *l, prs_struct *pd, const char* name) -{ - int i = 0; - - if (l->ntlmssp_auth && l->ntlmssp_validated) - { - if (!api_pipe_auth_process(l, pd)) return False; + if (auth_verify) { + RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; + char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4; - DEBUG(0,("api_pipe_request: **** MUST CALL become_user() HERE **** \n")); -#if 0 - become_user(); -#endif - } + DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4)); - for (i = 0; i < num_cmds; i++) - { - if (strequal(api_fd_commands[i]->pipe_clnt_name, name) && - api_fd_commands[i]->fn != NULL) - { - DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i]->pipe_clnt_name)); - return api_fd_commands[i]->fn(l, pd); + /* + * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the + * incoming buffer. + */ + if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) { + DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n", + RPC_AUTH_NTLMSSP_CHK_LEN - 4 )); + return False; } - } - return False; -} - -BOOL rpc_add_to_pdu(prs_struct *ps, const char *data, int len) -{ - int prev_size; - int new_size; - char *to = NULL; - - ps->offset = 0; - if (ps->data == NULL) - { - DEBUG(10,("rpc_add_to_pdu: new_size: %d\n", len)); - prs_init(ps, len, 4, 0, True); - prev_size = 0; - new_size = len; - if (ps->data == NULL) - { + NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); + if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) { + DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n")); return False; } - } - else - { - prev_size = ps->data->data_used; - new_size = prev_size + len; - DEBUG(10,("rpc_add_to_pdu: prev_size: %d new_size: %d\n", - prev_size, new_size)); - if (!mem_realloc_data(ps->data, new_size)) - { + + if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) { + DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n")); return False; } } - DEBUG(10,("ps->data->start: %d\n", ps->data->offset.start)); - ps->data->offset.start = 0x0; + /* + * Return the current pointer to the data offset. + */ - to = mem_data(&ps->data, prev_size); - if (to == NULL) - { - DEBUG(10,("rpc_add_to_pdu: data could not be found\n")); - return False; - } - if (ps->data->data_used != new_size) - { - DEBUG(10,("rpc_add_to_pdu: ERROR: data used %d new_size %d\n", - ps->data->data_used, new_size)); + if(!prs_set_offset(rpc_in, old_offset)) { + DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n", + (unsigned int)old_offset )); return False; } - memcpy(to, data, len); + return True; } -static BOOL rpc_redir_remote(pipes_struct *p, prs_struct *req, prs_struct *resp) +/**************************************************************************** + Find the correct RPC function to call for this request. + If the pipe is authenticated then become the correct UNIX user + before doing the call. +****************************************************************************/ + +static BOOL api_pipe_request(pipes_struct *p, prs_struct *rpc_in) { - DEBUG(10,("rpc_redirect\n")); + int i = 0; + BOOL ret = False; + BOOL changed_user_id = False; - if (!msrpc_send_prs(p->m, req)) - { - DEBUG(2,("msrpc redirect send failed\n")); - return False; + if (p->ntlmssp_auth_validated) { + if (!api_pipe_auth_process(p, rpc_in)) + return False; + + if(!become_authenticated_pipe_user(p)) + return False; + + changed_user_id = True; } - if (!msrpc_receive_prs(p->m, resp)) - { - DEBUG(2,("msrpc redirect receive failed\n")); - return False; + + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) { + DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); + ret = api_fd_commands[i].fn(p, rpc_in); + } } - prs_link(NULL, resp, NULL); - prs_debug_out(resp, "redirect", 100); - return True; + + if(changed_user_id) + unbecome_authenticated_pipe_user(p); + + return ret; } -static BOOL rpc_redir_local(rpcsrv_struct *l, prs_struct *req, prs_struct *resp, - const char* name) +/**************************************************************************** + This function is the entry point to processing a DCE/RPC request. + All the data for the request (including RPC headers and authentication + verifiers) must be linearized in the input_data buffer, with a length + of data_len. + + The output is placed into the pipes_struct, and handed back to the + client on demand. +****************************************************************************/ + +BOOL rpc_command(pipes_struct *p, char *input_data, int data_len) { + prs_struct rpc_in; BOOL reply = False; - if (req->data == NULL) return False; + if (input_data == NULL) + return False; + + prs_init(&rpc_in, 0, 4, UNMARSHALL); - /* lkclXXXX still assume that the first complete PDU is always - in a single request!!! + /* + * Hand the data to the prs_struct, but don't let + * it own it. */ - /* process the rpc header */ - req->offset = 0x0; - smb_io_rpc_hdr("", &l->hdr, req, 0); + prs_give_memory( &rpc_in, input_data, (uint32)data_len, False); - if (req->offset == 0) return False; + /* Unmarshall the rpc header */ + if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) { + DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n")); + return False; + } - switch (l->hdr.pkt_type) - { - case RPC_BIND : - { - reply = api_pipe_bind_req(l, req, name); - break; - } - case RPC_ALTCONT: - { - reply = api_pipe_alt_req(l, req, name); - break; - } - case RPC_REQUEST: - { - if (l->ntlmssp_auth && !l->ntlmssp_validated) - { - /* authentication _was_ requested - and it failed. sorry, no deal! - */ - reply = False; - } - else - { - /* read the rpc header */ - smb_io_rpc_hdr_req("req", &(l->hdr_req), req, 0); - reply = api_pipe_request(l, req, name); + /* + * Create the response data buffer. + */ + + if(!pipe_init_outgoing_data(p)) { + DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n")); + return False; + } + + switch (p->hdr.pkt_type) { + case RPC_BIND: + reply = api_pipe_bind_req(p, &rpc_in); + break; + case RPC_REQUEST: + if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) { + /* authentication _was_ requested + and it failed. sorry, no deal! + */ + DEBUG(0,("rpc_command: RPC request received on pipe %s where \ +authentication failed. Denying the request.\n", p->name)); + reply = False; + } else { + /* read the RPC request header */ + if(!smb_io_rpc_hdr_req("req", &p->hdr_req, &rpc_in, 0)) { + DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR_REQ.\n")); + return False; } - break; - } - case RPC_BINDRESP: /* not the real name! */ - { - reply = api_pipe_bind_auth_resp(l, req); - l->ntlmssp_auth = reply; - break; + reply = api_pipe_request(p, &rpc_in); } + break; + case RPC_BINDRESP: /* not the real name! */ + reply = api_pipe_bind_auth_resp(p, &rpc_in); + break; } if (!reply) - { - reply = api_pipe_fault_resp(l, req, 0x1c010002); - } - - if (reply) - { - /* flatten the data into a single pdu */ - reply = prs_copy(resp, &l->rhdr); - } - - /* delete intermediate data used to set up the pdu. leave - rdata alone because that's got the rest of the data in it */ - rpcsrv_free_temp(l); + DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n")); return reply; } -BOOL rpc_send_and_rcv_pdu(pipes_struct *p) -{ - DEBUG(10,("rpc_send_and_rcv_pdu\n")); - - if (p->m != NULL) - { - return rpc_redir_remote(p, &p->smb_pdu, &p->rsmb_pdu); - } - else if (p->l != NULL) - { - return rpc_redir_local(p->l, &p->smb_pdu, &p->rsmb_pdu, - p->name); - } - return False; -} /******************************************************************* - entry point from msrpc to smb. adds data received to pdu; checks - pdu; hands pdu off to msrpc, which gets a pdu back (except in the - case of the RPC_BINDCONT pdu). + Calls the underlying RPC function for a named pipe. ********************************************************************/ -BOOL rpc_to_smb(pipes_struct *p, char *data, int len) -{ - BOOL reply = rpc_add_to_pdu(&p->smb_pdu, data, len); - if (reply && is_complete_pdu(&p->smb_pdu)) - { - p->smb_pdu.offset = p->smb_pdu.data->data_size; - prs_link(NULL, &p->smb_pdu, NULL); - reply = rpc_send_and_rcv_pdu(p); - mem_free_data(p->smb_pdu.data); - prs_init(&p->smb_pdu, 0, 4, 0, True); - - } - return reply; -} - -/******************************************************************* - receives a netlogon pipe and responds. - ********************************************************************/ -static BOOL api_rpc_command(rpcsrv_struct *l, - char *rpc_name, struct api_struct *api_rpc_cmds, - prs_struct *data) +BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds, + prs_struct *rpc_in) { int fn_num; - DEBUG(4,("api_rpc_command: %s op 0x%x - ", rpc_name, l->hdr_req.opnum)); - for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) - { - if (api_rpc_cmds[fn_num].opnum == l->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) - { + /* interpret the command */ + DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); + + for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { + if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name)); break; } } - if (api_rpc_cmds[fn_num].name == NULL) - { + if (api_rpc_cmds[fn_num].name == NULL) { DEBUG(4, ("unknown\n")); return False; } - /* start off with 1024 bytes, and a large safety margin too */ - prs_init(&l->rdata, 1024, 4, SAFETY_MARGIN, False); - /* do the actual command */ - api_rpc_cmds[fn_num].fn(l, data, &(l->rdata)); - - if (l->rdata.data == NULL || l->rdata.offset == 0) - { - mem_free_data(l->rdata.data); + if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->rdata)) { + DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); + prs_mem_free(&p->rdata); return False; } - mem_realloc_data(l->rdata.data, l->rdata.offset); - - DEBUG(10,("called %s\n", rpc_name)); + DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name)); return True; } - - -/******************************************************************* - receives a netlogon pipe and responds. - ********************************************************************/ -BOOL api_rpcTNP(rpcsrv_struct *l, char *rpc_name, struct api_struct *api_rpc_cmds, - prs_struct *data) -{ - if (data == NULL || data->data == NULL) - { - DEBUG(2,("%s: NULL data received\n", rpc_name)); - return False; - } - - /* interpret the command */ - if (!api_rpc_command(l, rpc_name, api_rpc_cmds, data)) - { - return False; - } - - /* create the rpc header */ - if (!create_rpc_reply(l, 0)) - { - return False; - } - - return True; -} - -BOOL is_complete_pdu(prs_struct *ps) -{ - RPC_HDR hdr; - int len = ps->data->data_size; - - DEBUG(10,("is_complete_pdu - len %d\n", len)); - ps->offset = 0x0; - - if (!ps->io) - { - /* writing. oops!! */ - DEBUG(4,("is_complete_pdu: write set, not read!\n")); - return False; - } - - if (!smb_io_rpc_hdr("hdr", &hdr, ps, 0)) - { - return False; - } - /* check that the fragment length is equal to the data length so far */ - return hdr.frag_len == len; -} -- cgit From fbd17c8dafeefac788f4bc1c41045726825f513f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 3 Jan 2000 19:19:48 +0000 Subject: simple mods to add msrpc pipe redirection. default behaviour: fall back to using internal msrpc code in smbd. (This used to be commit 8976e26d46cb991710bc77463f7f928ac00dd4d8) --- source3/rpc_server/srv_pipe.c | 1037 ++--------------------------------------- 1 file changed, 40 insertions(+), 997 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 236558ba70..98c3e90c06 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,3 +1,4 @@ + /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -5,7 +6,6 @@ * Copyright (C) Andrew Tridgell 1992-1998 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1997-1998. - * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,1035 +43,78 @@ extern int DEBUGLEVEL; -static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) -{ - unsigned char *hash = p->ntlmssp_hash; - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - int ind; - - for( ind = 0; ind < len; ind++) { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; - } - - hash[256] = index_i; - hash[257] = index_j; -} - /******************************************************************* - Generate the next PDU to be returned from the data in p->rdata. - We cheat here as this function doesn't handle the special auth - footers of the authenticated bind response reply. + entry point from msrpc to smb. adds data received to pdu; checks + pdu; hands pdu off to msrpc, which gets a pdu back (except in the + case of the RPC_BINDCONT pdu). ********************************************************************/ - -BOOL create_next_pdu(pipes_struct *p) -{ - RPC_HDR_RESP hdr_resp; - BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); - BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); - uint32 data_len; - uint32 data_space_available; - uint32 data_len_left; - prs_struct outgoing_pdu; - char *data; - char *data_from; - uint32 data_pos; - - memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); - - /* Change the incoming request header to a response. */ - p->hdr.pkt_type = RPC_RESPONSE; - - /* Set up rpc header flags. */ - if (p->data_sent_length == 0) - p->hdr.flags = RPC_FLG_FIRST; - else - p->hdr.flags = 0; - - /* - * Work out how much we can fit in a sigle PDU. - */ - - data_space_available = sizeof(p->current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; - if(p->ntlmssp_auth_validated) - data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); - - /* - * The amount we send is the minimum of the available - * space and the amount left to send. - */ - - data_len_left = prs_offset(&p->rdata) - p->data_sent_length; - - /* - * Ensure there really is data left to send. - */ - - if(!data_len_left) { - DEBUG(0,("create_next_pdu: no data left to send !\n")); - return False; - } - - data_len = MIN(data_len_left, data_space_available); - - /* - * Set up the alloc hint. This should be the data left to - * send. - */ - - hdr_resp.alloc_hint = data_len_left; - - /* - * Set up the header lengths. - */ - - if (p->ntlmssp_auth_validated) { - p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + - RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN; - p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; - } else { - p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; - p->hdr.auth_len = 0; - } - - /* - * Work out if this PDU will be the last. - */ - - if(p->data_sent_length + data_len >= prs_offset(&p->rdata)) - p->hdr.flags |= RPC_FLG_LAST; - - /* - * Init the parse struct to point at the outgoing - * data. - */ - - prs_init( &outgoing_pdu, 0, 4, MARSHALL); - prs_give_memory( &outgoing_pdu, (char *)p->current_pdu, sizeof(p->current_pdu), False); - - /* Store the header in the data stream. */ - if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n")); - return False; - } - - if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n")); - return False; - } - - /* Store the current offset. */ - data_pos = prs_offset(&outgoing_pdu); - - /* Copy the data into the PDU. */ - data_from = prs_data_p(&p->rdata) + p->data_sent_length; - - if(!prs_append_data(&outgoing_pdu, data_from, data_len)) { - DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len)); - return False; - } - - /* - * Set data to point to where we copied the data into. - */ - - data = prs_data_p(&outgoing_pdu) + data_pos; - - if (p->hdr.auth_len > 0) { - uint32 crc32 = 0; - - DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n", - BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len)); - - if (auth_seal) { - crc32 = crc32_calc_buffer(data, data_len); - NTLMSSPcalc_p(p, (uchar*)data, data_len); - } - - if (auth_seal || auth_verify) { - RPC_HDR_AUTH auth_info; - - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, - (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0)); - if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); - return False; - } - } - - if (auth_verify) { - RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; - char *auth_data = prs_data_p(&outgoing_pdu); - - p->ntlmssp_seq_num++; - init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION, - crc32, p->ntlmssp_seq_num++); - auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4; - if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n")); - return False; - } - NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); - } - } - - /* - * Setup the counts for this PDU. - */ - - p->data_sent_length += data_len; - p->current_pdu_len = p->hdr.frag_len; - p->current_pdu_sent = 0; - - return True; -} - -/******************************************************************* - Process an NTLMSSP authentication response. - If this function succeeds, the user has been authenticated - and their domain, name and calling workstation stored in - the pipe struct. - The initial challenge is stored in p->challenge. - *******************************************************************/ - -static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp) +BOOL readwrite_pipe(pipes_struct *p, char *data, int len, + char **rdata, int *rlen) { - uchar lm_owf[24]; - uchar nt_owf[24]; - fstring user_name; - fstring unix_user_name; - fstring domain; - fstring wks; - BOOL guest_user = False; - struct smb_passwd *smb_pass = NULL; - struct passwd *pass = NULL; - uchar null_smb_passwd[16]; - uchar *smb_passwd_ptr = NULL; - - DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); - - memset(p->user_name, '\0', sizeof(p->user_name)); - memset(p->unix_user_name, '\0', sizeof(p->unix_user_name)); - memset(p->domain, '\0', sizeof(p->domain)); - memset(p->wks, '\0', sizeof(p->wks)); - - /* - * Setup an empty password for a guest user. - */ - - memset(null_smb_passwd,0,16); - - /* - * We always negotiate UNICODE. - */ - - if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) { - fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); - fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); - fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); - } else { - fstrcpy(user_name, ntlmssp_resp->user); - fstrcpy(domain, ntlmssp_resp->domain); - fstrcpy(wks, ntlmssp_resp->wks); - } - - DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks)); - - memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf)); - memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf)); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("lm, nt owfs, chal\n")); - dump_data(100, (char *)lm_owf, sizeof(lm_owf)); - dump_data(100, (char *)nt_owf, sizeof(nt_owf)); - dump_data(100, (char *)p->challenge, 8); -#endif - - /* - * Allow guest access. Patch from Shirish Kalele . - */ - - if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_lm_resp.str_str_len==0) && - (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) { - - guest_user = True; - - fstrcpy(unix_user_name, lp_guestaccount(-1)); - DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name)); - - smb_passwd_ptr = null_smb_passwd; - - } else { - - /* - * Pass the user through the NT -> unix user mapping - * function. - */ - - fstrcpy(unix_user_name, user_name); - (void)map_username(unix_user_name); - - /* - * Do the length checking only if user is not NULL. - */ - - if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_usr.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_domain.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_wks.str_str_len == 0) - return False; - - } - - /* - * Find the user in the unix password db. - */ - - if(!(pass = Get_Pwnam(unix_user_name,True))) { - DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name)); - return(False); - } - - if(!guest_user) { - - become_root(True); - - if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain, - (uchar*)p->challenge, lm_owf, nt_owf, NULL))) { - DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ -failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name )); - unbecome_root(True); - return False; - } - - if(!(smb_pass = getsmbpwnam(unix_user_name))) { - DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", - unix_user_name)); - unbecome_root(True); - return False; - } - - unbecome_root(True); - - if (smb_pass == NULL) { - DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", - unix_user_name)); - return(False); - } - - /* Quit if the account was disabled. */ - if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) { - DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name)); - return(False); - } - - if(!smb_pass->smb_nt_passwd) { - DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name)); - return(False); - } - - smb_passwd_ptr = smb_pass->smb_passwd; - } - - /* - * Set up the sign/seal data. - */ + DEBUG(10,("rpc_to_smb_readwrite: len %d\n", len)); + if (write(p->m->fd, data, len) != len) { - uchar p24[24]; - NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24); - { - unsigned char j = 0; - int ind; - - unsigned char k2[8]; - - memcpy(k2, p24, 5); - k2[5] = 0xe5; - k2[6] = 0x38; - k2[7] = 0xb0; - - for (ind = 0; ind < 256; ind++) - p->ntlmssp_hash[ind] = (unsigned char)ind; - - for( ind = 0; ind < 256; ind++) { - unsigned char tc; - - j += (p->ntlmssp_hash[ind] + k2[ind%8]); - - tc = p->ntlmssp_hash[ind]; - p->ntlmssp_hash[ind] = p->ntlmssp_hash[j]; - p->ntlmssp_hash[j] = tc; - } - - p->ntlmssp_hash[256] = 0; - p->ntlmssp_hash[257] = 0; - } -/* NTLMSSPhash(p->ntlmssp_hash, p24); */ - p->ntlmssp_seq_num = 0; - - } - - fstrcpy(p->user_name, user_name); - fstrcpy(p->unix_user_name, unix_user_name); - fstrcpy(p->domain, domain); - fstrcpy(p->wks, wks); - - /* - * Store the UNIX credential data (uid/gid pair) in the pipe structure. - */ - - p->uid = pass->pw_uid; - p->gid = pass->pw_gid; - - p->ntlmssp_auth_validated = True; - return True; -} - -/******************************************************************* - The switch table for the pipe names and the functions to handle them. - *******************************************************************/ - -struct api_cmd -{ - char * pipe_clnt_name; - char * pipe_srv_name; - BOOL (*fn) (pipes_struct *, prs_struct *); -}; - -static struct api_cmd api_fd_commands[] = -{ - { "lsarpc", "lsass", api_ntlsa_rpc }, - { "samr", "lsass", api_samr_rpc }, - { "srvsvc", "ntsvcs", api_srvsvc_rpc }, - { "wkssvc", "ntsvcs", api_wkssvc_rpc }, - { "NETLOGON", "lsass", api_netlog_rpc }, -#if DISABLED_IN_2_0 - { "winreg", "winreg", api_reg_rpc }, -#endif - { NULL, NULL, NULL } -}; - -/******************************************************************* - This is the client reply to our challenge for an authenticated - bind request. The challenge we sent is in p->challenge. -*******************************************************************/ - -static BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *pd) -{ - RPC_HDR_AUTHA autha_info; - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; - - DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); - - if (p->hdr.auth_len == 0) { - DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n")); - return False; - } - - /* - * Decode the authentication verifier response. - */ - - if(!smb_io_rpc_hdr_autha("", &autha_info, pd, 0)) { - DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n")); - return False; - } - - if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) { - DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n", - (int)autha_info.auth_type, (int)autha_info.auth_level )); return False; } - if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) { - DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n")); - return False; - } - - /* - * Ensure this is a NTLMSSP_AUTH packet type. - */ - - if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) { - DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n")); - return False; - } - - if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, pd, 0)) { - DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n")); - return False; - } - - /* - * The following call actually checks the challenge/response data. - * for correctness against the given DOMAIN\user name. - */ - - if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp)) - return False; - - return True; -} - -/******************************************************************* - Marshall a bind_nak pdu. -*******************************************************************/ - -static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd) -{ - prs_struct outgoing_rpc; - RPC_HDR nak_hdr; - uint16 zero = 0; - - /* - * Marshall directly into the outgoing PDU space. We - * must do this as we need to set to the bind response - * header and are never sending more than one PDU here. - */ - - prs_init( &outgoing_rpc, 0, 4, MARSHALL); - prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False); - - - /* - * Initialize a bind_nak header. - */ - - init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST, - p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0); - - /* - * Marshall the header into the outgoing PDU. - */ - - if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) { - DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n")); + if ((*rlen) == 0) + { return False; } - /* - * Now add the reject reason. - */ - - if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) - return False; - - p->data_sent_length = 0; - p->current_pdu_len = prs_offset(&outgoing_rpc); - p->current_pdu_sent = 0; - - return True; -} - -/******************************************************************* - Respond to a pipe bind request. -*******************************************************************/ - -static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) -{ - RPC_HDR_BA hdr_ba; - RPC_HDR_RB hdr_rb; - RPC_HDR_AUTH auth_info; - uint16 assoc_gid; - fstring ack_pipe_name; - prs_struct out_hdr_ba; - prs_struct out_auth; - prs_struct outgoing_rpc; - int i = 0; - int auth_len = 0; - - p->ntlmssp_auth_requested = False; - - DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); - - /* - * Try and find the correct pipe name to ensure - * that this is a pipe name we support. - */ - - for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { - if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && - api_fd_commands[i].fn != NULL) { - DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", - api_fd_commands[i].pipe_clnt_name, - api_fd_commands[i].pipe_srv_name)); - fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name); - break; - } - } - - if (api_fd_commands[i].fn == NULL) { - DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", - p->name )); - if(!setup_bind_nak(p, pd)) - return False; - return True; - } - - /* decode the bind request */ - if(!smb_io_rpc_hdr_rb("", &hdr_rb, pd, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); + (*rdata) = (char*)Realloc((*rdata), (*rlen)); + if ((*rdata) == NULL) + { return False; } - - /* - * Check if this is an authenticated request. - */ - - if (p->hdr.auth_len != 0) { - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; - - /* - * Decode the authentication verifier. - */ - - if(!smb_io_rpc_hdr_auth("", &auth_info, pd, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); - return False; - } - - /* - * We only support NTLMSSP_AUTH_TYPE requests. - */ - - if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) { - DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", - auth_info.auth_type )); - return False; - } - - if(!smb_io_rpc_auth_verifier("", &auth_verifier, pd, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); - return False; - } - - if(!strequal(auth_verifier.signature, "NTLMSSP")) { - DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n")); - return False; - } - - if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { - DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", - auth_verifier.msg_type)); - return False; - } - - if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, pd, 0)) { - DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); - return False; - } - - p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; - p->ntlmssp_auth_requested = True; - } - - /* name has to be \PIPE\xxxxx */ - fstrcpy(ack_pipe_name, "\\PIPE\\"); - fstrcat(ack_pipe_name, p->pipe_srv_name); - - DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); - - /* - * Marshall directly into the outgoing PDU space. We - * must do this as we need to set to the bind response - * header and are never sending more than one PDU here. - */ - - prs_init( &outgoing_rpc, 0, 4, MARSHALL); - prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False); - - /* - * Setup the memory to marshall the ba header, and the - * auth footers. - */ - - if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) { - DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); + (*rlen) = read(p->m->fd, (*rdata), (*rlen)); + if ((*rlen) < 0) + { return False; } - - if(!prs_init(&out_auth, 1024, 4, MARSHALL)) { - DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n")); - prs_mem_free(&out_hdr_ba); + (*rdata) = (char*)Realloc((*rdata), (*rlen)); + if ((*rdata) == NULL) + { return False; } - - if (p->ntlmssp_auth_requested) - assoc_gid = 0x7a77; - else - assoc_gid = hdr_rb.bba.assoc_gid; - - /* - * Create the bind response struct. - */ - - init_rpc_hdr_ba(&hdr_ba, - hdr_rb.bba.max_tsize, - hdr_rb.bba.max_rsize, - assoc_gid, - ack_pipe_name, - 0x1, 0x0, 0x0, - &hdr_rb.transfer); - - /* - * and marshall it. - */ - - if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n")); - goto err_exit; - } - - /* - * Now the authentication. - */ - - if (p->ntlmssp_auth_requested) { - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal; - - generate_random_buffer(p->challenge, 8, False); - - /*** Authentication info ***/ - - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1); - if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); - goto err_exit; - } - - /*** NTLMSSP verifier ***/ - - init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE); - if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n")); - goto err_exit; - } - - /* NTLMSSP challenge ***/ - - init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge); - if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n")); - goto err_exit; - } - - /* Auth len in the rpc header doesn't include auth_header. */ - auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; - } - - /* - * Create the header, now we know the length. - */ - - init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, - p->hdr.call_id, - RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), - auth_len); - - /* - * Marshall the header into the outgoing PDU. - */ - - if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) { - DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n")); - goto err_exit; - } - - /* - * Now add the RPC_HDR_BA and any auth needed. - */ - - if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) { - DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n")); - goto err_exit; - } - - if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) { - DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n")); - goto err_exit; - } - - /* - * Setup the lengths for the initial reply. - */ - - p->data_sent_length = 0; - p->current_pdu_len = prs_offset(&outgoing_rpc); - p->current_pdu_sent = 0; - - prs_mem_free(&out_hdr_ba); - prs_mem_free(&out_auth); - return True; - - err_exit: - - prs_mem_free(&out_hdr_ba); - prs_mem_free(&out_auth); - return False; } /**************************************************************************** - Deal with sign & seal processing on an RPC request. -****************************************************************************/ - -static BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) + writes data to a pipe. + ****************************************************************************/ +ssize_t write_pipe(pipes_struct *p, char *data, size_t n) { - /* - * We always negotiate the following two bits.... - */ - BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); - BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); - int data_len; - int auth_len; - uint32 old_offset; - uint32 crc32 = 0; - - auth_len = p->hdr.auth_len; + DEBUG(6,("write_pipe: %x", p->pnum)); + DEBUG(6,("name: %s open: %s len: %d", + p->name, BOOLSTR(p->open), n)); - if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) { - DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len )); - return False; - } - - /* - * The following is that length of the data we must verify or unseal. - * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN - * preceeding the auth_data. - */ - - data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - - (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len; - - DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n", - BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); - - if (auth_seal) { - char *data = prs_data_p(rpc_in) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; - NTLMSSPcalc_p(p, (uchar*)data, data_len); - crc32 = crc32_calc_buffer(data, data_len); - } - - old_offset = prs_offset(rpc_in); - - if (auth_seal || auth_verify) { - RPC_HDR_AUTH auth_info; - - if(!prs_set_offset(rpc_in, old_offset + data_len)) { - DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n", - (unsigned int)old_offset + data_len )); - return False; - } - - if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { - DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n")); - return False; - } - } + dump_data(50, data, n); - if (auth_verify) { - RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; - char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4; - - DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4)); - - /* - * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the - * incoming buffer. - */ - if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) { - DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n", - RPC_AUTH_NTLMSSP_CHK_LEN - 4 )); - return False; - } - - NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); - if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) { - DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n")); - return False; - } - - if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) { - DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n")); - return False; - } - } - - /* - * Return the current pointer to the data offset. - */ - - if(!prs_set_offset(rpc_in, old_offset)) { - DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n", - (unsigned int)old_offset )); - return False; - } - - return True; + return write(p->m->fd, data, n); } -/**************************************************************************** - Find the correct RPC function to call for this request. - If the pipe is authenticated then become the correct UNIX user - before doing the call. -****************************************************************************/ - -static BOOL api_pipe_request(pipes_struct *p, prs_struct *rpc_in) -{ - int i = 0; - BOOL ret = False; - BOOL changed_user_id = False; - - if (p->ntlmssp_auth_validated) { - if (!api_pipe_auth_process(p, rpc_in)) - return False; - - if(!become_authenticated_pipe_user(p)) - return False; - - changed_user_id = True; - } - - for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { - if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && - api_fd_commands[i].fn != NULL) { - DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); - ret = api_fd_commands[i].fn(p, rpc_in); - } - } - - if(changed_user_id) - unbecome_authenticated_pipe_user(p); - - return ret; -} /**************************************************************************** - This function is the entry point to processing a DCE/RPC request. - All the data for the request (including RPC headers and authentication - verifiers) must be linearized in the input_data buffer, with a length - of data_len. + reads data from a pipe. - The output is placed into the pipes_struct, and handed back to the - client on demand. -****************************************************************************/ + headers are interspersed with the data at regular intervals. by the time + this function is called, the start of the data could possibly have been + read by an SMBtrans (file_offset != 0). -BOOL rpc_command(pipes_struct *p, char *input_data, int data_len) + ****************************************************************************/ +int read_pipe(pipes_struct *p, char *data, int n) { - prs_struct rpc_in; - BOOL reply = False; - - if (input_data == NULL) - return False; - - prs_init(&rpc_in, 0, 4, UNMARSHALL); - - /* - * Hand the data to the prs_struct, but don't let - * it own it. - */ - prs_give_memory( &rpc_in, input_data, (uint32)data_len, False); + DEBUG(6,("read_pipe: %x name: %s open: %s len: %d", + p->pnum, p->name, BOOLSTR(p->open), n)); - /* Unmarshall the rpc header */ - if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) { - DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n")); - return False; - } - - /* - * Create the response data buffer. - */ - - if(!pipe_init_outgoing_data(p)) { - DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n")); - return False; - } - - switch (p->hdr.pkt_type) { - case RPC_BIND: - reply = api_pipe_bind_req(p, &rpc_in); - break; - case RPC_REQUEST: - if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) { - /* authentication _was_ requested - and it failed. sorry, no deal! - */ - DEBUG(0,("rpc_command: RPC request received on pipe %s where \ -authentication failed. Denying the request.\n", p->name)); - reply = False; - } else { - /* read the RPC request header */ - if(!smb_io_rpc_hdr_req("req", &p->hdr_req, &rpc_in, 0)) { - DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR_REQ.\n")); - return False; - } - reply = api_pipe_request(p, &rpc_in); - } - break; - case RPC_BINDRESP: /* not the real name! */ - reply = api_pipe_bind_auth_resp(p, &rpc_in); - break; + if (!p || !p->open) + { + DEBUG(6,("pipe not open\n")); + return -1; } - if (!reply) - DEBUG(3,("rpc_command: DCE/RPC fault should be sent here\n")); - - return reply; + return read(p->m->fd, data, n); } - -/******************************************************************* - Calls the underlying RPC function for a named pipe. - ********************************************************************/ - -BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds, - prs_struct *rpc_in) -{ - int fn_num; - - /* interpret the command */ - DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); - - for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { - if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { - DEBUG(3,("api_rpc_command: %s\n", api_rpc_cmds[fn_num].name)); - break; - } - } - - if (api_rpc_cmds[fn_num].name == NULL) { - DEBUG(4, ("unknown\n")); - return False; - } - - /* do the actual command */ - if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->rdata)) { - DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); - prs_mem_free(&p->rdata); - return False; - } - - DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name)); - - return True; -} -- cgit From 528399a8a2a0903e6b8a9de0e3ac07f1f0b5f21b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 4 Jan 2000 07:52:21 +0000 Subject: oops, must use read_data() not read(), as read() may only provide part of the data stream. read_data() is a wrapper to guarantee receiving exactly the requested number of bytes. (This used to be commit 90c27b7bffa9b2121eaed0e07931830c3ba308d7) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 98c3e90c06..49733b0767 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -68,7 +68,7 @@ BOOL readwrite_pipe(pipes_struct *p, char *data, int len, { return False; } - (*rlen) = read(p->m->fd, (*rdata), (*rlen)); + (*rlen) = read_data(p->m->fd, (*rdata), (*rlen)); if ((*rlen) < 0) { return False; @@ -115,6 +115,6 @@ int read_pipe(pipes_struct *p, char *data, int n) return -1; } - return read(p->m->fd, data, n); + return read_data(p->m->fd, data, n); } -- cgit From ac9c6994e02ff0a204a19931c4c118c5f1028479 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 4 Jan 2000 15:59:57 +0000 Subject: using read_with_timeout(), min data size 16 bytes (DCE/RPC header), max size of SMBtrans response, timeout of 10 seconds. read_data() _certainly_ doesn't work, as you don't know what size of the data is going to come back that needs to be fed back in the SMBtrans response. yes, oops :-) (This used to be commit 70d6f7635776bba98c9c09405eff6c2087dac590) --- source3/rpc_server/srv_pipe.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 49733b0767..f8439de9a7 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -68,7 +68,11 @@ BOOL readwrite_pipe(pipes_struct *p, char *data, int len, { return False; } - (*rlen) = read_data(p->m->fd, (*rdata), (*rlen)); + + /* read a minimum of an rpc header, then wait for up to 10 seconds + * to read up to a maximum of the SMBtrans max data size + */ + (*rlen) = read_with_timeout(p->m->fd, (*rdata), 16, (*rlen), 10000); if ((*rlen) < 0) { return False; -- cgit From 6bb92a6d38db41a11e80c4369623d137763f0f52 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Mar 2000 21:45:16 +0000 Subject: Big update moving the multi-pdu support from 2.0.x into HEAD for JF and the printer functions. Also tidied up some header includes and got the order right so you can now do a : make proto make clean make Jeremy. (This used to be commit 833cd9fba92e4ad5297b235d108dd2be8c17079b) --- source3/rpc_server/srv_pipe.c | 1099 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 1056 insertions(+), 43 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index f8439de9a7..11822e7d03 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,4 +1,3 @@ - /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -6,6 +5,7 @@ * Copyright (C) Andrew Tridgell 1992-1998 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1997-1998. + * Copyright (C) Jeremy Allison 1999. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,82 +43,1095 @@ extern int DEBUGLEVEL; +static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) +{ + unsigned char *hash = p->ntlmssp_hash; + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; + + for( ind = 0; ind < len; ind++) { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + /******************************************************************* - entry point from msrpc to smb. adds data received to pdu; checks - pdu; hands pdu off to msrpc, which gets a pdu back (except in the - case of the RPC_BINDCONT pdu). + Generate the next PDU to be returned from the data in p->rdata. + We cheat here as this function doesn't handle the special auth + footers of the authenticated bind response reply. ********************************************************************/ -BOOL readwrite_pipe(pipes_struct *p, char *data, int len, - char **rdata, int *rlen) + +BOOL create_next_pdu(pipes_struct *p) { - DEBUG(10,("rpc_to_smb_readwrite: len %d\n", len)); + RPC_HDR_RESP hdr_resp; + BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); + BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); + uint32 data_len; + uint32 data_space_available; + uint32 data_len_left; + prs_struct outgoing_pdu; + char *data; + char *data_from; + uint32 data_pos; - if (write(p->m->fd, data, len) != len) - { + /* + * If we're in the fault state, keep returning fault PDU's until + * the pipe gets closed. JRA. + */ + + if(p->fault_state) { + setup_fault_pdu(p); + return True; + } + + memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); + + /* Change the incoming request header to a response. */ + p->hdr.pkt_type = RPC_RESPONSE; + + /* Set up rpc header flags. */ + if (p->out_data.data_sent_length == 0) + p->hdr.flags = RPC_FLG_FIRST; + else + p->hdr.flags = 0; + + /* + * Work out how much we can fit in a sigle PDU. + */ + + data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + if(p->ntlmssp_auth_validated) + data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); + + /* + * The amount we send is the minimum of the available + * space and the amount left to send. + */ + + data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length; + + /* + * Ensure there really is data left to send. + */ + + if(!data_len_left) { + DEBUG(0,("create_next_pdu: no data left to send !\n")); return False; } - if ((*rlen) == 0) - { + data_len = MIN(data_len_left, data_space_available); + + /* + * Set up the alloc hint. This should be the data left to + * send. + */ + + hdr_resp.alloc_hint = data_len_left; + + /* + * Set up the header lengths. + */ + + if (p->ntlmssp_auth_validated) { + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + + RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN; + p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; + } else { + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; + p->hdr.auth_len = 0; + } + + /* + * Work out if this PDU will be the last. + */ + + if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) + p->hdr.flags |= RPC_FLG_LAST; + + /* + * Init the parse struct to point at the outgoing + * data. + */ + + prs_init( &outgoing_pdu, 0, 4, MARSHALL); + prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); + + /* Store the header in the data stream. */ + if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n")); return False; } - (*rdata) = (char*)Realloc((*rdata), (*rlen)); - if ((*rdata) == NULL) - { + if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n")); return False; } - /* read a minimum of an rpc header, then wait for up to 10 seconds - * to read up to a maximum of the SMBtrans max data size + /* Store the current offset. */ + data_pos = prs_offset(&outgoing_pdu); + + /* Copy the data into the PDU. */ + data_from = prs_data_p(&p->out_data.rdata) + p->out_data.data_sent_length; + + if(!prs_append_data(&outgoing_pdu, data_from, data_len)) { + DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len)); + return False; + } + + /* + * Set data to point to where we copied the data into. + */ + + data = prs_data_p(&outgoing_pdu) + data_pos; + + if (p->hdr.auth_len > 0) { + uint32 crc32 = 0; + + DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n", + BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len)); + + if (auth_seal) { + crc32 = crc32_calc_buffer(data, data_len); + NTLMSSPcalc_p(p, (uchar*)data, data_len); + } + + if (auth_seal || auth_verify) { + RPC_HDR_AUTH auth_info; + + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, + (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0)); + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); + return False; + } + } + + if (auth_verify) { + RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; + char *auth_data = prs_data_p(&outgoing_pdu); + + p->ntlmssp_seq_num++; + init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION, + crc32, p->ntlmssp_seq_num++); + auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4; + if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n")); + return False; + } + NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); + } + } + + /* + * Setup the counts for this PDU. + */ + + p->out_data.data_sent_length += data_len; + p->out_data.current_pdu_len = p->hdr.frag_len; + p->out_data.current_pdu_sent = 0; + + return True; +} + +/******************************************************************* + Process an NTLMSSP authentication response. + If this function succeeds, the user has been authenticated + and their domain, name and calling workstation stored in + the pipe struct. + The initial challenge is stored in p->challenge. + *******************************************************************/ + +static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp) +{ + uchar lm_owf[24]; + uchar nt_owf[24]; + fstring user_name; + fstring unix_user_name; + fstring domain; + fstring wks; + BOOL guest_user = False; + struct smb_passwd *smb_pass = NULL; + struct passwd *pass = NULL; + uchar null_smb_passwd[16]; + uchar *smb_passwd_ptr = NULL; + + DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); + + memset(p->user_name, '\0', sizeof(p->user_name)); + memset(p->unix_user_name, '\0', sizeof(p->unix_user_name)); + memset(p->domain, '\0', sizeof(p->domain)); + memset(p->wks, '\0', sizeof(p->wks)); + + /* + * Setup an empty password for a guest user. */ - (*rlen) = read_with_timeout(p->m->fd, (*rdata), 16, (*rlen), 10000); - if ((*rlen) < 0) + + memset(null_smb_passwd,0,16); + + /* + * We always negotiate UNICODE. + */ + + if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) { + fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); + fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); + fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); + } else { + fstrcpy(user_name, ntlmssp_resp->user); + fstrcpy(domain, ntlmssp_resp->domain); + fstrcpy(wks, ntlmssp_resp->wks); + } + + DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks)); + + memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf)); + memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf)); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm, nt owfs, chal\n")); + dump_data(100, (char *)lm_owf, sizeof(lm_owf)); + dump_data(100, (char *)nt_owf, sizeof(nt_owf)); + dump_data(100, (char *)p->challenge, 8); +#endif + + /* + * Allow guest access. Patch from Shirish Kalele . + */ + + if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_lm_resp.str_str_len==0) && + (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) { + + guest_user = True; + + fstrcpy(unix_user_name, lp_guestaccount(-1)); + DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name)); + + smb_passwd_ptr = null_smb_passwd; + + } else { + + /* + * Pass the user through the NT -> unix user mapping + * function. + */ + + fstrcpy(unix_user_name, user_name); + (void)map_username(unix_user_name); + + /* + * Do the length checking only if user is not NULL. + */ + + if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_usr.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_domain.str_str_len == 0) + return False; + if (ntlmssp_resp->hdr_wks.str_str_len == 0) + return False; + + } + + /* + * Find the user in the unix password db. + */ + + if(!(pass = Get_Pwnam(unix_user_name,True))) { + DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name)); + return(False); + } + + if(!guest_user) { + + become_root(True); + + if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain, + (uchar*)p->challenge, lm_owf, nt_owf, NULL))) { + DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ +failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name )); + unbecome_root(True); + return False; + } + + if(!(smb_pass = getsmbpwnam(unix_user_name))) { + DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", + unix_user_name)); + unbecome_root(True); + return False; + } + + unbecome_root(True); + + if (smb_pass == NULL) { + DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", + unix_user_name)); + return(False); + } + + /* Quit if the account was disabled. */ + if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) { + DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name)); + return(False); + } + + if(!smb_pass->smb_nt_passwd) { + DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name)); + return(False); + } + + smb_passwd_ptr = smb_pass->smb_passwd; + } + + /* + * Set up the sign/seal data. + */ + { + uchar p24[24]; + NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24); + { + unsigned char j = 0; + int ind; + + unsigned char k2[8]; + + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + for (ind = 0; ind < 256; ind++) + p->ntlmssp_hash[ind] = (unsigned char)ind; + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (p->ntlmssp_hash[ind] + k2[ind%8]); + + tc = p->ntlmssp_hash[ind]; + p->ntlmssp_hash[ind] = p->ntlmssp_hash[j]; + p->ntlmssp_hash[j] = tc; + } + + p->ntlmssp_hash[256] = 0; + p->ntlmssp_hash[257] = 0; + } +/* NTLMSSPhash(p->ntlmssp_hash, p24); */ + p->ntlmssp_seq_num = 0; + + } + + fstrcpy(p->user_name, user_name); + fstrcpy(p->unix_user_name, unix_user_name); + fstrcpy(p->domain, domain); + fstrcpy(p->wks, wks); + + /* + * Store the UNIX credential data (uid/gid pair) in the pipe structure. + */ + + p->uid = pass->pw_uid; + p->gid = pass->pw_gid; + + p->ntlmssp_auth_validated = True; + return True; +} + +/******************************************************************* + The switch table for the pipe names and the functions to handle them. + *******************************************************************/ + +struct api_cmd +{ + char * pipe_clnt_name; + char * pipe_srv_name; + BOOL (*fn) (pipes_struct *, prs_struct *); +}; + +static struct api_cmd api_fd_commands[] = +{ + { "lsarpc", "lsass", api_ntlsa_rpc }, + { "samr", "lsass", api_samr_rpc }, + { "srvsvc", "ntsvcs", api_srvsvc_rpc }, + { "wkssvc", "ntsvcs", api_wkssvc_rpc }, + { "NETLOGON", "lsass", api_netlog_rpc }, +#if 1 /* DISABLED_IN_2_0 JRATEST */ + { "winreg", "winreg", api_reg_rpc }, +#endif + { NULL, NULL, NULL } +}; + +/******************************************************************* + This is the client reply to our challenge for an authenticated + bind request. The challenge we sent is in p->challenge. +*******************************************************************/ + +BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p) +{ + RPC_HDR_AUTHA autha_info; + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; + + DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); + + /* + * Create the response data buffer. + */ + + if(!pipe_init_outgoing_data(&p->out_data)) { + DEBUG(0,("api_pipe_bind_auth_resp: failed to create outgoing buffer.\n")); return False; } - (*rdata) = (char*)Realloc((*rdata), (*rlen)); - if ((*rdata) == NULL) - { + + if (p->hdr.auth_len == 0) { + DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n")); + return False; + } + + /* + * Decode the authentication verifier response. + */ + + if(!smb_io_rpc_hdr_autha("", &autha_info, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n")); + return False; + } + + if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) { + DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n", + (int)autha_info.auth_type, (int)autha_info.auth_level )); return False; } + + if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n")); + return False; + } + + /* + * Ensure this is a NTLMSSP_AUTH packet type. + */ + + if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) { + DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n")); + return False; + } + + if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n")); + return False; + } + + /* + * The following call actually checks the challenge/response data. + * for correctness against the given DOMAIN\user name. + */ + + if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp)) + return False; + + p->pipe_bound = True +; return True; } -/**************************************************************************** - writes data to a pipe. - ****************************************************************************/ -ssize_t write_pipe(pipes_struct *p, char *data, size_t n) +/******************************************************************* + Marshall a bind_nak pdu. +*******************************************************************/ + +static BOOL setup_bind_nak(pipes_struct *p) { - DEBUG(6,("write_pipe: %x", p->pnum)); - DEBUG(6,("name: %s open: %s len: %d", - p->name, BOOLSTR(p->open), n)); + prs_struct outgoing_rpc; + RPC_HDR nak_hdr; + uint16 zero = 0; + + /* Free any memory in the current return data buffer. */ + prs_mem_free(&p->out_data.rdata); + + /* + * Marshall directly into the outgoing PDU space. We + * must do this as we need to set to the bind response + * header and are never sending more than one PDU here. + */ + + prs_init( &outgoing_rpc, 0, 4, MARSHALL); + prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); + + + /* + * Initialize a bind_nak header. + */ + + init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0); + + /* + * Marshall the header into the outgoing PDU. + */ + + if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) { + DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n")); + return False; + } + + /* + * Now add the reject reason. + */ + + if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) + return False; - dump_data(50, data, n); + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); + p->out_data.current_pdu_sent = 0; - return write(p->m->fd, data, n); + p->pipe_bound = False; + + return True; } +/******************************************************************* + Marshall a fault pdu. +*******************************************************************/ + +BOOL setup_fault_pdu(pipes_struct *p) +{ + prs_struct outgoing_pdu; + RPC_HDR fault_hdr; + RPC_HDR_RESP hdr_resp; + RPC_HDR_FAULT fault_resp; + + /* Free any memory in the current return data buffer. */ + prs_mem_free(&p->out_data.rdata); + + /* + * Marshall directly into the outgoing PDU space. We + * must do this as we need to set to the bind response + * header and are never sending more than one PDU here. + */ + + prs_init( &outgoing_pdu, 0, 4, MARSHALL); + prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); + + /* + * Initialize a fault header. + */ + + init_rpc_hdr(&fault_hdr, RPC_FAULT, RPC_FLG_FIRST | RPC_FLG_LAST | RPC_FLG_NOCALL, + p->hdr.call_id, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_FAULT_LEN, 0); + + /* + * Initialize the HDR_RESP and FAULT parts of the PDU. + */ + + memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); + + fault_resp.status = 0x1c010002; + fault_resp.reserved = 0; + + /* + * Marshall the header into the outgoing PDU. + */ + + if(!smb_io_rpc_hdr("", &fault_hdr, &outgoing_pdu, 0)) { + DEBUG(0,("setup_fault_pdu: marshalling of RPC_HDR failed.\n")); + return False; + } + + if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { + DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_RESP.\n")); + return False; + } + + if(!smb_io_rpc_hdr_fault("fault", &fault_resp, &outgoing_pdu, 0)) { + DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_FAULT.\n")); + return False; + } + + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_len = prs_offset(&outgoing_pdu); + p->out_data.current_pdu_sent = 0; + + return True; +} + +/******************************************************************* + Respond to a pipe bind request. +*******************************************************************/ + +BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) +{ + RPC_HDR_BA hdr_ba; + RPC_HDR_RB hdr_rb; + RPC_HDR_AUTH auth_info; + uint16 assoc_gid; + fstring ack_pipe_name; + prs_struct out_hdr_ba; + prs_struct out_auth; + prs_struct outgoing_rpc; + int i = 0; + int auth_len = 0; + enum RPC_PKT_TYPE reply_pkt_type; + + p->ntlmssp_auth_requested = False; + + DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); + + /* + * Create the response data buffer. + */ + + if(!pipe_init_outgoing_data(&p->out_data)) { + DEBUG(0,("api_pipe_bind_req: failed to create outgoing buffer.\n")); + return False; + } + + /* + * Try and find the correct pipe name to ensure + * that this is a pipe name we support. + */ + + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) { + DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + api_fd_commands[i].pipe_clnt_name, + api_fd_commands[i].pipe_srv_name)); + fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name); + break; + } + } + + if (api_fd_commands[i].fn == NULL) { + DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", + p->name )); + if(!setup_bind_nak(p)) + return False; + return True; + } + + /* decode the bind request */ + if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); + return False; + } + + /* + * Check if this is an authenticated request. + */ + + if (p->hdr.auth_len != 0) { + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; + + /* + * Decode the authentication verifier. + */ + + if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); + return False; + } + + /* + * We only support NTLMSSP_AUTH_TYPE requests. + */ + + if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) { + DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", + auth_info.auth_type )); + return False; + } + + if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); + return False; + } + + if(!strequal(auth_verifier.signature, "NTLMSSP")) { + DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n")); + return False; + } + + if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { + DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", + auth_verifier.msg_type)); + return False; + } + + if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); + return False; + } + + p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; + p->ntlmssp_auth_requested = True; + } + + switch(p->hdr.pkt_type) { + case RPC_BIND: + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, p->pipe_srv_name); + reply_pkt_type = RPC_BINDACK; + break; + case RPC_ALTCONT: + /* secondary address CAN be NULL + * as the specs say it's ignored. + * It MUST NULL to have the spoolss working. + */ + fstrcpy(ack_pipe_name,""); + reply_pkt_type = RPC_ALTCONTRESP; + break; + default: + return False; + } + + DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); + + /* + * Marshall directly into the outgoing PDU space. We + * must do this as we need to set to the bind response + * header and are never sending more than one PDU here. + */ + + prs_init( &outgoing_rpc, 0, 4, MARSHALL); + prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); + + /* + * Setup the memory to marshall the ba header, and the + * auth footers. + */ + + if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) { + DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); + return False; + } + + if(!prs_init(&out_auth, 1024, 4, MARSHALL)) { + DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n")); + prs_mem_free(&out_hdr_ba); + return False; + } + + if (p->ntlmssp_auth_requested) + assoc_gid = 0x7a77; + else + assoc_gid = hdr_rb.bba.assoc_gid; + + /* + * Create the bind response struct. + */ + + init_rpc_hdr_ba(&hdr_ba, + MAX_PDU_FRAG_LEN, + MAX_PDU_FRAG_LEN, + assoc_gid, + ack_pipe_name, + 0x1, 0x0, 0x0, + &hdr_rb.transfer); + + /* + * and marshall it. + */ + + if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n")); + goto err_exit; + } + + /* + * Now the authentication. + */ + + if (p->ntlmssp_auth_requested) { + RPC_AUTH_VERIFIER auth_verifier; + RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal; + + generate_random_buffer(p->challenge, 8, False); + + /*** Authentication info ***/ + + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1); + if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); + goto err_exit; + } + + /*** NTLMSSP verifier ***/ + + init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE); + if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n")); + goto err_exit; + } + + /* NTLMSSP challenge ***/ + + init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge); + if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n")); + goto err_exit; + } + + /* Auth len in the rpc header doesn't include auth_header. */ + auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; + } + + /* + * Create the header, now we know the length. + */ + + init_rpc_hdr(&p->hdr, reply_pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, + RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), + auth_len); + + /* + * Marshall the header into the outgoing PDU. + */ + + if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) { + DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n")); + goto err_exit; + } + + /* + * Now add the RPC_HDR_BA and any auth needed. + */ + + if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) { + DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n")); + goto err_exit; + } + + if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) { + DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n")); + goto err_exit; + } + + if(!p->ntlmssp_auth_requested) + p->pipe_bound = True; + + /* + * Setup the lengths for the initial reply. + */ + + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); + p->out_data.current_pdu_sent = 0; + + prs_mem_free(&out_hdr_ba); + prs_mem_free(&out_auth); + + return True; + + err_exit: + + prs_mem_free(&out_hdr_ba); + prs_mem_free(&out_auth); + return False; +} /**************************************************************************** - reads data from a pipe. + Deal with sign & seal processing on an RPC request. +****************************************************************************/ + +BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) +{ + /* + * We always negotiate the following two bits.... + */ + BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); + BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); + int data_len; + int auth_len; + uint32 old_offset; + uint32 crc32 = 0; + + auth_len = p->hdr.auth_len; + + if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) { + DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len )); + return False; + } + + /* + * The following is that length of the data we must verify or unseal. + * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN + * preceeding the auth_data. + */ + + data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - + (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len; + + DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n", + BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); + + if (auth_seal) { + char *data = prs_data_p(rpc_in) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; + NTLMSSPcalc_p(p, (uchar*)data, data_len); + crc32 = crc32_calc_buffer(data, data_len); + } + + old_offset = prs_offset(rpc_in); + + if (auth_seal || auth_verify) { + RPC_HDR_AUTH auth_info; - headers are interspersed with the data at regular intervals. by the time - this function is called, the start of the data could possibly have been - read by an SMBtrans (file_offset != 0). + if(!prs_set_offset(rpc_in, old_offset + data_len)) { + DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n", + (unsigned int)old_offset + data_len )); + return False; + } - ****************************************************************************/ -int read_pipe(pipes_struct *p, char *data, int n) + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { + DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n")); + return False; + } + } + + if (auth_verify) { + RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; + char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4; + + DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4)); + + /* + * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the + * incoming buffer. + */ + if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) { + DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n", + RPC_AUTH_NTLMSSP_CHK_LEN - 4 )); + return False; + } + + NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); + if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) { + DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n")); + return False; + } + + if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) { + DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n")); + return False; + } + } + + /* + * Return the current pointer to the data offset. + */ + + if(!prs_set_offset(rpc_in, old_offset)) { + DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n", + (unsigned int)old_offset )); + return False; + } + + return True; +} + +/**************************************************************************** + Find the correct RPC function to call for this request. + If the pipe is authenticated then become the correct UNIX user + before doing the call. +****************************************************************************/ + +BOOL api_pipe_request(pipes_struct *p) { - DEBUG(6,("read_pipe: %x name: %s open: %s len: %d", - p->pnum, p->name, BOOLSTR(p->open), n)); + int i = 0; + BOOL ret = False; + BOOL changed_user_id = False; - if (!p || !p->open) - { - DEBUG(6,("pipe not open\n")); - return -1; + /* + * Create the response data buffer. + */ + + if(!pipe_init_outgoing_data(&p->out_data)) { + DEBUG(0,("api_pipe_request: failed to create outgoing buffer.\n")); + return False; } - return read_data(p->m->fd, data, n); + if (p->ntlmssp_auth_validated) { + + if(!become_authenticated_pipe_user(p)) { + prs_mem_free(&p->out_data.rdata); + return False; + } + + changed_user_id = True; + } + + for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { + if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && + api_fd_commands[i].fn != NULL) { + DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); + ret = api_fd_commands[i].fn(p, &p->in_data.data); + } + } + + if(changed_user_id) + unbecome_authenticated_pipe_user(p); + + return ret; } +/******************************************************************* + Calls the underlying RPC function for a named pipe. + ********************************************************************/ + +BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds, + prs_struct *rpc_in) +{ + int fn_num; + + /* interpret the command */ + DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); + + for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { + if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { + DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name)); + break; + } + } + + if (api_rpc_cmds[fn_num].name == NULL) { + /* + * For an unknown RPC just return a fault PDU but + * return True to allow RPC's on the pipe to continue + * and not put the pipe into fault state. JRA. + */ + DEBUG(4, ("unknown\n")); + setup_fault_pdu(p); + return True; + } + + /* do the actual command */ + if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->out_data.rdata)) { + DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); + prs_mem_free(&p->out_data.rdata); + return False; + } + + DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name)); + + return True; +} -- cgit From 32811abdf10bd499d3ea3d511f176528e2a04002 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 10 Mar 2000 17:03:04 +0000 Subject: restore the spoolss pipe as Jeremy replaced srv_pipe with the one from SAMBA_2_0 :-) J.F. (This used to be commit 34a3781961a5c41aba9929ec49aacc3bfa14270f) --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 11822e7d03..9079590f31 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -475,6 +475,7 @@ static struct api_cmd api_fd_commands[] = #if 1 /* DISABLED_IN_2_0 JRATEST */ { "winreg", "winreg", api_reg_rpc }, #endif + { "spoolss", "spoolss", api_spoolss_rpc }, { NULL, NULL, NULL } }; -- cgit From 5e22394654eba2ed5d01e81b165a044a59dd65ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Mar 2000 19:50:03 +0000 Subject: Fixups for compiles with gcc flags -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual Partially implemented rpc daemon redirect (needs more work). Jeremy. (This used to be commit a462191698fa589ceac4afd14c652adf699eccad) --- source3/rpc_server/srv_pipe.c | 27 --------------------------- 1 file changed, 27 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9079590f31..9a17862bd5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -492,15 +492,6 @@ BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p) DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); - /* - * Create the response data buffer. - */ - - if(!pipe_init_outgoing_data(&p->out_data)) { - DEBUG(0,("api_pipe_bind_auth_resp: failed to create outgoing buffer.\n")); - return False; - } - if (p->hdr.auth_len == 0) { DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n")); return False; @@ -695,15 +686,6 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); - /* - * Create the response data buffer. - */ - - if(!pipe_init_outgoing_data(&p->out_data)) { - DEBUG(0,("api_pipe_bind_req: failed to create outgoing buffer.\n")); - return False; - } - /* * Try and find the correct pipe name to ensure * that this is a pipe name we support. @@ -1062,15 +1044,6 @@ BOOL api_pipe_request(pipes_struct *p) BOOL ret = False; BOOL changed_user_id = False; - /* - * Create the response data buffer. - */ - - if(!pipe_init_outgoing_data(&p->out_data)) { - DEBUG(0,("api_pipe_request: failed to create outgoing buffer.\n")); - return False; - } - if (p->ntlmssp_auth_validated) { if(!become_authenticated_pipe_user(p)) { -- cgit From ba0a53b52ca934389268b65ec0d9e7336ae85d4f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 4 Apr 2000 00:35:34 +0000 Subject: Removed unused parameter vuid from rpc_server api_* calls. For the very few functions that need to access the vuid, it can be obtained from the current_user global. Did some whitespace cleanup. (This used to be commit 738b307bd7053ede369431da7b1349befaa523d9) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9a17862bd5..ebb38154d3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1099,7 +1099,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds } /* do the actual command */ - if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->out_data.rdata)) { + if(!api_rpc_cmds[fn_num].fn(rpc_in, &p->out_data.rdata)) { DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); prs_mem_free(&p->out_data.rdata); return False; -- cgit From 067b341a01319577f59e4c742f7bf11b42381ecc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Apr 2000 19:02:41 +0000 Subject: Ensure sign&seal work. Data len must have RPC_HEADER_LEN removed, but offset should not (rpc header already consumed). This fix does not affect tng. Jeremy. (This used to be commit 018ec4fdd937994824f53cb956cea1ade9690f97) --- source3/rpc_server/srv_pipe.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ebb38154d3..a20b112196 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -969,7 +969,11 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); if (auth_seal) { - char *data = prs_data_p(rpc_in) + RPC_HEADER_LEN + RPC_HDR_REQ_LEN; + /* + * The data in rpc_in doesn't contain the RPC_HEADER as this + * has already been consumed. + */ + char *data = prs_data_p(rpc_in) + RPC_HDR_REQ_LEN; NTLMSSPcalc_p(p, (uchar*)data, data_len); crc32 = crc32_calc_buffer(data, data_len); } -- cgit From d2db520692898c317acc2eba78f88f8398a1fd21 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Apr 2000 21:23:26 +0000 Subject: Sync up with 2.0.7 w.r.t. guest users. Jeremy. (This used to be commit 8a99d824c0e9a43c8a8c81140f8c9005c7e2621a) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a20b112196..fe78d48fa6 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -312,9 +312,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm * Allow guest access. Patch from Shirish Kalele . */ - if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_lm_resp.str_str_len==0) && - (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) { - + if((strlen(user_name) == 0) && + (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) + { guest_user = True; fstrcpy(unix_user_name, lp_guestaccount(-1)); -- cgit From 00e3fe132476fcaed0f4b9bbe74b0a6559c39df0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Apr 2000 14:06:57 +0000 Subject: moved trans2.h and nterr.h into includes.h with all our other includes (This used to be commit d7cd7c88fdabb01d9e40ae8a657737907a21ac37) --- source3/rpc_server/srv_pipe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index fe78d48fa6..3637f68adf 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -39,7 +39,6 @@ */ #include "includes.h" -#include "nterr.h" extern int DEBUGLEVEL; -- cgit From c23e01d049cc7aee34e8ac83efeb74c09aa257a2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 May 2000 13:28:19 +0000 Subject: the beginnings of a new scheme I've working on to allow an easier head/tng merge. It goes something like this: - headers from tng get copied over one at a time - the old headers get renamed to *_old.h - server side code that used the old headers gets a #define OLD_NTDOMAIN 1 #undef OLD_NTDOMAIN at the start and end of the code - mkproto.awk recognises these special defines and does magic stuff so that each .c file sees the right headers - we start moving the rpc client libraries from tng to head. if this goes OK then, in theory, we should be able to move the client side rpc code from tng to head without disturbing the existing head server side code. Then when that works we can consider merging the server side. it remains to be seen if this scheme will work. So far I've moved rpc_samr.h and don't seem to have broken anything. Note this this is still a very delicate operation, as at every step of the way I want to keep head fully functional. Please don't take part unless you discuss it with me first. (This used to be commit f76c037255a6a79d11bec65e863e009a41a4f0fd) --- source3/rpc_server/srv_pipe.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3637f68adf..581d6c04bd 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,3 +1,4 @@ +#define OLD_NTDOMAIN 1 /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -1112,3 +1113,5 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds return True; } + +#undef OLD_NTDOMAIN -- cgit From 378ec58bebdbc2ae7c7306fc25f358a58478ecf8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 May 2000 07:18:12 +0000 Subject: add prs_dump() at the top level rpc switch this gets us examples of all rpc messages sent to us (This used to be commit ce3dd8db6d3cf6bfdbd695f6e32f60488c9073ae) --- source3/rpc_server/srv_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 581d6c04bd..9c1ad2ef5a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1084,6 +1084,8 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds /* interpret the command */ DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); + prs_dump(rpc_name, p->hdr_req.opnum, rpc_in); + for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name)); -- cgit From e2e33eb3207e1a6f85ca36cafc564aa9427fd7af Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 May 2000 09:59:58 +0000 Subject: call prs_dump() on every input and output packet so we have plenty of data to work with (This used to be commit 839ab0e33255be37d72c113c2e09baaa34d50ce4) --- source3/rpc_server/srv_pipe.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9c1ad2ef5a..853c1b8ed6 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1080,11 +1080,14 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds prs_struct *rpc_in) { int fn_num; - + fstring name; + uint32 offset1, offset2; + /* interpret the command */ DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); - prs_dump(rpc_name, p->hdr_req.opnum, rpc_in); + slprintf(name, sizeof(name), "in_%s", rpc_name); + prs_dump(name, p->hdr_req.opnum, rpc_in); for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { @@ -1104,6 +1107,8 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds return True; } + offset1 = p->out_data.rdata.data_offset; + /* do the actual command */ if(!api_rpc_cmds[fn_num].fn(rpc_in, &p->out_data.rdata)) { DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); @@ -1111,6 +1116,12 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds return False; } + slprintf(name, sizeof(name), "out_%s", rpc_name); + offset2 = p->out_data.rdata.data_offset; + p->out_data.rdata.data_offset = offset1; + prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata); + p->out_data.rdata.data_offset = offset2; + DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name)); return True; -- cgit From b27886addbdb1ff7c8e678023c7c1ef6d3bba9a9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 May 2000 17:13:50 +0000 Subject: passdb/secrets.c: Fix typo in comment. rpc_server/srv_pipe.c: Use accessor functions rather than diddling with structure internals directly. smbd/process.c: smbd/reply.c: Remove READ_PREDICTION #ifdefs. Jeremy. (This used to be commit eba825ff030a175bd271caa6f543379dfdbbd646) --- source3/rpc_server/srv_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 853c1b8ed6..ebd4f55fce 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1107,7 +1107,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds return True; } - offset1 = p->out_data.rdata.data_offset; + offset1 = prs_offset(&p->out_data.rdata); /* do the actual command */ if(!api_rpc_cmds[fn_num].fn(rpc_in, &p->out_data.rdata)) { @@ -1117,10 +1117,10 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds } slprintf(name, sizeof(name), "out_%s", rpc_name); - offset2 = p->out_data.rdata.data_offset; - p->out_data.rdata.data_offset = offset1; + offset2 = prs_offset(&p->out_data.rdata); + prs_set_offset(&p->out_data.rdata, offset1); prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata); - p->out_data.rdata.data_offset = offset2; + prs_set_offset(&p->out_data.rdata, offset2); DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name)); -- cgit From 4fb2e2c72f25a1204bf764504c370d746d12a162 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 May 2000 20:08:26 +0000 Subject: Added fix for Win2k ACL query code from Shirish. I need this back ported to 2.2.0. Jeremy. (This used to be commit 74851a481efedd15f59d5da15db7078dc4ce5d20) --- source3/rpc_server/srv_pipe.c | 57 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ebd4f55fce..9ba62ea656 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -472,9 +472,7 @@ static struct api_cmd api_fd_commands[] = { "srvsvc", "ntsvcs", api_srvsvc_rpc }, { "wkssvc", "ntsvcs", api_wkssvc_rpc }, { "NETLOGON", "lsass", api_netlog_rpc }, -#if 1 /* DISABLED_IN_2_0 JRATEST */ { "winreg", "winreg", api_reg_rpc }, -#endif { "spoolss", "spoolss", api_spoolss_rpc }, { NULL, NULL, NULL } }; @@ -664,6 +662,43 @@ BOOL setup_fault_pdu(pipes_struct *p) return True; } +/******************************************************************* + Ensure a bind request has the correct abstract & transfer interface. + Used to reject unknown binds from Win2k. +*******************************************************************/ + +BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, + RPC_IFACE* transfer) +{ + extern struct pipe_id_info pipe_names[]; + int i=0; + fstring pname; + fstrcpy(pname,"\\PIPE\\"); + fstrcat(pname,pipe_name); + + for(i=0;pipe_names[i].client_pipe; i++) { + if(strequal(pipe_names[i].client_pipe, pname)) + break; + } + + if(pipe_names[i].client_pipe == NULL) + return False; + + /* check the abstract interface */ + if((abstract->version != pipe_names[i].abstr_syntax.version) || + (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, + sizeof(RPC_UUID)) != 0)) + return False; + + /* check the transfer interface */ + if((transfer->version != pipe_names[i].trans_syntax.version) || + (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, + sizeof(RPC_UUID)) != 0)) + return False; + + return True; +} + /******************************************************************* Respond to a pipe bind request. *******************************************************************/ @@ -823,13 +858,29 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) * Create the bind response struct. */ - init_rpc_hdr_ba(&hdr_ba, + /* If the requested abstract synt uuid doesn't match our client pipe, + reject the bind_ack & set the transfer interface synt to all 0's, + ver 0 (observed when NT5 attempts to bind to abstract interfaces + unknown to NT4) + Needed when adding entries to a DACL from NT5 - SK */ + + if(check_bind_req(p->name, &hdr_rb.abstract, &hdr_rb.transfer)) { + init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x0, 0x0, &hdr_rb.transfer); + } else { + RPC_IFACE null_interface; + ZERO_STRUCT(null_interface); + /* Rejection reason: abstract syntax not supported */ + init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN, + MAX_PDU_FRAG_LEN, assoc_gid, + ack_pipe_name, 0x1, 0x2, 0x1, + &null_interface); + } /* * and marshall it. -- cgit From c560164030c0b842ee06f651a2b019c5596624a2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 May 2000 03:12:56 +0000 Subject: Fixed bug where mallocd size of prs_struct could be larger than incoming packet. Ensure new alloced memory is zeroed before use. Jeremy. (This used to be commit 1c3193aa1c1137734dc34ef2e6d62abb0609c30e) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9ba62ea656..06743d8d16 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -110,7 +110,7 @@ BOOL create_next_pdu(pipes_struct *p) p->hdr.flags = 0; /* - * Work out how much we can fit in a sigle PDU. + * Work out how much we can fit in a single PDU. */ data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; -- cgit From 74d677ec591a715e28dba29a33ee40e1b1c2f830 Mon Sep 17 00:00:00 2001 From: Shirish Kalele Date: Thu, 18 May 2000 18:43:53 +0000 Subject: Added the NETDFS pipe to allow remote administration of the msdfs symlinks on the samba server. (This used to be commit 15e7d8f6c5cddf6ce409ee2505744250d181ec34) --- source3/rpc_server/srv_pipe.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 06743d8d16..aef0c9d23b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -474,6 +474,9 @@ static struct api_cmd api_fd_commands[] = { "NETLOGON", "lsass", api_netlog_rpc }, { "winreg", "winreg", api_reg_rpc }, { "spoolss", "spoolss", api_spoolss_rpc }, +#ifdef MS_DFS + { "netdfs", "netdfs" , api_netdfs_rpc }, +#endif { NULL, NULL, NULL } }; -- cgit From 8a86541e282424c4e0ea5626b26e818779ba0375 Mon Sep 17 00:00:00 2001 From: Shirish Kalele Date: Fri, 26 May 2000 17:10:40 +0000 Subject: Changed MS_DFS to WITH_MSDFS throughout. Fixed trans2 calls on IPC$ to let dfs referral calls through. (This used to be commit e0965a80bdca5239886b11ef55dc29fed261bfc0) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index aef0c9d23b..11dc5a2f89 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -474,7 +474,7 @@ static struct api_cmd api_fd_commands[] = { "NETLOGON", "lsass", api_netlog_rpc }, { "winreg", "winreg", api_reg_rpc }, { "spoolss", "spoolss", api_spoolss_rpc }, -#ifdef MS_DFS +#ifdef WITH_MSDFS { "netdfs", "netdfs" , api_netdfs_rpc }, #endif { NULL, NULL, NULL } -- cgit From a72f277f721903d504fc8501de55bf8c07801e05 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 16 Jun 2000 08:11:32 +0000 Subject: Simplified server pipe implementation by changing arguments passed down through to the individual pipe api calls. Instead of passing two prs_struct pointers, we now pass the pipes_struct pointer which contains the former information as well as other useful stuff like the vuid. (This used to be commit 96addba216bad2189120d78f5531d5caa6f37880) --- source3/rpc_server/srv_pipe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 11dc5a2f89..46cb521018 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -462,7 +462,7 @@ struct api_cmd { char * pipe_clnt_name; char * pipe_srv_name; - BOOL (*fn) (pipes_struct *, prs_struct *); + BOOL (*fn) (pipes_struct *); }; static struct api_cmd api_fd_commands[] = @@ -1116,7 +1116,7 @@ BOOL api_pipe_request(pipes_struct *p) if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && api_fd_commands[i].fn != NULL) { DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); - ret = api_fd_commands[i].fn(p, &p->in_data.data); + ret = api_fd_commands[i].fn(p); } } @@ -1130,8 +1130,8 @@ BOOL api_pipe_request(pipes_struct *p) Calls the underlying RPC function for a named pipe. ********************************************************************/ -BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds, - prs_struct *rpc_in) +BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, + struct api_struct *api_rpc_cmds) { int fn_num; fstring name; @@ -1141,7 +1141,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); slprintf(name, sizeof(name), "in_%s", rpc_name); - prs_dump(name, p->hdr_req.opnum, rpc_in); + prs_dump(name, p->hdr_req.opnum, &p->in_data.data); for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { @@ -1164,7 +1164,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds offset1 = prs_offset(&p->out_data.rdata); /* do the actual command */ - if(!api_rpc_cmds[fn_num].fn(rpc_in, &p->out_data.rdata)) { + if(!api_rpc_cmds[fn_num].fn(p)) { DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); prs_mem_free(&p->out_data.rdata); return False; -- cgit From 218653764f55b5fe16ffbda93d415a1495460956 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Jun 2000 05:53:18 +0000 Subject: Removed save directory argument to become_root() calls. Probably most of this stuff doesn't need to be done as root anyway. (This used to be commit c3cad0ff6482784f95fd54ba51ee5be2354bb95d) --- source3/rpc_server/srv_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 46cb521018..a5d69efd7e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -360,24 +360,24 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm if(!guest_user) { - become_root(True); + become_root(); if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain, (uchar*)p->challenge, lm_owf, nt_owf, NULL))) { DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name )); - unbecome_root(True); + unbecome_root(); return False; } if(!(smb_pass = getsmbpwnam(unix_user_name))) { DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", unix_user_name)); - unbecome_root(True); + unbecome_root(); return False; } - unbecome_root(True); + unbecome_root(); if (smb_pass == NULL) { DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", -- cgit From f048209484b10ed397c55864ca9ee29789f4e372 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jul 2000 06:52:31 +0000 Subject: Some more sec_ctx changes. Modified some fields in the pipe_struct structure so authenticated pipe users can have their unix groups set when become_authenticated_pipe_user() is called. (This used to be commit 55c9bf124dc661df43bfe582ef14b1297aeaf0fa) --- source3/rpc_server/srv_pipe.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a5d69efd7e..f6746367bb 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -260,7 +260,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm uchar lm_owf[24]; uchar nt_owf[24]; fstring user_name; - fstring unix_user_name; + fstring pipe_user_name; fstring domain; fstring wks; BOOL guest_user = False; @@ -272,7 +272,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); memset(p->user_name, '\0', sizeof(p->user_name)); - memset(p->unix_user_name, '\0', sizeof(p->unix_user_name)); + memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); memset(p->domain, '\0', sizeof(p->domain)); memset(p->wks, '\0', sizeof(p->wks)); @@ -317,8 +317,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm { guest_user = True; - fstrcpy(unix_user_name, lp_guestaccount(-1)); - DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", unix_user_name)); + fstrcpy(pipe_user_name, lp_guestaccount(-1)); + DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", pipe_user_name)); smb_passwd_ptr = null_smb_passwd; @@ -329,8 +329,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm * function. */ - fstrcpy(unix_user_name, user_name); - (void)map_username(unix_user_name); + fstrcpy(pipe_user_name, user_name); + (void)map_username(pipe_user_name); /* * Do the length checking only if user is not NULL. @@ -353,8 +353,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm * Find the user in the unix password db. */ - if(!(pass = Get_Pwnam(unix_user_name,True))) { - DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",unix_user_name)); + if(!(pass = Get_Pwnam(pipe_user_name,True))) { + DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",pipe_user_name)); return(False); } @@ -362,17 +362,17 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm become_root(); - if(!(p->ntlmssp_auth_validated = pass_check_smb(unix_user_name, domain, + if(!(p->ntlmssp_auth_validated = pass_check_smb(pipe_user_name, domain, (uchar*)p->challenge, lm_owf, nt_owf, NULL))) { DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ -failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name )); +failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); unbecome_root(); return False; } - if(!(smb_pass = getsmbpwnam(unix_user_name))) { + if(!(smb_pass = getsmbpwnam(pipe_user_name))) { DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", - unix_user_name)); + pipe_user_name)); unbecome_root(); return False; } @@ -381,18 +381,18 @@ failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name if (smb_pass == NULL) { DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", - unix_user_name)); + pipe_user_name)); return(False); } /* Quit if the account was disabled. */ if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) { - DEBUG(1,("Account for user '%s' was disabled.\n", unix_user_name)); + DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); return(False); } if(!smb_pass->smb_nt_passwd) { - DEBUG(1,("Account for user '%s' has no NT password hash.\n", unix_user_name)); + DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); return(False); } @@ -439,7 +439,7 @@ failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name } fstrcpy(p->user_name, user_name); - fstrcpy(p->unix_user_name, unix_user_name); + fstrcpy(p->pipe_user_name, pipe_user_name); fstrcpy(p->domain, domain); fstrcpy(p->wks, wks); @@ -447,8 +447,10 @@ failed authentication on named pipe %s.\n", domain, unix_user_name, wks, p->name * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - p->uid = pass->pw_uid; - p->gid = pass->pw_gid; + p->pipe_user.uid = pass->pw_uid; + p->pipe_user.gid = pass->pw_gid; + + /* XXX also set up pipe user group membership */ p->ntlmssp_auth_validated = True; return True; -- cgit From 5ec1642809d9de83da8c88c65d6595c6eb0270f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Jul 2000 00:47:19 +0000 Subject: Ok - this is a *BIG* change - but it fixes the problems with static strings in the RPC code. This change was prompted by trying to save a long (>256) character comment in the printer properties page. The new system associates a TALLOC_CTX with the pipe struct, and frees the pool on return of a complete PDU. A global TALLOC_CTX is used for the odd buffer allocated in the BUFFERxx code, and is freed in the main loop. This code works with insure, and seems to be free of memory leaks and crashes (so far) but there are probably the occasional problem with code that uses UNISTRxx structs on the stack and expects them to contain storage without doing a init_unistrXX(). This means that rpcclient will probably be horribly broken. A TALLOC_CTX also needed associating with the struct cli_state also, to make the prs_xx code there work. The main interface change is the addition of a TALLOC_CTX to the prs_init calls - used for dynamic allocation in the prs_XXX calls. Now this is in place it should make dynamic allocation of all RPC memory on unmarshall *much* easier to fix. Jeremy. (This used to be commit 0ff2ce543ee54f7364e6d839db6d06e7ef1edcf4) --- source3/rpc_server/srv_pipe.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index f6746367bb..6f650c7e5e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -167,17 +167,19 @@ BOOL create_next_pdu(pipes_struct *p) * data. */ - prs_init( &outgoing_pdu, 0, 4, MARSHALL); + prs_init( &outgoing_pdu, 0, 4, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* Store the header in the data stream. */ if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n")); + prs_mem_free(&outgoing_pdu); return False; } if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n")); + prs_mem_free(&outgoing_pdu); return False; } @@ -189,6 +191,7 @@ BOOL create_next_pdu(pipes_struct *p) if(!prs_append_data(&outgoing_pdu, data_from, data_len)) { DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len)); + prs_mem_free(&outgoing_pdu); return False; } @@ -216,6 +219,7 @@ BOOL create_next_pdu(pipes_struct *p) (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0)); if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); + prs_mem_free(&outgoing_pdu); return False; } } @@ -230,6 +234,7 @@ BOOL create_next_pdu(pipes_struct *p) auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4; if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n")); + prs_mem_free(&outgoing_pdu); return False; } NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); @@ -244,6 +249,7 @@ BOOL create_next_pdu(pipes_struct *p) p->out_data.current_pdu_len = p->hdr.frag_len; p->out_data.current_pdu_sent = 0; + prs_mem_free(&outgoing_pdu); return True; } @@ -566,7 +572,7 @@ static BOOL setup_bind_nak(pipes_struct *p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_rpc, 0, 4, MARSHALL); + prs_init( &outgoing_rpc, 0, 4, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); @@ -583,6 +589,7 @@ static BOOL setup_bind_nak(pipes_struct *p) if(!smb_io_rpc_hdr("", &nak_hdr, &outgoing_rpc, 0)) { DEBUG(0,("setup_bind_nak: marshalling of RPC_HDR failed.\n")); + prs_mem_free(&outgoing_rpc); return False; } @@ -590,8 +597,10 @@ static BOOL setup_bind_nak(pipes_struct *p) * Now add the reject reason. */ - if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) + if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) { + prs_mem_free(&outgoing_rpc); return False; + } p->out_data.data_sent_length = 0; p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); @@ -622,7 +631,7 @@ BOOL setup_fault_pdu(pipes_struct *p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_pdu, 0, 4, MARSHALL); + prs_init( &outgoing_pdu, 0, 4, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -647,16 +656,19 @@ BOOL setup_fault_pdu(pipes_struct *p) if(!smb_io_rpc_hdr("", &fault_hdr, &outgoing_pdu, 0)) { DEBUG(0,("setup_fault_pdu: marshalling of RPC_HDR failed.\n")); + prs_mem_free(&outgoing_pdu); return False; } if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_RESP.\n")); + prs_mem_free(&outgoing_pdu); return False; } if(!smb_io_rpc_hdr_fault("fault", &fault_resp, &outgoing_pdu, 0)) { DEBUG(0,("setup_fault_pdu: failed to marshall RPC_HDR_FAULT.\n")); + prs_mem_free(&outgoing_pdu); return False; } @@ -664,6 +676,7 @@ BOOL setup_fault_pdu(pipes_struct *p) p->out_data.current_pdu_len = prs_offset(&outgoing_pdu); p->out_data.current_pdu_sent = 0; + prs_mem_free(&outgoing_pdu); return True; } @@ -835,7 +848,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_rpc, 0, 4, MARSHALL); + prs_init( &outgoing_rpc, 0, 4, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -843,13 +856,15 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) * auth footers. */ - if(!prs_init(&out_hdr_ba, 1024, 4, MARSHALL)) { + if(!prs_init(&out_hdr_ba, 1024, 4, p->mem_ctx, MARSHALL)) { DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); + prs_mem_free(&outgoing_rpc); return False; } - if(!prs_init(&out_auth, 1024, 4, MARSHALL)) { + if(!prs_init(&out_auth, 1024, 4, p->mem_ctx, MARSHALL)) { DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n")); + prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); return False; } @@ -984,6 +999,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) err_exit: + prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); prs_mem_free(&out_auth); return False; -- cgit From 7f36df301e28dc8ca0e5bfadc109d6e907d9ba2b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Aug 2000 18:32:34 +0000 Subject: Tidyup removing many of the 0xC0000000 | NT_STATUS_XXX stuff (only need NT_STATUS_XXX). Removed IS_BITS_xxx macros as they were just reproducing "C" syntax in a more obscure way. Jeremy. (This used to be commit c55bcec817f47d6162466b193d533c877194124a) --- source3/rpc_server/srv_pipe.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 6f650c7e5e..049db69ca7 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -78,8 +78,8 @@ static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) BOOL create_next_pdu(pipes_struct *p) { RPC_HDR_RESP hdr_resp; - BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); - BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); + BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0); + BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0); uint32 data_len; uint32 data_space_available; uint32 data_len_left; @@ -292,7 +292,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm * We always negotiate UNICODE. */ - if (IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_UNICODE)) { + if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); @@ -1014,8 +1014,8 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) /* * We always negotiate the following two bits.... */ - BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN); - BOOL auth_seal = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SEAL); + BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0); + BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0); int data_len; int auth_len; uint32 old_offset; -- cgit From 06e4f11acd3aedd6c8e4adf365932a01eca902b8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Aug 2000 00:59:09 +0000 Subject: Fixed up the user/group contexts when using authenticated pipes. Added a become_root()/unbecome_root() (push/pop security context) around the initgroups() call to ensure it would succeed. Hmmm - I wonder if this call being done as non-root might explain any "group access" bugs we've had in the past.... Jeremy. (This used to be commit 06a65972e872f37d88b84f22ea714feebd38f6c0) --- source3/rpc_server/srv_pipe.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 049db69ca7..ded01e4e21 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -282,6 +282,11 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm memset(p->domain, '\0', sizeof(p->domain)); memset(p->wks, '\0', sizeof(p->wks)); + /* Set up for non-authenticated user. */ + delete_nt_token(&p->pipe_user.nt_user_token); + p->pipe_user.ngroups = 0; + safe_free( p->pipe_user.groups); + /* * Setup an empty password for a guest user. */ @@ -456,7 +461,13 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name p->pipe_user.uid = pass->pw_uid; p->pipe_user.gid = pass->pw_gid; - /* XXX also set up pipe user group membership */ + /* Set up pipe user group membership. */ + initialize_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); + get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); + + /* Create an NT_USER_TOKEN struct for this user. */ + p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, + p->pipe_user.ngroups, p->pipe_user.groups); p->ntlmssp_auth_validated = True; return True; -- cgit From d12f3fea7529c03b6a3650e7aa8b4b47a445d548 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Aug 2000 06:46:53 +0000 Subject: Merge from appliance branch. (This used to be commit 567b0095b1b8393b3b1e32533aa2860ab3dbfa47) --- source3/rpc_server/srv_pipe.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ded01e4e21..44bca13c1a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -462,6 +462,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name p->pipe_user.gid = pass->pw_gid; /* Set up pipe user group membership. */ + initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); initialize_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); -- cgit From 75c346e70c83f7386ecd2f10fe155c4a4dfd47de Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 7 Oct 2000 15:56:36 +0000 Subject: added samr_set_user_info and info_2. cleanup of create_user cleanup of rid/sid mix in samr. now we only have sid. some prs_align() missing in parse_samr.c a small debug change in srv_pipe.c You still can't change a user's password in this commit. Will be availble in the next one. J.F. (This used to be commit b655bc281fa183b1827a946ada1fcf500fb93aea) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 44bca13c1a..01d9568477 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1195,7 +1195,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, /* do the actual command */ if(!api_rpc_cmds[fn_num].fn(p)) { - DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); + DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name)); prs_mem_free(&p->out_data.rdata); return False; } -- cgit From cbee552bdb1a4692a19667175fbbf090a9597d71 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 11 Oct 2000 04:54:37 +0000 Subject: Don't initialise groups twice. (This used to be commit 15d7f16bdc2ff4f2ae82871eb9f318ba45cf4d1c) --- source3/rpc_server/srv_pipe.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 01d9568477..fd5155a554 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -463,7 +463,6 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* Set up pipe user group membership. */ initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); - initialize_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); /* Create an NT_USER_TOKEN struct for this user. */ -- cgit From 282930d31f83e658573d1582d2ac89c98616ee2d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 18 Oct 2000 01:15:05 +0000 Subject: Merge of rpc parse buffer underflow debug code. (This used to be commit c8d88713d9f7a646eb3b8e76bdd0250a3b89b722) --- source3/rpc_server/srv_pipe.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index fd5155a554..4cb57c69d8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1207,6 +1207,25 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, DEBUG(5,("api_rpcTNP: called %s successfully\n", rpc_name)); + /* Check for buffer underflow in rpc parsing */ + + if ((DEBUGLEVEL >= 10) && + (p->in_data.data.data_offset != p->in_data.data.buffer_size)) { + int data_len = p->in_data.data.buffer_size - + p->in_data.data.data_offset; + char *data; + + data = malloc(data_len); + + DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n")); + if (data) { + prs_uint8s(False, "", &p->in_data.data, 0, data, + data_len); + free(data); + } + + } + return True; } -- cgit From 9fede0dc0dbad51528cd1384023d24549c3f0ba4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 13 Nov 2000 23:03:34 +0000 Subject: Large commit which restructures the local password storage API. Currently the only backend which works is smbpasswd (tdb, LDAP, and NIS+) are broken, but they were somewhat broken before. :) The following functions implement the storage manipulation interface /*The following definitions come from passdb/pdb_smbpasswd.c */ BOOL pdb_setsampwent (BOOL update); void pdb_endsampwent (void); SAM_ACCOUNT* pdb_getsampwent (void); SAM_ACCOUNT* pdb_getsampwnam (char *username); SAM_ACCOUNT* pdb_getsampwuid (uid_t uid); SAM_ACCOUNT* pdb_getsampwrid (uint32 rid); BOOL pdb_add_sam_account (SAM_ACCOUNT *sampass); BOOL pdb_update_sam_account (SAM_ACCOUNT *sampass, BOOL override); BOOL pdb_delete_sam_account (char* username); There is also a host of pdb_set..() and pdb_get..() functions for manipulating SAM_ACCOUNT struct members. Note that the struct passdb_ops {} has gone away. Also notice that struct smb_passwd (formally in smb.h) has been moved to passdb/pdb_smbpasswd.c and is not accessed outisde of static internal functions in this file. All local password searches should make use of the the SAM_ACCOUNT struct and the previously mentioned functions. I'll write some documentation for this later. The next step is to fix the TDB passdb backend, then work on spliting the backends out into share libraries, and finally get the LDAP backend going. What works and may not: o domain logons from Win9x works o domain logons from WinNT 4 works o user and group enumeration as implemented by Tim works o file and print access works o changing password from Win9x & NT ummm...i'll fix this tonight :) If I broke anything else, just yell and I'll fix it. I think it should be fairly quite. -- jerry (This used to be commit 0b92d0838ebdbe24f34f17e313ecbf61a0301389) --- source3/rpc_server/srv_pipe.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4cb57c69d8..d15f045252 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -270,10 +270,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm fstring domain; fstring wks; BOOL guest_user = False; - struct smb_passwd *smb_pass = NULL; - struct passwd *pass = NULL; - uchar null_smb_passwd[16]; - uchar *smb_passwd_ptr = NULL; + SAM_ACCOUNT *sam_pass = NULL; + BYTE null_smb_passwd[16]; + BYTE *smb_passwd_ptr = NULL; DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); @@ -359,7 +358,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm return False; } - +/* unnecessary as the passdb validates the user before returning --jerry */ +#if 0 /* * Find the user in the unix password db. */ @@ -369,6 +369,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm return(False); } +#endif /* 0 */ + if(!guest_user) { become_root(); @@ -381,8 +383,8 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name return False; } - if(!(smb_pass = getsmbpwnam(pipe_user_name))) { - DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", + if(!(sam_pass = pdb_getsampwnam(pipe_user_name))) { + DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in passdb.\n", pipe_user_name)); unbecome_root(); return False; @@ -390,24 +392,24 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name unbecome_root(); - if (smb_pass == NULL) { - DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in smb_passwd file.\n", + if (sam_pass == NULL) { + DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in passdb.\n", pipe_user_name)); return(False); } /* Quit if the account was disabled. */ - if((smb_pass->acct_ctrl & ACB_DISABLED) || !smb_pass->smb_passwd) { + if((pdb_get_acct_ctrl(sam_pass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sam_pass)) { DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); return(False); } - if(!smb_pass->smb_nt_passwd) { + if(!pdb_get_nt_passwd(sam_pass)) { DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); return(False); } - smb_passwd_ptr = smb_pass->smb_passwd; + smb_passwd_ptr = pdb_get_lanman_passwd(sam_pass); } /* @@ -457,9 +459,8 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - - p->pipe_user.uid = pass->pw_uid; - p->pipe_user.gid = pass->pw_gid; + p->pipe_user.uid = pdb_get_uid(sam_pass); + p->pipe_user.gid = pdb_get_gid(sam_pass); /* Set up pipe user group membership. */ initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); @@ -467,7 +468,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* Create an NT_USER_TOKEN struct for this user. */ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups); + p->pipe_user.ngroups, p->pipe_user.groups); p->ntlmssp_auth_validated = True; return True; -- cgit From 90a7d7d3d7e77ed1f33e2bb9969beef7aa464712 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 12 Dec 2000 05:29:47 +0000 Subject: Compile fix for new arg to create_nt_token() (This used to be commit 806185ca8cc8d28f16745a1db9427f52eb8d22e4) --- source3/rpc_server/srv_pipe.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index d15f045252..6d0a006593 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -467,8 +467,10 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); /* Create an NT_USER_TOKEN struct for this user. */ - p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups); + p->pipe_user.nt_user_token = + create_nt_token(p->pipe_user.uid,p->pipe_user.gid, + p->pipe_user.ngroups, p->pipe_user.groups, + guest_user); p->ntlmssp_auth_validated = True; return True; -- cgit From 25db9b02ba36b25c3254bbb44323fcbfa2a2a5e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Mar 2001 05:01:20 +0000 Subject: Fix for AS/U not liking it's own assoc_gid. Jeremy. (This used to be commit 81fe571daf62ff3f53d7137dcd30312b6874b786) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 6d0a006593..c0174280ab 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -886,7 +886,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) if (p->ntlmssp_auth_requested) assoc_gid = 0x7a77; else - assoc_gid = hdr_rb.bba.assoc_gid; + assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0; /* * Create the bind response struct. -- cgit From 00ab9021b0cc5fe2667d383eb9cc2973072cdaaa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Mar 2001 23:48:58 +0000 Subject: Serious (and I *mean* serious) attempt to fix little/bigendian RPC issues. We were reading the endainness in the RPC header and then never propagating it to the internal parse_structs used to parse the data. Also removed the "align" argument to prs_init as it was *always* set to 4, and if needed can be set differently on a case by case basis. Now ready for AS/U testing when Herb gets it set up :-). Jeremy. (This used to be commit 0cd37c831d79a12a10e479bf4fa89ffe64c1292a) --- source3/rpc_server/srv_pipe.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index c0174280ab..dcefeed8b9 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -167,7 +167,7 @@ BOOL create_next_pdu(pipes_struct *p) * data. */ - prs_init( &outgoing_pdu, 0, 4, p->mem_ctx, MARSHALL); + prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* Store the header in the data stream. */ @@ -586,7 +586,7 @@ static BOOL setup_bind_nak(pipes_struct *p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_rpc, 0, 4, p->mem_ctx, MARSHALL); + prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); @@ -645,7 +645,7 @@ BOOL setup_fault_pdu(pipes_struct *p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_pdu, 0, 4, p->mem_ctx, MARSHALL); + prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -862,7 +862,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_rpc, 0, 4, p->mem_ctx, MARSHALL); + prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -870,13 +870,13 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) * auth footers. */ - if(!prs_init(&out_hdr_ba, 1024, 4, p->mem_ctx, MARSHALL)) { + if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) { DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); prs_mem_free(&outgoing_rpc); return False; } - if(!prs_init(&out_auth, 1024, 4, p->mem_ctx, MARSHALL)) { + if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) { DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n")); prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/rpc_server/srv_pipe.c | 71 ++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 45 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index dcefeed8b9..bc5b2ab473 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,4 +1,3 @@ -#define OLD_NTDOMAIN 1 /* * Unix SMB/Netbios implementation. * Version 1.9. @@ -270,9 +269,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm fstring domain; fstring wks; BOOL guest_user = False; - SAM_ACCOUNT *sam_pass = NULL; - BYTE null_smb_passwd[16]; - BYTE *smb_passwd_ptr = NULL; + SAM_ACCOUNT *sampass = NULL; + uchar null_smb_passwd[16]; + uchar *smb_passwd_ptr = NULL; DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); @@ -358,18 +357,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm return False; } -/* unnecessary as the passdb validates the user before returning --jerry */ -#if 0 - /* - * Find the user in the unix password db. - */ - - if(!(pass = Get_Pwnam(pipe_user_name,True))) { - DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",pipe_user_name)); - return(False); - } - -#endif /* 0 */ if(!guest_user) { @@ -383,8 +370,8 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name return False; } - if(!(sam_pass = pdb_getsampwnam(pipe_user_name))) { - DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in passdb.\n", + if(!(sampass = pdb_getsampwnam(pipe_user_name))) { + DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", pipe_user_name)); unbecome_root(); return False; @@ -392,24 +379,18 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name unbecome_root(); - if (sam_pass == NULL) { - DEBUG(1,("api_pipe_ntlmssp_verify: Couldn't find user '%s' in passdb.\n", - pipe_user_name)); - return(False); - } - - /* Quit if the account was disabled. */ - if((pdb_get_acct_ctrl(sam_pass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sam_pass)) { - DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); - return(False); - } - - if(!pdb_get_nt_passwd(sam_pass)) { - DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); - return(False); - } - - smb_passwd_ptr = pdb_get_lanman_passwd(sam_pass); + /* Quit if the account was disabled. */ + if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) { + DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); + return(False); + } + + if(!pdb_get_nt_passwd(sampass)) { + DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); + return(False); + } + + smb_passwd_ptr = pdb_get_lanman_passwd(sampass); } /* @@ -459,18 +440,18 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - p->pipe_user.uid = pdb_get_uid(sam_pass); - p->pipe_user.gid = pdb_get_gid(sam_pass); + + p->pipe_user.uid = pdb_get_uid(sampass); + p->pipe_user.gid = pdb_get_uid(sampass); /* Set up pipe user group membership. */ initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); /* Create an NT_USER_TOKEN struct for this user. */ - p->pipe_user.nt_user_token = - create_nt_token(p->pipe_user.uid,p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, - guest_user); + p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, + p->pipe_user.ngroups, p->pipe_user.groups, + guest_user); p->ntlmssp_auth_validated = True; return True; @@ -1148,7 +1129,9 @@ BOOL api_pipe_request(pipes_struct *p) if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && api_fd_commands[i].fn != NULL) { DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); + set_current_rpc_talloc(p->mem_ctx); ret = api_fd_commands[i].fn(p); + set_current_rpc_talloc(NULL); } } @@ -1222,7 +1205,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n")); if (data) { - prs_uint8s(False, "", &p->in_data.data, 0, data, + prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, data_len); free(data); } @@ -1231,5 +1214,3 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, return True; } - -#undef OLD_NTDOMAIN -- cgit From 0ef2179d23a2f9826e17c2b858fd8f2a9634b332 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Mar 2001 01:44:05 +0000 Subject: Fixed reading of strings from big-endian RPC clients. Jeremy. (This used to be commit e7ecb9410ff2e4fcd33bca9f82e14c060590942a) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index bc5b2ab473..16243043d4 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -296,9 +296,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm */ if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { - fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); - fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); - fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); + fstrcpy(user_name, rpc_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2, p->endian)); + fstrcpy(domain, rpc_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2, p->endian)); + fstrcpy(wks, rpc_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2, p->endian)); } else { fstrcpy(user_name, ntlmssp_resp->user); fstrcpy(domain, ntlmssp_resp->domain); -- cgit From 4ab6182a0ffdbe92a01dd6533e0862aa8d0f6d83 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2001 00:49:13 +0000 Subject: AS/U on a sparc now joins and authenticates against a Samba PDC ! Jeremy. (This used to be commit 28a0bc5f5710aa732db662caa38f9da2138b5db2) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 16243043d4..bc5b2ab473 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -296,9 +296,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm */ if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { - fstrcpy(user_name, rpc_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2, p->endian)); - fstrcpy(domain, rpc_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2, p->endian)); - fstrcpy(wks, rpc_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2, p->endian)); + fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); + fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); + fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); } else { fstrcpy(user_name, ntlmssp_resp->user); fstrcpy(domain, ntlmssp_resp->domain); -- cgit From 950f1d9605179d75ab0755cecffbabbde769beb9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 7 Apr 2001 00:36:38 +0000 Subject: Added 3 params to manipulate shares. "add share command/change share command/ delete share command". Implemented "delete" - more work to come on add and change. Jeremy. (This used to be commit 2e6b1759e14456421066ee131af70a495f862f2b) --- source3/rpc_server/srv_pipe.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index bc5b2ab473..32ec81b07a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1103,6 +1103,22 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) return True; } +/**************************************************************************** + Return a user struct for a pipe user. +****************************************************************************/ + +struct current_user *get_current_user(struct current_user *user, pipes_struct *p) +{ + if (p->ntlmssp_auth_validated) { + memcpy(user, &p->pipe_user, sizeof(struct current_user)); + } else { + extern struct current_user current_user; + memcpy(user, ¤t_user, sizeof(struct current_user)); + } + + return user; +} + /**************************************************************************** Find the correct RPC function to call for this request. If the pipe is authenticated then become the correct UNIX user -- cgit From f9a15ce1a69f905e94db7650f0a4805720cd9c88 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 8 Apr 2001 20:22:39 +0000 Subject: Got "medieval on our ass" about adding the -1 to slprintf. Jeremy. (This used to be commit 94747b4639ed9b19f7d0fb896e43aa392a84989a) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 32ec81b07a..0654f24493 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1171,7 +1171,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, /* interpret the command */ DEBUG(4,("api_rpcTNP: %s op 0x%x - ", rpc_name, p->hdr_req.opnum)); - slprintf(name, sizeof(name), "in_%s", rpc_name); + slprintf(name, sizeof(name)-1, "in_%s", rpc_name); prs_dump(name, p->hdr_req.opnum, &p->in_data.data); for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { @@ -1201,7 +1201,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, return False; } - slprintf(name, sizeof(name), "out_%s", rpc_name); + slprintf(name, sizeof(name)-1, "out_%s", rpc_name); offset2 = prs_offset(&p->out_data.rdata); prs_set_offset(&p->out_data.rdata, offset1); prs_dump(name, p->hdr_req.opnum, &p->out_data.rdata); -- cgit From f35157f39293f9fa240a28642c41708b55d301c8 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 4 May 2001 15:44:27 +0000 Subject: Big cleanup of passdb and backends. I did some basic tests but I have probably broken something. Notably the password changing. So don't cry ;-) J.F. (This used to be commit a4a4c02b12f030a3b9e6225b999c90689dfc4719) --- source3/rpc_server/srv_pipe.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 0654f24493..7060979ce4 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -370,27 +370,32 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name return False; } - if(!(sampass = pdb_getsampwnam(pipe_user_name))) { + pdb_init_sam(&sampass); + + if(!pdb_getsampwnam(sampass, pipe_user_name)) { DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", pipe_user_name)); + pdb_clear_sam(sampass); unbecome_root(); return False; } unbecome_root(); - /* Quit if the account was disabled. */ - if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) { - DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); - return(False); - } + /* Quit if the account was disabled. */ + if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) { + DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); + pdb_clear_sam(sampass); + return False; + } - if(!pdb_get_nt_passwd(sampass)) { - DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); - return(False); - } + if(!pdb_get_nt_passwd(sampass)) { + DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); + pdb_clear_sam(sampass); + return False; + } - smb_passwd_ptr = pdb_get_lanman_passwd(sampass); + smb_passwd_ptr = pdb_get_lanman_passwd(sampass); } /* @@ -454,6 +459,8 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name guest_user); p->ntlmssp_auth_validated = True; + + pdb_clear_sam(sampass); return True; } -- cgit From 30c4c04c2f584857633ce7605555dcfb37a3e1af Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 7 May 2001 14:04:46 +0000 Subject: Patch from Simo: o sed 's/pdb_clear_sam/pdb_free_sam/g' o add pdb_reset_sam() o password changing should be ok now as well. (This used to be commit 96d0e7c3301ad990f6c83b9c216720cb32661fb5) --- source3/rpc_server/srv_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7060979ce4..345664a396 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -375,7 +375,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name if(!pdb_getsampwnam(sampass, pipe_user_name)) { DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", pipe_user_name)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); unbecome_root(); return False; } @@ -385,13 +385,13 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* Quit if the account was disabled. */ if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) { DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return False; } if(!pdb_get_nt_passwd(sampass)) { DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return False; } @@ -460,7 +460,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name p->ntlmssp_auth_validated = True; - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return True; } -- cgit From c912d04389e9bd38ac4e5ef8b29fae1faaf86e7b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 May 2001 01:30:21 +0000 Subject: Fix the W2KSP2 joining a Samba domain problem. Jeremy. (This used to be commit 6bbcab5e48f91a80d4ebcbd2bee38f2e0a8bff78) --- source3/rpc_server/srv_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 345664a396..5f6a1d479c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -93,7 +93,7 @@ BOOL create_next_pdu(pipes_struct *p) */ if(p->fault_state) { - setup_fault_pdu(p); + setup_fault_pdu(p, 0x1c010002); return True; } @@ -617,7 +617,7 @@ static BOOL setup_bind_nak(pipes_struct *p) Marshall a fault pdu. *******************************************************************/ -BOOL setup_fault_pdu(pipes_struct *p) +BOOL setup_fault_pdu(pipes_struct *p, uint32 status) { prs_struct outgoing_pdu; RPC_HDR fault_hdr; @@ -649,7 +649,7 @@ BOOL setup_fault_pdu(pipes_struct *p) memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); - fault_resp.status = 0x1c010002; + fault_resp.status = status; fault_resp.reserved = 0; /* @@ -1195,7 +1195,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, * and not put the pipe into fault state. JRA. */ DEBUG(4, ("unknown\n")); - setup_fault_pdu(p); + setup_fault_pdu(p, 0x1c010002); return True; } -- cgit From 87fbb7092b8f8b2f0db0f361c3d625e19de57cd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5f6a1d479c..cdf914a164 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -296,9 +296,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm */ if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { - fstrcpy(user_name, dos_unistrn2((uint16*)ntlmssp_resp->user, ntlmssp_resp->hdr_usr.str_str_len/2)); - fstrcpy(domain, dos_unistrn2((uint16*)ntlmssp_resp->domain, ntlmssp_resp->hdr_domain.str_str_len/2)); - fstrcpy(wks, dos_unistrn2((uint16*)ntlmssp_resp->wks, ntlmssp_resp->hdr_wks.str_str_len/2)); + rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 ); + rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0); + rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0); } else { fstrcpy(user_name, ntlmssp_resp->user); fstrcpy(domain, ntlmssp_resp->domain); -- cgit From 5b8d230e39cedda6117cf8528065cbab45bdd835 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Jul 2001 14:10:30 +0000 Subject: This removes unused paramaters from various authtication functions, and should not change behaviour. This should make my later diffs smaller, where I actualy start cleaning up this mess... Andrew Bartlett (This used to be commit 04f090c224bb7ac3b53c430a591fce1fc939a81c) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index cdf914a164..cd17de77f3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -363,7 +363,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm become_root(); if(!(p->ntlmssp_auth_validated = pass_check_smb(pipe_user_name, domain, - (uchar*)p->challenge, lm_owf, nt_owf, NULL))) { + (uchar*)p->challenge, lm_owf, nt_owf))) { DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); unbecome_root(); -- cgit From 986372901e85a79343ba32f590a4a3e7658d2565 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Aug 2001 13:09:23 +0000 Subject: This is my 'Authentication Rewrite' version 1.01, mostly as submitted to samba-technical a few weeks ago. The idea here is to standardize the checking of user names and passwords, thereby ensuring that all authtentications pass the same standards. The interface currently implemented in as nt_status = check_password(user_info, server_info) where user_info contains (mostly) the authentication data, and server_info contains things like the user-id they got, and their resolved user name. The current ugliness with the way the structures are created will be killed the next revision, when they will be created and malloced by creator functions. This patch also includes the first implementation of NTLMv2 in HEAD, but which needs some more testing. We also add a hack to allow plaintext passwords to be compared with smbpasswd, not the system password database. Finally, this patch probably reintroduces the PAM accounts bug we had in 2.2.0, I'll fix that once this hits the tree. (I've just finished testing it on a wide variety of platforms, so I want to get this patch in). (This used to be commit b30b6202f31d339b48d51c0d38174cafd1cfcd42) --- source3/rpc_server/srv_pipe.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index cd17de77f3..277cd13522 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -263,7 +263,9 @@ BOOL create_next_pdu(pipes_struct *p) static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp) { uchar lm_owf[24]; - uchar nt_owf[24]; + uchar nt_owf[128]; + int nt_pw_len; + int lm_pw_len; fstring user_name; fstring pipe_user_name; fstring domain; @@ -307,13 +309,16 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks)); + nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len); + lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len); + memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf)); - memcpy(nt_owf, ntlmssp_resp->nt_resp, sizeof(nt_owf)); + memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len); #ifdef DEBUG_PASSWORD DEBUG(100,("lm, nt owfs, chal\n")); dump_data(100, (char *)lm_owf, sizeof(lm_owf)); - dump_data(100, (char *)nt_owf, sizeof(nt_owf)); + dump_data(100, (char *)nt_owf, nt_pw_len); dump_data(100, (char *)p->challenge, 8); #endif @@ -362,8 +367,11 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm become_root(); - if(!(p->ntlmssp_auth_validated = pass_check_smb(pipe_user_name, domain, - (uchar*)p->challenge, lm_owf, nt_owf))) { + if(!(p->ntlmssp_auth_validated = + pass_check_smb_with_chal(pipe_user_name, domain, + (uchar*)p->challenge, + lm_owf, lm_pw_len, + nt_owf, nt_pw_len) == NT_STATUS_NOPROBLEMO)) { DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); unbecome_root(); -- cgit From f8d3cac8af0185eca2995e524c62f064ab9b4017 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 9 Aug 2001 15:53:49 +0000 Subject: a few cleanups while mergeing the passdb code into 2.2 (This used to be commit ef01739708479c43f529c646dd136ee5670b08f9) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 277cd13522..4d4d058fba 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -455,7 +455,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name */ p->pipe_user.uid = pdb_get_uid(sampass); - p->pipe_user.gid = pdb_get_uid(sampass); + p->pipe_user.gid = pdb_get_gid(sampass); /* Set up pipe user group membership. */ initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); -- cgit From b031af348c7dcc8c74bf49945211c466b8eca079 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 19:46:22 +0000 Subject: converted another bunch of stuff to NTSTATUS (This used to be commit 1d36250e338ae0ff9fbbf86019809205dd97d05e) --- source3/rpc_server/srv_pipe.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4d4d058fba..60250c903f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -93,7 +93,7 @@ BOOL create_next_pdu(pipes_struct *p) */ if(p->fault_state) { - setup_fault_pdu(p, 0x1c010002); + setup_fault_pdu(p, NT_STATUS(0x1c010002)); return True; } @@ -367,11 +367,12 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm become_root(); - if(!(p->ntlmssp_auth_validated = - pass_check_smb_with_chal(pipe_user_name, domain, - (uchar*)p->challenge, - lm_owf, lm_pw_len, - nt_owf, nt_pw_len) == NT_STATUS_NOPROBLEMO)) { + p->ntlmssp_auth_validated = + NT_STATUS_IS_OK(pass_check_smb_with_chal(pipe_user_name, domain, + (uchar*)p->challenge, + lm_owf, lm_pw_len, + nt_owf, nt_pw_len)); + if (!p->ntlmssp_auth_validated) { DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); unbecome_root(); @@ -625,7 +626,7 @@ static BOOL setup_bind_nak(pipes_struct *p) Marshall a fault pdu. *******************************************************************/ -BOOL setup_fault_pdu(pipes_struct *p, uint32 status) +BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status) { prs_struct outgoing_pdu; RPC_HDR fault_hdr; @@ -1203,7 +1204,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, * and not put the pipe into fault state. JRA. */ DEBUG(4, ("unknown\n")); - setup_fault_pdu(p, 0x1c010002); + setup_fault_pdu(p, NT_STATUS(0x1c010002)); return True; } -- cgit From 39d7983a470cc3470dd7126de35697d965817cb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 12 Sep 2001 03:08:51 +0000 Subject: - enable MSDFS by default, there seems no reason not to have it enabled by default in Samba 3.x - got rid of some unused parameters in Makefile.in - declare DEBUGLEVEL in debug.h rather than in each file (This used to be commit b8651acb9c0d7248a6a2e82c33b1e43633fd83fd) --- source3/rpc_server/srv_pipe.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 60250c903f..3570969efc 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -493,9 +493,7 @@ static struct api_cmd api_fd_commands[] = { "NETLOGON", "lsass", api_netlog_rpc }, { "winreg", "winreg", api_reg_rpc }, { "spoolss", "spoolss", api_spoolss_rpc }, -#ifdef WITH_MSDFS { "netdfs", "netdfs" , api_netdfs_rpc }, -#endif { NULL, NULL, NULL } }; -- cgit From b800a36b1c81fb37ca963acdc49978ff065fb0d7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 12 Sep 2001 06:39:50 +0000 Subject: Some patches to authentication: - the usersupplied_info now contains a smb_username (as it comes across on the wire) and a unix_username (after being passed through mapping functions) - when doing security={server,domain} use the smb_username, otherwise use the unix_username (This used to be commit d34fd8ec0716127c7a68eeb8e77d1ae8cc07b547) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3570969efc..4a09410e81 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -368,7 +368,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm become_root(); p->ntlmssp_auth_validated = - NT_STATUS_IS_OK(pass_check_smb_with_chal(pipe_user_name, domain, + NT_STATUS_IS_OK(pass_check_smb_with_chal(pipe_user_name, NULL, domain, (uchar*)p->challenge, lm_owf, lm_pw_len, nt_owf, nt_pw_len)); -- cgit From dec3cbcaf097a3d6fab9359e001279447a5f4def Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 Sep 2001 06:35:35 +0000 Subject: Fix up workstaion and kickoff time checks, moved to auth_smbpasswd.c where they can have general effect. Fixed up workstaion support in the rest of samba, so that we can do these checks. Pass through the workstation for cli_net_logon(), if supplied. (This used to be commit 7f04a139b2ee34b4c282590509cdf21395815a7a) --- source3/rpc_server/srv_pipe.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4a09410e81..8629592c4c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -302,6 +302,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0); rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0); } else { + /* What charset are these meant to be in? */ fstrcpy(user_name, ntlmssp_resp->user); fstrcpy(domain, ntlmssp_resp->domain); fstrcpy(wks, ntlmssp_resp->wks); @@ -328,24 +329,24 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) - { + { guest_user = True; - - fstrcpy(pipe_user_name, lp_guestaccount(-1)); + + fstrcpy(pipe_user_name, lp_guestaccount(-1)); DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", pipe_user_name)); smb_passwd_ptr = null_smb_passwd; - + } else { /* * Pass the user through the NT -> unix user mapping * function. */ - + fstrcpy(pipe_user_name, user_name); (void)map_username(pipe_user_name); - + /* * Do the length checking only if user is not NULL. */ @@ -368,7 +369,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm become_root(); p->ntlmssp_auth_validated = - NT_STATUS_IS_OK(pass_check_smb_with_chal(pipe_user_name, NULL, domain, + NT_STATUS_IS_OK(pass_check_smb_with_chal(pipe_user_name, NULL, + domain, wks, (uchar*)p->challenge, lm_owf, lm_pw_len, nt_owf, nt_pw_len)); @@ -391,13 +393,6 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name unbecome_root(); - /* Quit if the account was disabled. */ - if((pdb_get_acct_ctrl(sampass) & ACB_DISABLED) || !pdb_get_lanman_passwd(sampass)) { - DEBUG(1,("Account for user '%s' was disabled.\n", pipe_user_name)); - pdb_free_sam(sampass); - return False; - } - if(!pdb_get_nt_passwd(sampass)) { DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); pdb_free_sam(sampass); -- cgit From 87945989c0383bd012be7ab8bc5920b6d03fa105 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 10:26:23 +0000 Subject: move to SAFE_FREE() (This used to be commit 5ceecc7bef71b455ba7c4efd9928e2433dccc961) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 8629592c4c..a352cd5eb6 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -285,7 +285,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm /* Set up for non-authenticated user. */ delete_nt_token(&p->pipe_user.nt_user_token); p->pipe_user.ngroups = 0; - safe_free( p->pipe_user.groups); + SAFE_FREE( p->pipe_user.groups); /* * Setup an empty password for a guest user. @@ -1232,7 +1232,7 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, if (data) { prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, data_len); - free(data); + SAFE_FREE(data); } } -- cgit From 80ad52d5c2c389ae8983f57b34a03d8d2d2ddd88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Sep 2001 13:22:22 +0000 Subject: fixed character set for user name pull (This used to be commit 374f76fa2d5dcd036943c3f968a94f097a971ac7) --- source3/rpc_server/srv_pipe.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a352cd5eb6..b3f590a177 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -302,10 +302,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0); rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0); } else { - /* What charset are these meant to be in? */ - fstrcpy(user_name, ntlmssp_resp->user); - fstrcpy(domain, ntlmssp_resp->domain); - fstrcpy(wks, ntlmssp_resp->wks); + pull_ascii_fstring(user_name, ntlmssp_resp->user); + pull_ascii_fstring(domain, ntlmssp_resp->domain); + pull_ascii_fstring(wks, ntlmssp_resp->wks); } DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks)); -- cgit From 81697d5ebe33ad95dedfc376118fcdf0367cf052 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Sep 2001 13:08:26 +0000 Subject: Fix up a number of intertwined issues: The big one is a global change to allow us to NULLify the free'ed pointer to a former passdb object. This was done to allow idra's SAFE_FREE() macro to do its magic, and to satisfy the input test in pdb_init_sam() for a NULL pointer to start with. This NULL pointer test was what was breaking the adding of accounts up until now, and this code has been reworked to avoid duplicating work - I hope this will avoid a similar mess-up in future. Finally, I fixed a few nasty bugs where the pdb_ fuctions's return codes were being ignored. Some of these functions malloc() and are permitted to fail. Also, this caught a nasty bug where pdb_set_lanman_password(sam, NULL) acheived precisely didilly-squat, just returning False. Now that we check the returns this bug was spotted. This could allow different LM and NT passwords. - the pdbedit code needs to start checking these too, but I havn't had a chance to fix it. I have also fixed up where some of the password changing code was using the pdb_set functions to store *internal* data. I assume this is from a previous lot of mass conversion work... Most likally (and going on past experience) I have missed somthing, probably in the LanMan password change code which I havn't yet been able to test, but this lot is in much better shape than it was before. If all this is too much to swallow (particularly for 2.2.2) then just adding a sam_pass = NULL to the particular line of passdb.c should do the trick for the ovbious bug. Andrew Bartlett (This used to be commit 762c8758a7869809d89b4da9c2a5249678942930) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index b3f590a177..00acb93cf3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -385,7 +385,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name if(!pdb_getsampwnam(sampass, pipe_user_name)) { DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", pipe_user_name)); - pdb_free_sam(sampass); + pdb_free_sam(&sampass); unbecome_root(); return False; } @@ -394,7 +394,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name if(!pdb_get_nt_passwd(sampass)) { DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); - pdb_free_sam(sampass); + pdb_free_sam(&sampass); return False; } @@ -463,7 +463,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name p->ntlmssp_auth_validated = True; - pdb_free_sam(sampass); + pdb_free_sam(&sampass); return True; } -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/rpc_server/srv_pipe.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 00acb93cf3..2957d7cc95 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -40,8 +40,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) { unsigned char *hash = p->ntlmssp_hash; -- cgit From c416ff851b4ecc7a44aee9d00d07dd481d8ae2a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2001 20:15:12 +0000 Subject: Merge the become_XXX -> change_to_XXX fixes from 2.2.2 to HEAD. Ensure make_conection() can only be called as root. Jeremy. (This used to be commit 8d23a7441b4687458ee021bfe8880558506eddba) --- source3/rpc_server/srv_pipe.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 2957d7cc95..7079cc2ca1 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1135,7 +1135,6 @@ BOOL api_pipe_request(pipes_struct *p) { int i = 0; BOOL ret = False; - BOOL changed_user_id = False; if (p->ntlmssp_auth_validated) { @@ -1143,8 +1142,6 @@ BOOL api_pipe_request(pipes_struct *p) prs_mem_free(&p->out_data.rdata); return False; } - - changed_user_id = True; } for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { @@ -1157,8 +1154,8 @@ BOOL api_pipe_request(pipes_struct *p) } } - if(changed_user_id) - unbecome_authenticated_pipe_user(p); + if(p->ntlmssp_auth_validated) + unbecome_authenticated_pipe_user(); return ret; } -- cgit From d9d7f023d8d11943ca0375e1573e6ec9921889bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Oct 2001 07:35:11 +0000 Subject: This commit is number 4 of 4. In particular this commit focuses on: Actually adding the 'const' to the passdb interface, and the flow-on changes. Also kill off the 'disp_info' stuff, as its no longer used. While these changes have been mildly tested, and are pretty small, any assistance in this is appreciated. ---- These changes introduces a large dose of 'const' to the Samba tree. There are a number of good reasons to do this: - I want to allow the SAM_ACCOUNT structure to move from wasteful pstrings and fstrings to allocated strings. We can't do that if people are modifying these outputs, as they may well make assumptions about getting pstrings and fstrings - I want --with-pam_smbpass to compile with a slightly sane volume of warnings, currently its pretty bad, even in 2.2 where is compiles at all. - Tridge assures me that he no longer opposes 'const religion' based on the ability to #define const the problem away. - Changed Get_Pwnam(x,y) into two variants (so that the const parameter can work correctly): - Get_Pwnam(const x) and Get_Pwnam_Modify(x). - Reworked smbd/chgpasswd.c to work with these mods, passing around a 'struct passwd' rather than the modified username --- This finishes this line of commits off, your tree should now compile again :-) Andrew Bartlett (This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7079cc2ca1..6f3c050519 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -271,7 +271,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm BOOL guest_user = False; SAM_ACCOUNT *sampass = NULL; uchar null_smb_passwd[16]; - uchar *smb_passwd_ptr = NULL; + const uchar *smb_passwd_ptr = NULL; DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); -- cgit From 60f0627afb167faad57385d44f0b587186a7ac2b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 10:46:25 +0000 Subject: This is a farily large patch (3300 lines) and reworks most of the AuthRewrite code. In particular this assists tpot in some of his work, becouse it provides the connection between the authenticaion and the vuid generation. Major Changes: - Fully malloc'ed structures. - Massive rework of the code so that all structures are made and destroyed using malloc and free, rather than hanging around on the stack. - SAM_ACCOUNT unix uids and gids are now pointers to the same, to allow them to be declared 'invalid' without the chance that people might get ROOT by default. - kill off some of the "DOMAIN\user" lookups. These can be readded at a more appropriate place (probably domain_client_validate.c) in the future. They don't belong in session setups. - Massive introduction of DATA_BLOB structures, particularly for passwords. - Use NTLMSSP flags to tell the backend what its getting, rather than magic lenghths. - Fix winbind back up again, but tpot is redoing this soon anyway. - Abstract much of the work in srv_netlog_nt back into auth helper functions. This is a LARGE change, and any assistance is testing it is appriciated. Domain logons are still broken (as far as I can tell) but other functionality seems intact. Needs testing with a wide variety of MS clients. Andrew Bartlett (This used to be commit f70fb819b2f57bd57232b51808345e2319d52f6c) --- source3/rpc_server/srv_pipe.c | 76 ++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 41 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 6f3c050519..21de4d3d2b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -269,10 +269,16 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm fstring domain; fstring wks; BOOL guest_user = False; - SAM_ACCOUNT *sampass = NULL; uchar null_smb_passwd[16]; + const uchar *smb_passwd_ptr = NULL; + auth_usersupplied_info *user_info; + auth_serversupplied_info *server_info; + + uid_t *puid; + uid_t *pgid; + DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); memset(p->user_name, '\0', sizeof(p->user_name)); @@ -336,14 +342,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm } else { - /* - * Pass the user through the NT -> unix user mapping - * function. - */ - - fstrcpy(pipe_user_name, user_name); - (void)map_username(pipe_user_name); - /* * Do the length checking only if user is not NULL. */ @@ -362,41 +360,28 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm } if(!guest_user) { + NTSTATUS nt_status; - become_root(); - - p->ntlmssp_auth_validated = - NT_STATUS_IS_OK(pass_check_smb_with_chal(pipe_user_name, NULL, - domain, wks, - (uchar*)p->challenge, - lm_owf, lm_pw_len, - nt_owf, nt_pw_len)); - if (!p->ntlmssp_auth_validated) { - DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ -failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); - unbecome_root(); + if (!make_user_info_netlogon_network(&user_info, + user_name, domain, wks, (uchar*)p->challenge, + lm_owf, lm_pw_len, + nt_owf, nt_pw_len)) { + DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n")); return False; } - pdb_init_sam(&sampass); - - if(!pdb_getsampwnam(sampass, pipe_user_name)) { - DEBUG(1,("api_pipe_ntlmssp_verify: Cannot find user %s in smb passwd database.\n", - pipe_user_name)); - pdb_free_sam(&sampass); - unbecome_root(); - return False; - } + nt_status = check_password(user_info, &server_info); + + free_user_info(&user_info); - unbecome_root(); + p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); - if(!pdb_get_nt_passwd(sampass)) { - DEBUG(1,("Account for user '%s' has no NT password hash.\n", pipe_user_name)); - pdb_free_sam(&sampass); + if (!p->ntlmssp_auth_validated) { + DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ +failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); + free_server_info(&server_info); return False; - } - - smb_passwd_ptr = pdb_get_lanman_passwd(sampass); + } } /* @@ -405,7 +390,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name { uchar p24[24]; - NTLMSSPOWFencrypt(smb_passwd_ptr, lm_owf, p24); + NTLMSSPOWFencrypt(server_info->first_8_lm_hash, lm_owf, p24); { unsigned char j = 0; int ind; @@ -447,8 +432,17 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - p->pipe_user.uid = pdb_get_uid(sampass); - p->pipe_user.gid = pdb_get_gid(sampass); + puid = pdb_get_uid(server_info->sam_account); + pgid = pdb_get_gid(server_info->sam_account); + + if (!puid || !pgid) { + DEBUG(0,("Attempted authenticated pipe with invalid user. No uid/gid in SAM_ACCOUNT\n")); + free_server_info(&server_info); + return False; + } + + p->pipe_user.uid = *puid; + p->pipe_user.gid = *pgid; /* Set up pipe user group membership. */ initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); @@ -461,7 +455,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name p->ntlmssp_auth_validated = True; - pdb_free_sam(&sampass); + pdb_free_sam(&server_info->sam_account); return True; } -- cgit From b49b7ed1fb6b63d40f6b2aa62f6c8b787a498419 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 11:09:21 +0000 Subject: Small changes for guest authenticated pipes. (This used to be commit 813bf962ae6f29ddcaee4bc8b67d8017f04172b1) --- source3/rpc_server/srv_pipe.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 21de4d3d2b..852dd7de26 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -273,8 +273,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm const uchar *smb_passwd_ptr = NULL; - auth_usersupplied_info *user_info; - auth_serversupplied_info *server_info; + auth_usersupplied_info *user_info = NULL; + auth_serversupplied_info *server_info = NULL; uid_t *puid; uid_t *pgid; @@ -295,8 +295,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm * Setup an empty password for a guest user. */ - memset(null_smb_passwd,0,16); - /* * We always negotiate UNICODE. */ @@ -338,8 +336,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm fstrcpy(pipe_user_name, lp_guestaccount(-1)); DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", pipe_user_name)); - smb_passwd_ptr = null_smb_passwd; - } else { /* @@ -382,6 +378,9 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name free_server_info(&server_info); return False; } + } else { + /* This includes a NULLed out first_8_lm_hash */ + make_server_info_guest(&server_info); } /* @@ -450,8 +449,8 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* Create an NT_USER_TOKEN struct for this user. */ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, - guest_user); + p->pipe_user.ngroups, p->pipe_user.groups, + guest_user); p->ntlmssp_auth_validated = True; -- cgit From abaedd04f273697ab297a0cbbac743f85ea95836 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 11:10:29 +0000 Subject: ... and clean up the unused variables. (This used to be commit e0b56a31480906b39f37761eed20d3cad0d53973) --- source3/rpc_server/srv_pipe.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 852dd7de26..76f4a1ed1e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -269,10 +269,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm fstring domain; fstring wks; BOOL guest_user = False; - uchar null_smb_passwd[16]; - const uchar *smb_passwd_ptr = NULL; - auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; -- cgit From f8e2baf39eb864481dd48f61404136b325cd73c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2001 23:34:24 +0000 Subject: Added NT_USER_TOKEN into server_info to fix extra groups problem. Got "medieval on our ass" about const warnings (as many as I could :-). Jeremy. (This used to be commit ee5e7ca547eff016818ba5c43b8ea0c9fa69b808) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 76f4a1ed1e..dfe03c2eb3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -447,7 +447,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* Create an NT_USER_TOKEN struct for this user. */ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, p->pipe_user.ngroups, p->pipe_user.groups, - guest_user); + guest_user, NULL); p->ntlmssp_auth_validated = True; -- cgit From 5f5661d21717ee7eea27d4776180dd88635ad8d4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 Nov 2001 01:14:15 +0000 Subject: Fix up authenticated pipes in line with vuser changes. This ensures that global groups obtained via a domain logon are respected in the attached NT_USER_TOKEN. This functionality is only available in HEAD, becosue of the way authenticaion has been abstracted. Both vuid logins and authenticated pipes need to use the same code for this in future. Can sombody with the correct facilties check this please?\ Thanks, Andrew Bartlett (This used to be commit caae69fcd096f20aa4c6879b95ec2c275afea041) --- source3/rpc_server/srv_pipe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index dfe03c2eb3..a718516baa 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -444,10 +444,13 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); + if (server_info->ptok) + add_supplementary_nt_login_groups(&p->pipe_user.ngroups, &p->pipe_user.groups, &server_info->ptok); + /* Create an NT_USER_TOKEN struct for this user. */ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, p->pipe_user.ngroups, p->pipe_user.groups, - guest_user, NULL); + guest_user, server_info->ptok); p->ntlmssp_auth_validated = True; -- cgit From 55dfb66079333acd8e0aee91c0ee90d0a413a8e6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Nov 2001 22:19:01 +0000 Subject: Change to guest logon code. This changes the way we process guest logons - we now treat them as normal logons, but set the 'guest' flag. In particular this is needed becouse Win2k will do an NTLMSSP login with username "", therefore missing our previous guest connection code - this is getting a pain to do as a special case all over the shop. Tridge: We don't seem to be setting a guest bit for NTLMSSP, in either the anonymous or authenticated case, can you take a look at this? Also some cleanups in the check_password() code that should make some of the debugs clearer. Various other minor cleanups: - change the session code to just take a vuser, rather than having to do a vuid lookup on vuser.vuid - Change some of the global_client_caps linking - Better debug in authorise_login(): show the vuid. Andrew Bartlett (This used to be commit 62f4e4bd0aef9ade653b3f8d575d2864c166ab4d) --- source3/rpc_server/srv_pipe.c | 51 +++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a718516baa..e3969f7ea8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -268,7 +268,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm fstring pipe_user_name; fstring domain; fstring wks; - BOOL guest_user = False; + + NTSTATUS nt_status; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; @@ -328,8 +329,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm if((strlen(user_name) == 0) && (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) { - guest_user = True; - + fstrcpy(pipe_user_name, lp_guestaccount(-1)); DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", pipe_user_name)); @@ -352,32 +352,25 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm } - if(!guest_user) { - NTSTATUS nt_status; - - if (!make_user_info_netlogon_network(&user_info, - user_name, domain, wks, (uchar*)p->challenge, - lm_owf, lm_pw_len, - nt_owf, nt_pw_len)) { - DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n")); - return False; - } - - nt_status = check_password(user_info, &server_info); - - free_user_info(&user_info); - - p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); - - if (!p->ntlmssp_auth_validated) { - DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ + if (!make_user_info_netlogon_network(&user_info, + user_name, domain, wks, (uchar*)p->challenge, + lm_owf, lm_pw_len, + nt_owf, nt_pw_len)) { + DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n")); + return False; + } + + nt_status = check_password(user_info, &server_info); + + free_user_info(&user_info); + + p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); + + if (!p->ntlmssp_auth_validated) { + DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); - free_server_info(&server_info); - return False; - } - } else { - /* This includes a NULLed out first_8_lm_hash */ - make_server_info_guest(&server_info); + free_server_info(&server_info); + return False; } /* @@ -450,7 +443,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name /* Create an NT_USER_TOKEN struct for this user. */ p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, p->pipe_user.ngroups, p->pipe_user.groups, - guest_user, server_info->ptok); + server_info->guest, server_info->ptok); p->ntlmssp_auth_validated = True; -- cgit From 395aa946cd4fb9d5e07dd2fee418045a8064dfab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Nov 2001 11:16:06 +0000 Subject: This change updates lp_guestaccount() to be a *global* paramater, rather than per-share. I beleive that almost all the things that this could have done on a per-share basis can be done with other tools, like 'force user'. Almost all the user's of this paramater used it as a global anyway... While this is one step at a time, I hope it will allow me to considerably simplfy the make_connection() code, particularly for the user-level security case. This already removes an absolute truckload of extra attempted password lookups on the guest account. Andrew Bartlett (This used to be commit 8e708332eded210c1d1fe0cebca3c9c19f054b71) --- source3/rpc_server/srv_pipe.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e3969f7ea8..b9c40e719b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -265,7 +265,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm int nt_pw_len; int lm_pw_len; fstring user_name; - fstring pipe_user_name; fstring domain; fstring wks; @@ -326,14 +325,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm * Allow guest access. Patch from Shirish Kalele . */ - if((strlen(user_name) == 0) && - (ntlmssp_resp->hdr_nt_resp.str_str_len==0)) - { - - fstrcpy(pipe_user_name, lp_guestaccount(-1)); - DEBUG(100,("Null user in NTLMSSP verification. Using guest = %s\n", pipe_user_name)); - - } else { + if (*user_name) { /* * Do the length checking only if user is not NULL. @@ -367,8 +359,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); if (!p->ntlmssp_auth_validated) { - DEBUG(1,("api_pipe_ntlmssp_verify: User %s\\%s from machine %s \ -failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name )); + DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \ +failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); free_server_info(&server_info); return False; } @@ -413,7 +405,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name } fstrcpy(p->user_name, user_name); - fstrcpy(p->pipe_user_name, pipe_user_name); + fstrcpy(p->pipe_user_name, pdb_get_username(server_info->sam_account)); fstrcpy(p->domain, domain); fstrcpy(p->wks, wks); @@ -434,7 +426,7 @@ failed authentication on named pipe %s.\n", domain, pipe_user_name, wks, p->name p->pipe_user.gid = *pgid; /* Set up pipe user group membership. */ - initialise_groups(pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); + initialise_groups(p->pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); if (server_info->ptok) -- cgit From d0a2faf78d316fec200497f5f7997df4c477a1e1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 24 Nov 2001 12:12:38 +0000 Subject: This is another rather major change to the samba authenticaion subystem. The particular aim is to modularized the interface - so that we can have arbitrary password back-ends. This code adds one such back-end, a 'winbind' module to authenticate against the winbind_auth_crap functionality. While fully-functional this code is mainly useful as a demonstration, because we don't get back the info3 as we would for direct ntdomain authentication. This commit introduced the new 'auth methods' parameter, in the spirit of the 'auth order' discussed on the lists. It is renamed because not all the methods may be consulted, even if previous methods fail - they may not have a suitable challenge for example. Also, we have a 'local' authentication method, for old-style 'unix if plaintext, sam if encrypted' authentication and a 'guest' module to handle guest logins in a single place. While this current design is not ideal, I feel that it does provide a better infrastructure than the current design, and can be built upon. The following parameters have changed: - use rhosts = This has been replaced by the 'rhosts' authentication method, and can be specified like 'auth methods = guest rhosts' - hosts equiv = This needs both this parameter and an 'auth methods' entry to be effective. (auth methods = guest hostsequiv ....) - plaintext to smbpasswd = This is replaced by specifying 'sam' rather than 'local' in the auth methods. The security = parameter is unchanged, and now provides defaults for the 'auth methods' parameter. The available auth methods are: guest rhosts hostsequiv sam (passdb direct hash access) unix (PAM, crypt() etc) local (the combination of the above, based on encryption) smbserver (old security=server) ntdomain (old security=domain) winbind (use winbind to cache DC connections) Assistance in testing, or the production of new and interesting authentication modules is always appreciated. Andrew Bartlett (This used to be commit 8d31eae52a9757739711dbb82035a4dfe6b40c99) --- source3/rpc_server/srv_pipe.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index b9c40e719b..4b3140b350 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -271,6 +271,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm NTSTATUS nt_status; auth_usersupplied_info *user_info = NULL; + auth_authsupplied_info *auth_info = NULL; auth_serversupplied_info *server_info = NULL; uid_t *puid; @@ -343,17 +344,20 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm return False; } + + make_auth_info_fixed(&auth_info, (uchar*)p->challenge); if (!make_user_info_netlogon_network(&user_info, - user_name, domain, wks, (uchar*)p->challenge, + user_name, domain, wks, lm_owf, lm_pw_len, nt_owf, nt_pw_len)) { DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n")); return False; } - nt_status = check_password(user_info, &server_info); + nt_status = check_password(user_info, auth_info, &server_info); + free_auth_info(&auth_info); free_user_info(&user_info); p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); -- cgit From 04aff47c716a51a1039b44a81d6ff19eeaa09017 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Dec 2001 06:38:04 +0000 Subject: moving SAM_ACCOUNT to include a bit field for initialized members (such as uid and gid). This way we will be able to keep ourselves from writing out default smb.conf settings when the admin doesn't want to, That part is not done yet. Tested compiles with ldap/tdb/smbpasswd. Tested connection with smbpasswd backend. oh...and smbpasswd doesn'y automatically expire accounts after 21 days from the last password change either now. Just ifdef'd out that code in build_sam_account(). Will merge updates into 2.2 as they are necessary. jerry (This used to be commit f0d43791157d8f04a13a07d029f203ad4384d317) --- source3/rpc_server/srv_pipe.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4b3140b350..c97619c4b6 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -274,8 +274,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm auth_authsupplied_info *auth_info = NULL; auth_serversupplied_info *server_info = NULL; - uid_t *puid; - uid_t *pgid; + uid_t uid; + uid_t gid; DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); @@ -417,17 +417,17 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - puid = pdb_get_uid(server_info->sam_account); - pgid = pdb_get_gid(server_info->sam_account); - - if (!puid || !pgid) { + if (!IS_SAM_UNIX_USER(server_info->sam_account)) { DEBUG(0,("Attempted authenticated pipe with invalid user. No uid/gid in SAM_ACCOUNT\n")); free_server_info(&server_info); return False; } - p->pipe_user.uid = *puid; - p->pipe_user.gid = *pgid; + uid = pdb_get_uid(server_info->sam_account); + gid = pdb_get_gid(server_info->sam_account); + + p->pipe_user.uid = uid; + p->pipe_user.gid = gid; /* Set up pipe user group membership. */ initialise_groups(p->pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); -- cgit From 2e28f8ff0e3bb50ac5b2742c7678c39cb65bcd95 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jan 2002 04:55:41 +0000 Subject: I've decided to move the auth code around a bit more... The auth_authsupplied_info typedef is now just a plain struct - auth_context, but it has been modified to contain the function pointers to the rest of the auth subsystem's components. (Who needs non-static functions anyway?) In working all this mess out, I fixed a number of memory leaks and moved the entire auth subsystem over to talloc(). Note that the TALLOC_CTX attached to the auth_context can be rather long-lived, it is provided for things that are intended to live as long. (The global_negprot_auth_context lasts the whole life of the smbd). I've also adjusted a few things in auth_domain.c, mainly passing the domain as a paramater to a few functions instead of looking up lp_workgroup(). I'm hopign to make this entire thing a bit more trusted domains (as PDC) freindly in the near future. Other than that, I moved a bit of the code around, hence the rather messy diff. Andrew Bartlett (This used to be commit 12f5515f556cf39fea98134fe3e2ac4540501048) --- source3/rpc_server/srv_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index c97619c4b6..36ca7e0686 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -270,8 +270,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm NTSTATUS nt_status; + struct auth_context *auth_context = NULL; auth_usersupplied_info *user_info = NULL; - auth_authsupplied_info *auth_info = NULL; auth_serversupplied_info *server_info = NULL; uid_t uid; @@ -345,7 +345,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm } - make_auth_info_fixed(&auth_info, (uchar*)p->challenge); + make_auth_context_fixed(&auth_context, (uchar*)p->challenge); if (!make_user_info_netlogon_network(&user_info, user_name, domain, wks, @@ -355,9 +355,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm return False; } - nt_status = check_password(user_info, auth_info, &server_info); + nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); - free_auth_info(&auth_info); + auth_context->free(&auth_context); free_user_info(&user_info); p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); -- cgit From f5bc0e92a66b418b2bd8f3669a9642b4d46bc8d1 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Wed, 9 Jan 2002 07:52:51 +0000 Subject: Better explanation message for dmalloc. Also more insertion of parenthesis to handle struct members called 'free'. You can now get useful dmalloc output, as long as it is compatible with your C library. On RH7.1 it looks like you have to rebuild dmalloc to allow free(0) by default, because something in libcrypt does that. (sigh) (This used to be commit 391cbb690196537c8b6292b42c2e27408cc7e249) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 36ca7e0686..a38b86f826 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -357,7 +357,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); - auth_context->free(&auth_context); + (auth_context->free)(&auth_context); free_user_info(&user_info); p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); -- cgit From 32101155d4a0c80faf392f56a6baa7b91847dd99 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jan 2002 13:26:31 +0000 Subject: Kill off another ugly wart from the side of the passdb subsystem. This time its the pdb_getsampwuid() function - which was only being used by the SAMR rpc subsystem to gain a 'user session key'. This 'user session key' is actually generated at login time, and the other changes here simply move that data around. This also means that (when I check some details) we will be able to use the user session key, even when we are not actually the DC, becouse its one of the components of the info3 struct returned on logon. Andrew Bartlett (This used to be commit 799ac01fe08a338e4e94289f5d6767ebf905c1fa) --- source3/rpc_server/srv_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a38b86f826..2630729281 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -423,6 +423,8 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); return False; } + memcpy(p->session_key, server_info->session_key, sizeof(p->session_key)); + uid = pdb_get_uid(server_info->sam_account); gid = pdb_get_gid(server_info->sam_account); -- cgit From 565b9cc1572e284ed5d9324f232249a32b76f164 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Jan 2002 05:28:37 +0000 Subject: Return correct RPC fault PDU on bad handle incoming. Jeremy. (This used to be commit 0db93d8752197e213f0974edae53e2dafdd77b51) --- source3/rpc_server/srv_pipe.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 2630729281..45e5567d1b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1188,6 +1188,13 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, return False; } + if (p->bad_handle_fault_state) { + DEBUG(4,("api_rpcTNP: bad handle fault return.\n")); + p->bad_handle_fault_state = False; + setup_fault_pdu(p, NT_STATUS(0x1C00001A)); + return True; + } + slprintf(name, sizeof(name)-1, "out_%s", rpc_name); offset2 = prs_offset(&p->out_data.rdata); prs_set_offset(&p->out_data.rdata, offset1); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/rpc_server/srv_pipe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 45e5567d1b..70574b4cdd 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,6 +1,5 @@ /* - * Unix SMB/Netbios implementation. - * Version 1.9. + * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1998 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/rpc_server/srv_pipe.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 70574b4cdd..b7be415abc 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -39,6 +39,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_RPC_SRV + static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) { unsigned char *hash = p->ntlmssp_hash; @@ -432,7 +435,7 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); /* Set up pipe user group membership. */ initialise_groups(p->pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); - get_current_groups( &p->pipe_user.ngroups, &p->pipe_user.groups); + get_current_groups(p->pipe_user.gid, &p->pipe_user.ngroups, &p->pipe_user.groups); if (server_info->ptok) add_supplementary_nt_login_groups(&p->pipe_user.ngroups, &p->pipe_user.groups, &server_info->ptok); @@ -1148,7 +1151,7 @@ BOOL api_pipe_request(pipes_struct *p) ********************************************************************/ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, - struct api_struct *api_rpc_cmds) + const struct api_struct *api_rpc_cmds) { int fn_num; fstring name; -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/rpc_server/srv_pipe.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index b7be415abc..1947d5514e 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -276,9 +276,6 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; - uid_t uid; - uid_t gid; - DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); memset(p->user_name, '\0', sizeof(p->user_name)); @@ -427,27 +424,30 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); memcpy(p->session_key, server_info->session_key, sizeof(p->session_key)); - uid = pdb_get_uid(server_info->sam_account); - gid = pdb_get_gid(server_info->sam_account); - - p->pipe_user.uid = uid; - p->pipe_user.gid = gid; - - /* Set up pipe user group membership. */ - initialise_groups(p->pipe_user_name, p->pipe_user.uid, p->pipe_user.gid); - get_current_groups(p->pipe_user.gid, &p->pipe_user.ngroups, &p->pipe_user.groups); + p->pipe_user.uid = pdb_get_uid(server_info->sam_account); + p->pipe_user.gid = pdb_get_gid(server_info->sam_account); + + p->pipe_user.ngroups = server_info->n_groups; + if (p->pipe_user.ngroups) { + if (!(p->pipe_user.groups = memdup(server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) { + DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); + free_server_info(&server_info); + return False; + } + } if (server_info->ptok) - add_supplementary_nt_login_groups(&p->pipe_user.ngroups, &p->pipe_user.groups, &server_info->ptok); - - /* Create an NT_USER_TOKEN struct for this user. */ - p->pipe_user.nt_user_token = create_nt_token(p->pipe_user.uid,p->pipe_user.gid, - p->pipe_user.ngroups, p->pipe_user.groups, - server_info->guest, server_info->ptok); + p->pipe_user.nt_user_token = dup_nt_token(server_info->ptok); + else { + DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); + p->pipe_user.nt_user_token = NULL; + free_server_info(&server_info); + return False; + } p->ntlmssp_auth_validated = True; - pdb_free_sam(&server_info->sam_account); + free_server_info(&server_info); return True; } -- cgit From 36ef82a52953384acedbd51f54ded9357fa8ca3e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Oct 2002 04:10:23 +0000 Subject: merge of new client side support the Win2k LSARPC UUID in rpcbind from APP_HEAD (This used to be commit 1cfd2ee433305e91e87804dd55d10e025d30a69e) --- source3/rpc_server/srv_pipe.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1947d5514e..5a935be279 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -681,26 +681,49 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, fstrcpy(pname,"\\PIPE\\"); fstrcat(pname,pipe_name); - for(i=0;pipe_names[i].client_pipe; i++) { - if(strequal(pipe_names[i].client_pipe, pname)) + +#ifndef SUPPORT_NEW_LSARPC_UUID + + /* check for the first pipe matching the name */ + + for ( i=0; pipe_names[i].client_pipe; i++ ) { + if ( strequal(pipe_names[i].client_pipe, pname) ) + break; + } +#else + /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ + + for ( i=0; pipe_names[i].client_pipe; i++ ) + { + if ( strequal(pipe_names[i].client_pipe, pname) + && (abstract->version == pipe_names[i].abstr_syntax.version) + && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) == 0) + && (transfer->version == pipe_names[i].trans_syntax.version) + && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) ) + { break; + } } +#endif if(pipe_names[i].client_pipe == NULL) return False; +#ifndef SUPPORT_NEW_LSARPC_UUID /* check the abstract interface */ - if((abstract->version != pipe_names[i].abstr_syntax.version) || - (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, - sizeof(RPC_UUID)) != 0)) + if ( (abstract->version != pipe_names[i].abstr_syntax.version) + || (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) != 0) ) + { return False; + } /* check the transfer interface */ - if((transfer->version != pipe_names[i].trans_syntax.version) || - (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, - sizeof(RPC_UUID)) != 0)) + if ( (transfer->version != pipe_names[i].trans_syntax.version) + || (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) != 0) ) + { return False; - + } +#endif return True; } -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5a935be279..8aaab43461 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -457,8 +457,8 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); struct api_cmd { - char * pipe_clnt_name; - char * pipe_srv_name; + const char * pipe_clnt_name; + const char * pipe_srv_name; BOOL (*fn) (pipes_struct *); }; @@ -1173,7 +1173,7 @@ BOOL api_pipe_request(pipes_struct *p) Calls the underlying RPC function for a named pipe. ********************************************************************/ -BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, +BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, const struct api_struct *api_rpc_cmds) { int fn_num; -- cgit From 49d3f7bc81d3ce96513128f3e504ae1228e53d68 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 14 Feb 2003 00:48:28 +0000 Subject: merge from HEAD - enable dynamic RPC modules (This used to be commit d9c485b01017594d113502f9de2248d6c120cfa3) --- source3/rpc_server/srv_pipe.c | 238 +++++++++++++++++++++++++++++++++++------- 1 file changed, 198 insertions(+), 40 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 8aaab43461..4c4b3e7af3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -3,8 +3,9 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-1998 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1997-1998. - * Copyright (C) Jeremy Allison 1999. + * Copyright (C) Paul Ashton 1997-1998, + * Copyright (C) Jeremy Allison 1999, + * Copyright (C) Anthony Liguori 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -457,24 +458,53 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); struct api_cmd { - const char * pipe_clnt_name; - const char * pipe_srv_name; - BOOL (*fn) (pipes_struct *); + const char *name; + int (*init)(void); }; static struct api_cmd api_fd_commands[] = { - { "lsarpc", "lsass", api_ntlsa_rpc }, - { "samr", "lsass", api_samr_rpc }, - { "srvsvc", "ntsvcs", api_srvsvc_rpc }, - { "wkssvc", "ntsvcs", api_wkssvc_rpc }, - { "NETLOGON", "lsass", api_netlog_rpc }, - { "winreg", "winreg", api_reg_rpc }, - { "spoolss", "spoolss", api_spoolss_rpc }, - { "netdfs", "netdfs" , api_netdfs_rpc }, - { NULL, NULL, NULL } +#ifndef RPC_LSA_DYNAMIC + { "lsarpc", rpc_lsa_init }, +#endif +#ifndef RPC_SAMR_DYNAMIC + { "samr", rpc_samr_init }, +#endif +#ifndef RPC_SVC_DYNAMIC + { "srvsvc", rpc_srv_init }, +#endif +#ifndef RPC_WKS_DYNAMIC + { "wkssvc", rpc_wks_init }, +#endif +#ifndef RPC_NETLOG_DYNAMIC + { "NETLOGON", rpc_net_init }, +#endif +#ifndef RPC_REG_DYNAMIC + { "winreg", rpc_reg_init }, +#endif +#ifndef RPC_SPOOLSS_DYNAMIC + { "spoolss", rpc_spoolss_init }, +#endif +#ifndef RPC_DFS_DYNAMIC + { "netdfs", rpc_dfs_init }, +#endif + { NULL, NULL } }; +struct rpc_table +{ + struct + { + const char *clnt; + const char *srv; + } pipe; + struct api_struct *cmds; + int n_cmds; +}; + +static struct rpc_table *rpc_lookup; +static int rpc_lookup_size; + /******************************************************************* This is the client reply to our challenge for an authenticated bind request. The challenge we sent is in p->challenge. @@ -681,6 +711,7 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, fstrcpy(pname,"\\PIPE\\"); fstrcat(pname,pipe_name); + DEBUG(3,("check_bind_req for %s\n", pname)); #ifndef SUPPORT_NEW_LSARPC_UUID @@ -727,6 +758,82 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, return True; } +/******************************************************************* + Register commands to an RPC pipe +*******************************************************************/ +int rpc_pipe_register_commands(const char *clnt, const char *srv, const struct api_struct *cmds, int size) +{ + struct rpc_table *rpc_entry; + + + /* We use a temporary variable because this call can fail and + rpc_lookup will still be valid afterwards. It could then succeed if + called again later */ + rpc_entry = realloc(rpc_lookup, + ++rpc_lookup_size*sizeof(struct rpc_table)); + if (NULL == rpc_entry) { + rpc_lookup_size--; + DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n")); + return 0; + } else { + rpc_lookup = rpc_entry; + } + + rpc_entry = rpc_lookup + (rpc_lookup_size - 1); + ZERO_STRUCTP(rpc_entry); + rpc_entry->pipe.clnt = strdup(clnt); + rpc_entry->pipe.srv = strdup(srv); + rpc_entry->cmds = realloc(rpc_entry->cmds, + (rpc_entry->n_cmds + size) * + sizeof(struct api_struct)); + memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds, + size * sizeof(struct api_struct)); + rpc_entry->n_cmds += size; + + return size; +} + +/******************************************************************* + Register commands to an RPC pipe +*******************************************************************/ +int rpc_load_module(const char *module) +{ +#ifdef HAVE_DLOPEN + void *handle; + int (*module_init)(void); + pstring full_path; + char *error; + + pstrcpy(full_path, lib_path("rpc")); + pstrcat(full_path, "/librpc_"); + pstrcat(full_path, module); + pstrcat(full_path, "."); + pstrcat(full_path, shlib_ext()); + + handle = sys_dlopen(full_path, RTLD_LAZY); + if (!handle) { + DEBUG(0, ("Could not load requested pipe %s as %s\n", + module, full_path)); + DEBUG(0, (" Error: %s\n", dlerror())); + return 0; + } + + DEBUG(3, ("Module '%s' loaded\n", full_path)); + + module_init = sys_dlsym(handle, "rpc_pipe_init"); + if ((error = sys_dlerror()) != NULL) { + DEBUG(0, ("Error trying to resolve symbol 'rpc_pipe_init' in %s: %s\n", + full_path, error)); + return 0; + } + + return module_init(); +#else + DEBUG(0,("Attempting to load a dynamic RPC pipe when dlopen isn't available\n")); + return 0; +#endif +} + /******************************************************************* Respond to a pipe bind request. *******************************************************************/ @@ -754,23 +861,40 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) * that this is a pipe name we support. */ - for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { - if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && - api_fd_commands[i].fn != NULL) { - DEBUG(3,("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", - api_fd_commands[i].pipe_clnt_name, - api_fd_commands[i].pipe_srv_name)); - fstrcpy(p->pipe_srv_name, api_fd_commands[i].pipe_srv_name); - break; - } + + for (i = 0; i < rpc_lookup_size; i++) { + if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { + DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); + fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); + break; + } } - if (api_fd_commands[i].fn == NULL) { - DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", - p->name )); - if(!setup_bind_nak(p)) - return False; - return True; + if (i == rpc_lookup_size) { + for (i = 0; api_fd_commands[i].name; i++) { + if (strequal(api_fd_commands[i].name, p->name)) { + api_fd_commands[i].init(); + break; + } + } + + if (!api_fd_commands[i].name && !rpc_load_module(p->name)) { + DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", + p->name )); + if(!setup_bind_nak(p)) + return False; + return True; + } + + for (i = 0; i < rpc_lookup_size; i++) { + if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { + DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); + fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); + break; + } + } } /* decode the bind request */ @@ -1153,14 +1277,46 @@ BOOL api_pipe_request(pipes_struct *p) } } - for (i = 0; api_fd_commands[i].pipe_clnt_name; i++) { - if (strequal(api_fd_commands[i].pipe_clnt_name, p->name) && - api_fd_commands[i].fn != NULL) { - DEBUG(3,("Doing \\PIPE\\%s\n", api_fd_commands[i].pipe_clnt_name)); - set_current_rpc_talloc(p->mem_ctx); - ret = api_fd_commands[i].fn(p); - set_current_rpc_talloc(NULL); - } + DEBUG(5, ("Requested \\PIPE\\%s\n", p->name)); + + for (i = 0; i < rpc_lookup_size; i++) { + if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { + DEBUG(3,("Doing \\PIPE\\%s\n", + rpc_lookup[i].pipe.clnt)); + set_current_rpc_talloc(p->mem_ctx); + ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt, + rpc_lookup[i].cmds, + rpc_lookup[i].n_cmds); + set_current_rpc_talloc(NULL); + break; + } + } + + + if (i == rpc_lookup_size) { + for (i = 0; api_fd_commands[i].name; i++) { + if (strequal(api_fd_commands[i].name, p->name)) { + api_fd_commands[i].init(); + break; + } + } + + if (!api_fd_commands[i].name) { + rpc_load_module(p->name); + } + + for (i = 0; i < rpc_lookup_size; i++) { + if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { + DEBUG(3,("Doing \\PIPE\\%s\n", + rpc_lookup[i].pipe.clnt)); + set_current_rpc_talloc(p->mem_ctx); + ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt, + rpc_lookup[i].cmds, + rpc_lookup[i].n_cmds); + set_current_rpc_talloc(NULL); + break; + } + } } if(p->ntlmssp_auth_validated) @@ -1174,7 +1330,7 @@ BOOL api_pipe_request(pipes_struct *p) ********************************************************************/ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, - const struct api_struct *api_rpc_cmds) + const struct api_struct *api_rpc_cmds, int n_cmds) { int fn_num; fstring name; @@ -1186,14 +1342,14 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, slprintf(name, sizeof(name)-1, "in_%s", rpc_name); prs_dump(name, p->hdr_req.opnum, &p->in_data.data); - for (fn_num = 0; api_rpc_cmds[fn_num].name; fn_num++) { + for (fn_num = 0; fn_num < n_cmds; fn_num++) { if (api_rpc_cmds[fn_num].opnum == p->hdr_req.opnum && api_rpc_cmds[fn_num].fn != NULL) { DEBUG(3,("api_rpcTNP: rpc command: %s\n", api_rpc_cmds[fn_num].name)); break; } } - if (api_rpc_cmds[fn_num].name == NULL) { + if (fn_num == n_cmds) { /* * For an unknown RPC just return a fault PDU but * return True to allow RPC's on the pipe to continue @@ -1206,6 +1362,8 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, offset1 = prs_offset(&p->out_data.rdata); + DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n", + fn_num, api_rpc_cmds[fn_num].fn)); /* do the actual command */ if(!api_rpc_cmds[fn_num].fn(p)) { DEBUG(0,("api_rpcTNP: %s: %s failed.\n", rpc_name, api_rpc_cmds[fn_num].name)); -- cgit From 8fc1f1aead6db996a6d96efdc5f81779afc9c8d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Feb 2003 22:55:46 +0000 Subject: Ensure that only parse_prs.c access internal members of the prs_struct. Needed to move to disk based i/o later. Jeremy. (This used to be commit a823fee5b41a5b6cd4ef05aa1f85f7725bd272a5) --- source3/rpc_server/srv_pipe.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4c4b3e7af3..50127005a1 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -84,8 +84,6 @@ BOOL create_next_pdu(pipes_struct *p) uint32 data_space_available; uint32 data_len_left; prs_struct outgoing_pdu; - char *data; - char *data_from; uint32 data_pos; /* @@ -187,26 +185,26 @@ BOOL create_next_pdu(pipes_struct *p) data_pos = prs_offset(&outgoing_pdu); /* Copy the data into the PDU. */ - data_from = prs_data_p(&p->out_data.rdata) + p->out_data.data_sent_length; - if(!prs_append_data(&outgoing_pdu, data_from, data_len)) { + if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) { DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len)); prs_mem_free(&outgoing_pdu); return False; } - /* - * Set data to point to where we copied the data into. - */ - - data = prs_data_p(&outgoing_pdu) + data_pos; - if (p->hdr.auth_len > 0) { uint32 crc32 = 0; + char *data; DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n", BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len)); + /* + * Set data to point to where we copied the data into. + */ + + data = prs_data_p(&outgoing_pdu) + data_pos; + if (auth_seal) { crc32 = crc32_calc_buffer(data, data_len); NTLMSSPcalc_p(p, (uchar*)data, data_len); @@ -1389,17 +1387,15 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, /* Check for buffer underflow in rpc parsing */ if ((DEBUGLEVEL >= 10) && - (p->in_data.data.data_offset != p->in_data.data.buffer_size)) { - int data_len = p->in_data.data.buffer_size - - p->in_data.data.data_offset; + (prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) { + size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data); char *data; data = malloc(data_len); DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n")); if (data) { - prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, - data_len); + prs_uint8s(False, "", &p->in_data.data, 0, (unsigned char *)data, (uint32)data_len); SAFE_FREE(data); } -- cgit From 52d1dd46d2f26e4f81a6b307e8139ed379af1920 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Mar 2003 19:56:57 +0000 Subject: Fix const warning. Jeremy. (This used to be commit dedc18212a5174b6abac60ede9828f9b726a6c2d) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 50127005a1..588d6644b1 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -800,7 +800,7 @@ int rpc_load_module(const char *module) void *handle; int (*module_init)(void); pstring full_path; - char *error; + const char *error; pstrcpy(full_path, lib_path("rpc")); pstrcat(full_path, "/librpc_"); -- cgit From b4d0f208fb936382c7b313bd94c180b5cb708cea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 6 Apr 2003 07:04:09 +0000 Subject: Merge the TNG netlogon schannel from HEAD. No more XP requiresignorseal anymore! Thanks again to Luke :-) Volker (This used to be commit 6b2b55901d66cab0c0c0c90bd0585c870be6e468) --- source3/rpc_server/srv_pipe.c | 422 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 394 insertions(+), 28 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 588d6644b1..af3f1549a0 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -43,6 +43,13 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV +/************************************************************* + HACK Alert! + We need to transfer the session key from one rpc bind to the + next. This is the way the netlogon schannel works. +**************************************************************/ +struct dcinfo last_dcinfo; + static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) { unsigned char *hash = p->ntlmssp_hash; @@ -115,6 +122,9 @@ BOOL create_next_pdu(pipes_struct *p) if(p->ntlmssp_auth_validated) data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); + if(p->netsec_auth_validated) + data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN); + /* * The amount we send is the minimum of the available * space and the amount left to send. @@ -148,6 +158,10 @@ BOOL create_next_pdu(pipes_struct *p) p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN; p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; + } else if (p->netsec_auth_validated) { + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + + RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN; + p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN; } else { p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; p->hdr.auth_len = 0; @@ -192,7 +206,7 @@ BOOL create_next_pdu(pipes_struct *p) return False; } - if (p->hdr.auth_len > 0) { + if (p->ntlmssp_auth_validated) { uint32 crc32 = 0; char *data; @@ -239,6 +253,47 @@ BOOL create_next_pdu(pipes_struct *p) } } + if (p->netsec_auth_validated) { + char *data; + RPC_HDR_AUTH auth_info; + static const uchar netsec_sig[8] = NETSEC_SIGNATURE; + static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; + + RPC_AUTH_NETSEC_CHK verf; + prs_struct rverf; + prs_struct rauth; + + uchar sign[8]; + + data = prs_data_p(&outgoing_pdu) + data_pos; + + init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, + RPC_HDR_AUTH_LEN, 1); + + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); + prs_mem_free(&outgoing_pdu); + return False; + } + + prs_init(&rverf, 0, p->mem_ctx, MARSHALL); + prs_init(&rauth, 0, p->mem_ctx, MARSHALL); + + memset(sign, 0, sizeof(sign)); + sign[3] = 0x01; + + init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, sign, nullbytes); + + if (!netsec_encode(&p->netsec_auth, &verf, data, data_len)) { + DEBUG(0,("create_next_pdu: failed encode data.\n")); + prs_mem_free(&outgoing_pdu); + return False; + } + + smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0); + p->netsec_auth.seq_num++; + } + /* * Setup the counts for this PDU. */ @@ -851,6 +906,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) enum RPC_PKT_TYPE reply_pkt_type; p->ntlmssp_auth_requested = False; + p->netsec_auth_validated = False; DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); @@ -918,39 +974,62 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) return False; } - /* - * We only support NTLMSSP_AUTH_TYPE requests. - */ + if(auth_info.auth_type == NTLMSSP_AUTH_TYPE) { - if(auth_info.auth_type != NTLMSSP_AUTH_TYPE) { - DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", - auth_info.auth_type )); - return False; - } + if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to " + "unmarshall RPC_HDR_AUTH struct.\n")); + return False; + } - if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); - return False; - } + if(!strequal(auth_verifier.signature, "NTLMSSP")) { + DEBUG(0,("api_pipe_bind_req: " + "auth_verifier.signature != NTLMSSP\n")); + return False; + } - if(!strequal(auth_verifier.signature, "NTLMSSP")) { - DEBUG(0,("api_pipe_bind_req: auth_verifier.signature != NTLMSSP\n")); - return False; - } + if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { + DEBUG(0,("api_pipe_bind_req: " + "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", + auth_verifier.msg_type)); + return False; + } - if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { - DEBUG(0,("api_pipe_bind_req: auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", - auth_verifier.msg_type)); - return False; - } + if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: " + "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); + return False; + } + + p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; + p->ntlmssp_auth_requested = True; + + } else if (auth_info.auth_type == NETSEC_AUTH_TYPE) { + + RPC_AUTH_NETSEC_NEG neg; + struct netsec_auth_struct *a = &(p->netsec_auth); + + if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: " + "Could not unmarshal SCHANNEL auth neg\n")); + return False; + } - if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); + p->netsec_auth_validated = True; + + memset(a->sess_key, 0, sizeof(a->sess_key)); + memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key)); + + a->seq_num = 0; + + DEBUG(10,("schannel auth: domain [%s] myname [%s]\n", + neg.domain, neg.myname)); + + } else { + DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", + auth_info.auth_type )); return False; } - - p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; - p->ntlmssp_auth_requested = True; } switch(p->hdr.pkt_type) { @@ -1081,6 +1160,33 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; } + if (p->netsec_auth_validated) { + RPC_AUTH_VERIFIER auth_verifier; + uint32 flags; + + init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1); + if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); + goto err_exit; + } + + /*** NETSEC verifier ***/ + + init_rpc_auth_verifier(&auth_verifier, "\001", 0x0); + if(!smb_io_rpc_netsec_verifier("", &auth_verifier, &out_auth, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n")); + goto err_exit; + } + + prs_align(&out_auth); + + flags = 5; + if(!prs_uint32("flags ", &out_auth, 0, &flags)) + goto err_exit; + + auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; + } + /* * Create the header, now we know the length. */ @@ -1108,7 +1214,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) goto err_exit; } - if(p->ntlmssp_auth_requested && !prs_append_prs_data( &outgoing_rpc, &out_auth)) { + if((p->ntlmssp_auth_requested|p->netsec_auth_validated) && + !prs_append_prs_data( &outgoing_rpc, &out_auth)) { DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n")); goto err_exit; } @@ -1240,6 +1347,265 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) return True; } +static void netsechash(uchar * key, uchar * data, int data_len) +{ + uchar hash[256]; + uchar index_i = 0; + uchar index_j = 0; + uchar j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + hash[ind] = (uchar) ind; + } + + for (ind = 0; ind < 256; ind++) + { + uchar tc; + + j += (hash[ind] + key[ind % 16]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + for (ind = 0; ind < data_len; ind++) + { + uchar tc; + uchar t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] ^= hash[t]; + } +} + +void dump_data_pw(const char *msg, const uchar * data, size_t len) +{ +#ifdef DEBUG_PASSWORD + DEBUG(11, ("%s", msg)); + if (data != NULL && len > 0) + { + dump_data(11, data, len); + } +#endif +} + +BOOL netsec_encode(struct netsec_auth_struct *a, + RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) +{ + uchar dataN[4]; + uchar digest1[16]; + struct MD5Context ctx3; + uchar sess_kf0[16]; + int i; + + /* store the sequence number */ + SIVAL(dataN, 0, a->seq_num); + + for (i = 0; i < sizeof(sess_kf0); i++) + { + sess_kf0[i] = a->sess_key[i] ^ 0xf0; + } + + dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); + dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); + + MD5Init(&ctx3); + MD5Update(&ctx3, dataN, 0x4); + MD5Update(&ctx3, verf->sig, 8); + + MD5Update(&ctx3, verf->data8, 8); + + dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); + dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); + + hmac_md5(sess_kf0, dataN, 0x4, digest1); + dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); + hmac_md5(digest1, verf->data3, 8, digest1); + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + netsechash(digest1, verf->data8, 8); + + dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); + + dump_data_pw("data :\n", data, data_len); + MD5Update(&ctx3, data, data_len); + + { + char digest_tmp[16]; + char digest2[16]; + MD5Final(digest_tmp, &ctx3); + hmac_md5(a->sess_key, digest_tmp, 16, digest2); + dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); + dump_data_pw("digest:\n", digest2, sizeof(digest2)); + memcpy(verf->data1, digest2, sizeof(verf->data1)); + } + + netsechash(digest1, data, data_len); + dump_data_pw("data:\n", data, data_len); + + hmac_md5(a->sess_key, dataN, 0x4, digest1); + dump_data_pw("ctx:\n", digest1, sizeof(digest1)); + + hmac_md5(digest1, verf->data1, 8, digest1); + + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + + dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); + netsechash(digest1, verf->data3, 8); + dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); + + return True; +} + +BOOL netsec_decode(struct netsec_auth_struct *a, + RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) +{ + uchar dataN[4]; + uchar digest1[16]; + struct MD5Context ctx3; + uchar sess_kf0[16]; + int i; + + /* store the sequence number */ + SIVAL(dataN, 0, a->seq_num); + + for (i = 0; i < sizeof(sess_kf0); i++) + { + sess_kf0[i] = a->sess_key[i] ^ 0xf0; + } + + dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); + dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); + hmac_md5(a->sess_key, dataN, 0x4, digest1); + dump_data_pw("ctx:\n", digest1, sizeof(digest1)); + + hmac_md5(digest1, verf->data1, 8, digest1); + + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); + netsechash(digest1, verf->data3, 8); + dump_data_pw("verf->data3_dec:\n", verf->data3, sizeof(verf->data3)); + + MD5Init(&ctx3); + MD5Update(&ctx3, dataN, 0x4); + MD5Update(&ctx3, verf->sig, 8); + + dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); + + hmac_md5(sess_kf0, dataN, 0x4, digest1); + dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); + hmac_md5(digest1, verf->data3, 8, digest1); + dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); + + dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); + netsechash(digest1, verf->data8, 8); + dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8)); + MD5Update(&ctx3, verf->data8, 8); + + dump_data_pw("data :\n", data, data_len); + netsechash(digest1, data, data_len); + dump_data_pw("datadec:\n", data, data_len); + + MD5Update(&ctx3, data, data_len); + { + uchar digest_tmp[16]; + MD5Final(digest_tmp, &ctx3); + hmac_md5(a->sess_key, digest_tmp, 16, digest1); + dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); + } + + dump_data_pw("digest:\n", digest1, sizeof(digest1)); + dump_data_pw("verf->data1:\n", verf->data1, sizeof(verf->data1)); + + return memcmp(digest1, verf->data1, sizeof(verf->data1)) == 0; +} + +/**************************************************************************** + Deal with schannel processing on an RPC request. +****************************************************************************/ +BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) +{ + /* + * We always negotiate the following two bits.... + */ + int data_len; + int auth_len; + uint32 old_offset; + RPC_HDR_AUTH auth_info; + RPC_AUTH_NETSEC_CHK netsec_chk; + + + auth_len = p->hdr.auth_len; + + if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + DEBUG(0,("Incorrect auth_len %d.\n", auth_len )); + return False; + } + + /* + * The following is that length of the data we must verify or unseal. + * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN + * preceeding the auth_data. + */ + + data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - + RPC_HDR_AUTH_LEN - auth_len; + + DEBUG(5,("data %d auth %d\n", data_len, auth_len)); + + old_offset = prs_offset(rpc_in); + + if(!prs_set_offset(rpc_in, old_offset + data_len)) { + DEBUG(0,("cannot move offset to %u.\n", + (unsigned int)old_offset + data_len )); + return False; + } + + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { + DEBUG(0,("failed to unmarshall RPC_HDR_AUTH.\n")); + return False; + } + + if ((auth_info.auth_type != NETSEC_AUTH_TYPE) || + (auth_info.auth_level != NETSEC_AUTH_LEVEL)) { + DEBUG(0,("Invalid auth info %d or level %d on schannel\n", + auth_info.auth_type, auth_info.auth_level)); + return False; + } + + if(!smb_io_rpc_auth_netsec_chk("", &netsec_chk, rpc_in, 0)) { + DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n")); + return False; + } + + if (!netsec_decode(&p->netsec_auth, &netsec_chk, + prs_data_p(rpc_in)+old_offset, data_len)) { + DEBUG(0,("failed to decode PDU\n")); + return False; + } + + /* + * Return the current pointer to the data offset. + */ + + if(!prs_set_offset(rpc_in, old_offset)) { + DEBUG(0,("failed to set offset back to %u\n", + (unsigned int)old_offset )); + return False; + } + + return True; +} + /**************************************************************************** Return a user struct for a pipe user. ****************************************************************************/ -- cgit From d3b8ac6f96889c3dc9137a6b24f351e8df9c23cb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 09:31:29 +0000 Subject: Put the core schannel functions to parse_prs.c. They are also used by schannel clients. Volker (This used to be commit 0f348a35d09ff020837119157ef7f4b9e6f07643) --- source3/rpc_server/srv_pipe.c | 189 +----------------------------------------- 1 file changed, 2 insertions(+), 187 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index af3f1549a0..80275e6070 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -284,13 +284,10 @@ BOOL create_next_pdu(pipes_struct *p) init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, sign, nullbytes); - if (!netsec_encode(&p->netsec_auth, &verf, data, data_len)) { - DEBUG(0,("create_next_pdu: failed encode data.\n")); - prs_mem_free(&outgoing_pdu); - return False; - } + netsec_encode(&p->netsec_auth, &verf, data, data_len); smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0); + p->netsec_auth.seq_num++; } @@ -1347,188 +1344,6 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) return True; } -static void netsechash(uchar * key, uchar * data, int data_len) -{ - uchar hash[256]; - uchar index_i = 0; - uchar index_j = 0; - uchar j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - hash[ind] = (uchar) ind; - } - - for (ind = 0; ind < 256; ind++) - { - uchar tc; - - j += (hash[ind] + key[ind % 16]); - - tc = hash[ind]; - hash[ind] = hash[j]; - hash[j] = tc; - } - - for (ind = 0; ind < data_len; ind++) - { - uchar tc; - uchar t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] ^= hash[t]; - } -} - -void dump_data_pw(const char *msg, const uchar * data, size_t len) -{ -#ifdef DEBUG_PASSWORD - DEBUG(11, ("%s", msg)); - if (data != NULL && len > 0) - { - dump_data(11, data, len); - } -#endif -} - -BOOL netsec_encode(struct netsec_auth_struct *a, - RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) -{ - uchar dataN[4]; - uchar digest1[16]; - struct MD5Context ctx3; - uchar sess_kf0[16]; - int i; - - /* store the sequence number */ - SIVAL(dataN, 0, a->seq_num); - - for (i = 0; i < sizeof(sess_kf0); i++) - { - sess_kf0[i] = a->sess_key[i] ^ 0xf0; - } - - dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); - dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); - - MD5Init(&ctx3); - MD5Update(&ctx3, dataN, 0x4); - MD5Update(&ctx3, verf->sig, 8); - - MD5Update(&ctx3, verf->data8, 8); - - dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); - dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); - - hmac_md5(sess_kf0, dataN, 0x4, digest1); - dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); - hmac_md5(digest1, verf->data3, 8, digest1); - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - netsechash(digest1, verf->data8, 8); - - dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); - - dump_data_pw("data :\n", data, data_len); - MD5Update(&ctx3, data, data_len); - - { - char digest_tmp[16]; - char digest2[16]; - MD5Final(digest_tmp, &ctx3); - hmac_md5(a->sess_key, digest_tmp, 16, digest2); - dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); - dump_data_pw("digest:\n", digest2, sizeof(digest2)); - memcpy(verf->data1, digest2, sizeof(verf->data1)); - } - - netsechash(digest1, data, data_len); - dump_data_pw("data:\n", data, data_len); - - hmac_md5(a->sess_key, dataN, 0x4, digest1); - dump_data_pw("ctx:\n", digest1, sizeof(digest1)); - - hmac_md5(digest1, verf->data1, 8, digest1); - - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - - dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); - netsechash(digest1, verf->data3, 8); - dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); - - return True; -} - -BOOL netsec_decode(struct netsec_auth_struct *a, - RPC_AUTH_NETSEC_CHK * verf, char *data, size_t data_len) -{ - uchar dataN[4]; - uchar digest1[16]; - struct MD5Context ctx3; - uchar sess_kf0[16]; - int i; - - /* store the sequence number */ - SIVAL(dataN, 0, a->seq_num); - - for (i = 0; i < sizeof(sess_kf0); i++) - { - sess_kf0[i] = a->sess_key[i] ^ 0xf0; - } - - dump_data_pw("a->sess_key:\n", a->sess_key, sizeof(a->sess_key)); - dump_data_pw("a->seq_num :\n", dataN, sizeof(dataN)); - hmac_md5(a->sess_key, dataN, 0x4, digest1); - dump_data_pw("ctx:\n", digest1, sizeof(digest1)); - - hmac_md5(digest1, verf->data1, 8, digest1); - - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - dump_data_pw("verf->data3:\n", verf->data3, sizeof(verf->data3)); - netsechash(digest1, verf->data3, 8); - dump_data_pw("verf->data3_dec:\n", verf->data3, sizeof(verf->data3)); - - MD5Init(&ctx3); - MD5Update(&ctx3, dataN, 0x4); - MD5Update(&ctx3, verf->sig, 8); - - dump_data_pw("sess_kf0:\n", sess_kf0, sizeof(sess_kf0)); - - hmac_md5(sess_kf0, dataN, 0x4, digest1); - dump_data_pw("digest1 (ebp-8):\n", digest1, sizeof(digest1)); - hmac_md5(digest1, verf->data3, 8, digest1); - dump_data_pw("netsechashkey:\n", digest1, sizeof(digest1)); - - dump_data_pw("verf->data8:\n", verf->data8, sizeof(verf->data8)); - netsechash(digest1, verf->data8, 8); - dump_data_pw("verf->data8_dec:\n", verf->data8, sizeof(verf->data8)); - MD5Update(&ctx3, verf->data8, 8); - - dump_data_pw("data :\n", data, data_len); - netsechash(digest1, data, data_len); - dump_data_pw("datadec:\n", data, data_len); - - MD5Update(&ctx3, data, data_len); - { - uchar digest_tmp[16]; - MD5Final(digest_tmp, &ctx3); - hmac_md5(a->sess_key, digest_tmp, 16, digest1); - dump_data_pw("digest_tmp:\n", digest_tmp, sizeof(digest_tmp)); - } - - dump_data_pw("digest:\n", digest1, sizeof(digest1)); - dump_data_pw("verf->data1:\n", verf->data1, sizeof(verf->data1)); - - return memcmp(digest1, verf->data1, sizeof(verf->data1)) == 0; -} - /**************************************************************************** Deal with schannel processing on an RPC request. ****************************************************************************/ -- cgit From 3b865c73989e7f13e3a6453f9f9c9a7aca74b129 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 Apr 2003 02:08:03 +0000 Subject: Merge of rpcecho pipe for testing large dcerpc requests and responses. Only compiled in when --enable-developer argument passed to configure. (This used to be commit 017da9393bab276543d0d5c50df8c760780f2450) --- source3/rpc_server/srv_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 80275e6070..1a48435c9d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -537,6 +537,11 @@ static struct api_cmd api_fd_commands[] = #endif #ifndef RPC_DFS_DYNAMIC { "netdfs", rpc_dfs_init }, +#endif +#ifdef DEVELOPER +#ifndef RPC_ECHO_DYNAMIC + { "rpcecho", rpc_echo_init }, +#endif #endif { NULL, NULL } }; -- cgit From ab8a9c8419a66ff22714fb84530534fde321db26 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2003 16:55:21 +0000 Subject: use the new modules system for the rpc modules (backport from HEAD) (This used to be commit aca7319e8d45eb604f28b8bd490413b08e2c98f2) --- source3/rpc_server/srv_pipe.c | 106 +++--------------------------------------- 1 file changed, 7 insertions(+), 99 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1a48435c9d..43fbb4edaa 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -506,46 +506,6 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); The switch table for the pipe names and the functions to handle them. *******************************************************************/ -struct api_cmd -{ - const char *name; - int (*init)(void); -}; - -static struct api_cmd api_fd_commands[] = -{ -#ifndef RPC_LSA_DYNAMIC - { "lsarpc", rpc_lsa_init }, -#endif -#ifndef RPC_SAMR_DYNAMIC - { "samr", rpc_samr_init }, -#endif -#ifndef RPC_SVC_DYNAMIC - { "srvsvc", rpc_srv_init }, -#endif -#ifndef RPC_WKS_DYNAMIC - { "wkssvc", rpc_wks_init }, -#endif -#ifndef RPC_NETLOG_DYNAMIC - { "NETLOGON", rpc_net_init }, -#endif -#ifndef RPC_REG_DYNAMIC - { "winreg", rpc_reg_init }, -#endif -#ifndef RPC_SPOOLSS_DYNAMIC - { "spoolss", rpc_spoolss_init }, -#endif -#ifndef RPC_DFS_DYNAMIC - { "netdfs", rpc_dfs_init }, -#endif -#ifdef DEVELOPER -#ifndef RPC_ECHO_DYNAMIC - { "rpcecho", rpc_echo_init }, -#endif -#endif - { NULL, NULL } -}; - struct rpc_table { struct @@ -848,47 +808,6 @@ int rpc_pipe_register_commands(const char *clnt, const char *srv, const struct a return size; } -/******************************************************************* - Register commands to an RPC pipe -*******************************************************************/ -int rpc_load_module(const char *module) -{ -#ifdef HAVE_DLOPEN - void *handle; - int (*module_init)(void); - pstring full_path; - const char *error; - - pstrcpy(full_path, lib_path("rpc")); - pstrcat(full_path, "/librpc_"); - pstrcat(full_path, module); - pstrcat(full_path, "."); - pstrcat(full_path, shlib_ext()); - - handle = sys_dlopen(full_path, RTLD_LAZY); - if (!handle) { - DEBUG(0, ("Could not load requested pipe %s as %s\n", - module, full_path)); - DEBUG(0, (" Error: %s\n", dlerror())); - return 0; - } - - DEBUG(3, ("Module '%s' loaded\n", full_path)); - - module_init = sys_dlsym(handle, "rpc_pipe_init"); - if ((error = sys_dlerror()) != NULL) { - DEBUG(0, ("Error trying to resolve symbol 'rpc_pipe_init' in %s: %s\n", - full_path, error)); - return 0; - } - - return module_init(); -#else - DEBUG(0,("Attempting to load a dynamic RPC pipe when dlopen isn't available\n")); - return 0; -#endif -} - /******************************************************************* Respond to a pipe bind request. *******************************************************************/ @@ -928,14 +847,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } if (i == rpc_lookup_size) { - for (i = 0; api_fd_commands[i].name; i++) { - if (strequal(api_fd_commands[i].name, p->name)) { - api_fd_commands[i].init(); - break; - } - } - - if (!api_fd_commands[i].name && !rpc_load_module(p->name)) { + if (!smb_probe_module("rpc", p->name)) { DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", p->name )); if(!setup_bind_nak(p)) @@ -951,6 +863,11 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) break; } } + + if (i == rpc_lookup_size) { + DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); + return False; + } } /* decode the bind request */ @@ -1478,16 +1395,7 @@ BOOL api_pipe_request(pipes_struct *p) if (i == rpc_lookup_size) { - for (i = 0; api_fd_commands[i].name; i++) { - if (strequal(api_fd_commands[i].name, p->name)) { - api_fd_commands[i].init(); - break; - } - } - - if (!api_fd_commands[i].name) { - rpc_load_module(p->name); - } + smb_probe_module("rpc", p->name); for (i = 0; i < rpc_lookup_size; i++) { if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { -- cgit From 09a50497d1360659eb8bd1b9f4be510680267bd2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Apr 2003 15:39:57 +0000 Subject: Fixes to make SCHANNEL work in 3.0 against a W2K DC. Still need to fix multi-PDU encode/decode with SCHANNEL. Also need to test against WNT DC. Jeremy. (This used to be commit ff66d4097088409205b6bad5124a78ef9946010d) --- source3/rpc_server/srv_pipe.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 43fbb4edaa..df99c15777 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -279,8 +279,13 @@ BOOL create_next_pdu(pipes_struct *p) prs_init(&rverf, 0, p->mem_ctx, MARSHALL); prs_init(&rauth, 0, p->mem_ctx, MARSHALL); - memset(sign, 0, sizeof(sign)); - sign[3] = 0x01; + if ((p->netsec_auth.seq_num & 1) == 0) { + DEBUG(0,("SCHANNEL ERROR: seq_num must be odd in server! (seq_num=%d)\n", + p->netsec_auth.seq_num)); + } + + RSIVAL(sign, 0, p->netsec_auth.seq_num); + SIVAL(sign, 4, 0); init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, sign, nullbytes); @@ -1340,6 +1345,9 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) return False; } + /* The sequence number gets incremented on both send and receive. */ + p->netsec_auth.seq_num++; + return True; } -- cgit From 8301c8c0e4e3085a6e661dd5c04b20fc89db0bc3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 22 Apr 2003 11:25:10 +0000 Subject: Setting the credentials for the netsec netlogon pipe connect upon each samlogon call certainly breaks the credential chain. Do it once during the bind response. Volker (This used to be commit d4262c37f13642e034d3e207bfbb563c17a8a176) --- source3/rpc_server/srv_pipe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index df99c15777..b09058629a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1088,6 +1088,11 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) RPC_AUTH_VERIFIER auth_verifier; uint32 flags; + /* The client opens a second RPC NETLOGON pipe without + doing a auth2. The credentials for the schannel are + re-used from the auth2 the client did before. */ + p->dc = last_dcinfo; + init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); -- cgit From 17a3acafa89bfc6090b0767d05a00a7505003fcc Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 28 Apr 2003 17:48:48 +0000 Subject: Use NTSTATUS as return value for smb_register_*() functions and init_module() function. Patch by metze with some minor modifications. (This used to be commit bc4b51bcb2daa7271c884cb83bf8bdba6d3a9b6d) --- source3/rpc_server/srv_pipe.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index b09058629a..5b9d39ddc7 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -781,10 +781,28 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, /******************************************************************* Register commands to an RPC pipe *******************************************************************/ -int rpc_pipe_register_commands(const char *clnt, const char *srv, const struct api_struct *cmds, int size) +NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size) { struct rpc_table *rpc_entry; + if (!clnt || !srv || !cmds) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (version != SMB_RPC_INTERFACE_VERSION) { + DEBUG(0,("Can't register rpc commands!\n" + "You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d" + ", while this version of samba uses version %d!\n", + version,SMB_RPC_INTERFACE_VERSION)); + return NT_STATUS_OBJECT_TYPE_MISMATCH; + } + + /* TODO: + * + * we still need to make sure that don't register the same commands twice!!! + * + * --metze + */ /* We use a temporary variable because this call can fail and rpc_lookup will still be valid afterwards. It could then succeed if @@ -794,7 +812,7 @@ int rpc_pipe_register_commands(const char *clnt, const char *srv, const struct a if (NULL == rpc_entry) { rpc_lookup_size--; DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n")); - return 0; + return NT_STATUS_NO_MEMORY; } else { rpc_lookup = rpc_entry; } @@ -810,7 +828,7 @@ int rpc_pipe_register_commands(const char *clnt, const char *srv, const struct a size * sizeof(struct api_struct)); rpc_entry->n_cmds += size; - return size; + return NT_STATUS_OK; } /******************************************************************* @@ -852,7 +870,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } if (i == rpc_lookup_size) { - if (!smb_probe_module("rpc", p->name)) { + if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", p->name )); if(!setup_bind_nak(p)) -- cgit From c823b191ab476fc2583d6d6aaa1e2edb09cbb88e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 12 May 2003 18:12:31 +0000 Subject: And finally IDMAP in 3_0 We really need idmap_ldap to have a good solution with ldapsam, porting it from the prvious code is beeing made, the code is really simple to do so I am confident it is not a problem to commit this code in. Not committing it would have been worst. I really would have been able to finish also the group code, maybe we can put it into a followin release after 3.0.0 even if it may be an upgrade problem. The code has been tested and seem to work right, more testing is needed for corner cases. Currently winbind pdc (working only for users and not for groups) is disabled as I was not able to make a complete group code replacement that works somewhat in a week (I have a complete patch, but there are bugs) Simo. (This used to be commit 0e58085978f984436815114a2ec347cf7899a89d) --- source3/rpc_server/srv_pipe.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5b9d39ddc7..6a9e591f64 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -472,16 +472,10 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - if (!IS_SAM_UNIX_USER(server_info->sam_account)) { - DEBUG(0,("Attempted authenticated pipe with invalid user. No uid/gid in SAM_ACCOUNT\n")); - free_server_info(&server_info); - return False; - } - memcpy(p->session_key, server_info->session_key, sizeof(p->session_key)); - p->pipe_user.uid = pdb_get_uid(server_info->sam_account); - p->pipe_user.gid = pdb_get_gid(server_info->sam_account); + p->pipe_user.uid = server_info->uid; + p->pipe_user.gid = server_info->gid; p->pipe_user.ngroups = server_info->n_groups; if (p->pipe_user.ngroups) { -- cgit From 61116049cabc292c2f2d570af4d68ddc537b91f5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 3 Jul 2003 14:36:42 +0000 Subject: This patch takes the work the jerry did for beta2, and generalises it: - The 'not implmented' checks are now done by all auth modules - the ntdomain/trustdomain/winbind modules are more presise as to what domain names they can and cannot handle - The become_root() calls are now around the winbind pipe opening only, not the entire auth call - The unix username is kept seperate from the NT username, removing the need for 'clean off the domain\' in parse_net.c - All sid->uid translations are now validated with getpwuid() to put a very basic stop to logins with 'half deleted' accounts. Andrew Bartlett (This used to be commit 85f88191b9927cc434645ef4c1eaf5ec0e8af2ec) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 6a9e591f64..f7663204b2 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -464,7 +464,7 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); } fstrcpy(p->user_name, user_name); - fstrcpy(p->pipe_user_name, pdb_get_username(server_info->sam_account)); + fstrcpy(p->pipe_user_name, server_info->unix_name); fstrcpy(p->domain, domain); fstrcpy(p->wks, wks); -- cgit From 456f51bcbe04ccbb37a27b6e115a851cc134adcd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Jul 2003 08:46:32 +0000 Subject: Jeremy requested that I get my NTLMSSP patch into CVS. He didn't request the schannel code, but I've included that anyway. :-) This patch revives the client-side NTLMSSP support for RPC named pipes in Samba, and cleans up the client and server schannel code. The use of the new code is enabled by the 'sign', 'seal' and 'schannel' commands in rpcclient. The aim was to prove that our separate NTLMSSP client library actually implements NTLMSSP signing and sealing as per Microsoft's NTLMv1 implementation, in the hope that knowing this will assist us in correctly implementing NTLMSSP signing for SMB packets. (Still not yet functional) This patch replaces the NTLMSSP implementation in rpc_client/cli_pipe.c with calls to libsmb/ntlmssp.c. In the process, we have gained the ability to use the more secure NT password, and the ability to sign-only, instead of having to seal the pipe connection. (Previously we were limited to sealing, and could only use the LM-password derived key). Our new client-side NTLMSSP code also needed alteration to cope with our comparatively simple server-side implementation. A future step is to replace it with calls to the same NTLMSSP library. Also included in this patch is the schannel 'sign only' patch I submitted to the team earlier. While not enabled (and not functional, at this stage) the work in this patch makes the code paths *much* easier to follow. I have also included similar hooks in rpccleint to allow the use of schannel on *any* pipe. rpcclient now defaults to not using schannel (or any other extra per-pipe authenticiation) for any connection. The 'schannel' command enables schannel for all pipes until disabled. This code is also much more secure than the previous code, as changes to our cli_pipe routines ensure that the authentication footer cannot be removed by an attacker, and more error states are correctly handled. (The same needs to be done to our server) Andrew Bartlett (This used to be commit 5472ddc9eaf4e79c5b2e1c8ee8c7f190dc285f19) --- source3/rpc_server/srv_pipe.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index f7663204b2..9a63ebc7a3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -227,7 +227,7 @@ BOOL create_next_pdu(pipes_struct *p) if (auth_seal || auth_verify) { RPC_HDR_AUTH auth_info; - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0)); if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); @@ -263,11 +263,9 @@ BOOL create_next_pdu(pipes_struct *p) prs_struct rverf; prs_struct rauth; - uchar sign[8]; - data = prs_data_p(&outgoing_pdu) + data_pos; - init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, + init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { @@ -284,12 +282,12 @@ BOOL create_next_pdu(pipes_struct *p) p->netsec_auth.seq_num)); } - RSIVAL(sign, 0, p->netsec_auth.seq_num); - SIVAL(sign, 4, 0); - - init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, sign, nullbytes); + init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, nullbytes, nullbytes); - netsec_encode(&p->netsec_auth, &verf, data, data_len); + netsec_encode(&p->netsec_auth, + AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL, + SENDER_IS_ACCEPTOR, + &verf, data, data_len); smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0); @@ -458,6 +456,10 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); p->ntlmssp_hash[256] = 0; p->ntlmssp_hash[257] = 0; } + + dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash, + sizeof(p->ntlmssp_hash)); + /* NTLMSSPhash(p->ntlmssp_hash, p24); */ p->ntlmssp_seq_num = 0; @@ -546,7 +548,7 @@ BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p) return False; } - if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != NTLMSSP_AUTH_LEVEL) { + if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) { DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n", (int)autha_info.auth_type, (int)autha_info.auth_level )); return False; @@ -1070,7 +1072,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) /*** Authentication info ***/ - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, NTLMSSP_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1); + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); goto err_exit; @@ -1105,7 +1107,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) re-used from the auth2 the client did before. */ p->dc = last_dcinfo; - init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, NETSEC_AUTH_LEVEL, RPC_HDR_AUTH_LEN, 1); + init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); goto err_exit; @@ -1226,7 +1228,14 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) * has already been consumed. */ char *data = prs_data_p(rpc_in) + RPC_HDR_REQ_LEN; + dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash, + sizeof(p->ntlmssp_hash)); + + dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n", + data, data_len); NTLMSSPcalc_p(p, (uchar*)data, data_len); + dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n", + data, data_len); crc32 = crc32_calc_buffer(data, data_len); } @@ -1335,7 +1344,7 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) } if ((auth_info.auth_type != NETSEC_AUTH_TYPE) || - (auth_info.auth_level != NETSEC_AUTH_LEVEL)) { + (auth_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL)) { DEBUG(0,("Invalid auth info %d or level %d on schannel\n", auth_info.auth_type, auth_info.auth_level)); return False; @@ -1346,7 +1355,10 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) return False; } - if (!netsec_decode(&p->netsec_auth, &netsec_chk, + if (!netsec_decode(&p->netsec_auth, + AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL, + SENDER_IS_INITIATOR, + &netsec_chk, prs_data_p(rpc_in)+old_offset, data_len)) { DEBUG(0,("failed to decode PDU\n")); return False; -- cgit From 4c53bb6b90fec8e03c812a70a84889fcdf3b1081 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Jul 2003 01:34:05 +0000 Subject: In the presense of RPC fragments, schannel is not strictly request/reply, so the shared sequence number will not be strictly odd/even. Andrew Bartlett (This used to be commit 77c3e69aef545d3f9b7cec9efdc366cbeb0c745e) --- source3/rpc_server/srv_pipe.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9a63ebc7a3..acc62880d0 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -277,11 +277,6 @@ BOOL create_next_pdu(pipes_struct *p) prs_init(&rverf, 0, p->mem_ctx, MARSHALL); prs_init(&rauth, 0, p->mem_ctx, MARSHALL); - if ((p->netsec_auth.seq_num & 1) == 0) { - DEBUG(0,("SCHANNEL ERROR: seq_num must be odd in server! (seq_num=%d)\n", - p->netsec_auth.seq_num)); - } - init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, nullbytes, nullbytes); netsec_encode(&p->netsec_auth, -- cgit From f210ee9b99b3b6ac0234680f1af83fd783ef9af4 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Aug 2003 14:47:39 +0000 Subject: Fix copyright statements for various pieces of Anthony Liguori's work. (This used to be commit 15d2bc47854df75f8b2644ccbc887d0357d9cd27) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index acc62880d0..668641e621 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1997-1998, * Copyright (C) Jeremy Allison 1999, - * Copyright (C) Anthony Liguori 2003. + * Copyright (C) Jim McDonough 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit From 8c64504f7c58b05769ec1014242c15a2eb93ca84 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Aug 2003 15:30:44 +0000 Subject: Update my copyrights according to my agreement with IBM (This used to be commit a2bd8f0bfa12f2a1e33c96bc9dabcc0e2171700d) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 668641e621..594cb3a9ae 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, * Copyright (C) Paul Ashton 1997-1998, * Copyright (C) Jeremy Allison 1999, - * Copyright (C) Jim McDonough 2003. + * Copyright (C) Jim McDonough 2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit From ac8c6e47463545011f5471960c2a2073a9b04979 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Aug 2003 23:09:09 +0000 Subject: Format tidyup. Jeremy. (This used to be commit 049e77d636c5abd0fdd8840c3c4c465708354ed7) --- source3/rpc_server/srv_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 594cb3a9ae..11a5c934de 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -878,10 +878,10 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } } - if (i == rpc_lookup_size) { - DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); - return False; - } + if (i == rpc_lookup_size) { + DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); + return False; + } } /* decode the bind request */ -- cgit From 11777e6a3085a996ab2c5fa3db34d8834401c24e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 14 Aug 2003 21:14:28 +0000 Subject: Attempt at fixing bug #283. There however is no solution. There is a workaround documented in the bug report. This patch does: * add server support for the LSA_DS UUID on the lsarpc pipe * store a list of context_ids/api_structs in the pipe_struct so that we don't have to lookup the function table for a pipe. We just match the context_id. Note that a dce/rpc alter_context does not destroy the previous context so it is possible to have multiple bindings active on the same pipe. Observed from standalone win2k sp4 client. * added server code for DsROleGetPrimaryDOmainInfo() but disabled it since it causes problems enumerating users and groups from a 2ksp4 domain member in a Samba domain. (This used to be commit 96bc2abfcb0dd0912696fad76e43cb217b33e061) --- source3/rpc_server/srv_pipe.c | 195 +++++++++++++++++++++++++++++------------- 1 file changed, 135 insertions(+), 60 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 11a5c934de..1c99943a9d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -713,26 +713,19 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status) Used to reject unknown binds from Win2k. *******************************************************************/ -BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, - RPC_IFACE* transfer) +BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, + RPC_IFACE* transfer, uint32 context_id) { extern struct pipe_id_info pipe_names[]; + char *pipe_name = p->name; int i=0; fstring pname; + fstrcpy(pname,"\\PIPE\\"); fstrcat(pname,pipe_name); DEBUG(3,("check_bind_req for %s\n", pname)); -#ifndef SUPPORT_NEW_LSARPC_UUID - - /* check for the first pipe matching the name */ - - for ( i=0; pipe_names[i].client_pipe; i++ ) { - if ( strequal(pipe_names[i].client_pipe, pname) ) - break; - } -#else /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ for ( i=0; pipe_names[i].client_pipe; i++ ) @@ -743,29 +736,34 @@ BOOL check_bind_req(char* pipe_name, RPC_IFACE* abstract, && (transfer->version == pipe_names[i].trans_syntax.version) && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) ) { + struct api_struct *fns = NULL; + int n_fns = 0; + PIPE_RPC_FNS *context_fns; + + if ( !(context_fns = malloc(sizeof(PIPE_RPC_FNS))) ) { + DEBUG(0,("check_bind_req: malloc() failed!\n")); + return False; + } + + /* save the RPC function table associated with this bind */ + + get_pipe_fns(i, &fns, &n_fns); + + context_fns->cmds = fns; + context_fns->n_cmds = n_fns; + context_fns->context_id = context_id; + + /* add to the list of open contexts */ + + DLIST_ADD( p->contexts, context_fns ); + break; } } -#endif if(pipe_names[i].client_pipe == NULL) return False; -#ifndef SUPPORT_NEW_LSARPC_UUID - /* check the abstract interface */ - if ( (abstract->version != pipe_names[i].abstr_syntax.version) - || (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) != 0) ) - { - return False; - } - - /* check the transfer interface */ - if ( (transfer->version != pipe_names[i].trans_syntax.version) - || (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) != 0) ) - { - return False; - } -#endif return True; } @@ -861,7 +859,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } if (i == rpc_lookup_size) { - if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { + if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", p->name )); if(!setup_bind_nak(p)) @@ -1028,7 +1026,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) unknown to NT4) Needed when adding entries to a DACL from NT5 - SK */ - if(check_bind_req(p->name, &hdr_rb.abstract, &hdr_rb.transfer)) { + if(check_bind_req(p, &hdr_rb.abstract, &hdr_rb.transfer, hdr_rb.context_id )) + { init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, @@ -1391,6 +1390,48 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p return user; } +/**************************************************************************** + Find the set of RPC functions associated with this context_id +****************************************************************************/ + +static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 context_id ) +{ + PIPE_RPC_FNS *fns = NULL; + PIPE_RPC_FNS *tmp = NULL; + + if ( !list ) { + DEBUG(0,("find_pipe_fns_by_context: ERROR! No context list for pipe!\n")); + return NULL; + } + + for (tmp=list; tmp; tmp=tmp->next ) { + if ( tmp->context_id == context_id ) + break; + } + + fns = tmp; + + return fns; +} + +/**************************************************************************** + memory cleanup +****************************************************************************/ + +void free_pipe_rpc_context( PIPE_RPC_FNS *list ) +{ + PIPE_RPC_FNS *tmp = list; + PIPE_RPC_FNS *tmp2; + + while (tmp) { + tmp2 = tmp->next; + SAFE_FREE(tmp); + tmp = tmp2; + } + + return; +} + /**************************************************************************** Find the correct RPC function to call for this request. If the pipe is authenticated then become the correct UNIX user @@ -1399,9 +1440,9 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p BOOL api_pipe_request(pipes_struct *p) { - int i = 0; BOOL ret = False; - + PIPE_RPC_FNS *pipe_fns; + if (p->ntlmssp_auth_validated) { if(!become_authenticated_pipe_user(p)) { @@ -1411,36 +1452,19 @@ BOOL api_pipe_request(pipes_struct *p) } DEBUG(5, ("Requested \\PIPE\\%s\n", p->name)); - - for (i = 0; i < rpc_lookup_size; i++) { - if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { - DEBUG(3,("Doing \\PIPE\\%s\n", - rpc_lookup[i].pipe.clnt)); - set_current_rpc_talloc(p->mem_ctx); - ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt, - rpc_lookup[i].cmds, - rpc_lookup[i].n_cmds); - set_current_rpc_talloc(NULL); - break; - } + + /* get the set of RPC functions for this context */ + + pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id); + + if ( pipe_fns ) { + set_current_rpc_talloc(p->mem_ctx); + ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds); + set_current_rpc_talloc(NULL); } - - - if (i == rpc_lookup_size) { - smb_probe_module("rpc", p->name); - - for (i = 0; i < rpc_lookup_size; i++) { - if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { - DEBUG(3,("Doing \\PIPE\\%s\n", - rpc_lookup[i].pipe.clnt)); - set_current_rpc_talloc(p->mem_ctx); - ret = api_rpcTNP(p, rpc_lookup[i].pipe.clnt, - rpc_lookup[i].cmds, - rpc_lookup[i].n_cmds); - set_current_rpc_talloc(NULL); - break; - } - } + else { + DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n", + p->hdr_req.context_id, p->name)); } if(p->ntlmssp_auth_validated) @@ -1529,3 +1553,54 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, return True; } + +/******************************************************************* +*******************************************************************/ + +void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) +{ + struct api_struct *cmds = NULL; + int n_cmds = 0; + + switch ( idx ) { + case PI_LSARPC: + lsa_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_LSARPC_DS: + lsa_ds_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_SAMR: + samr_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_NETLOGON: + netlog_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_SRVSVC: + srvsvc_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_WKSSVC: + wkssvc_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_WINREG: + reg_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_SPOOLSS: + spoolss_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_NETDFS: + netdfs_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_ECHO: + echo_get_pipe_fns( &cmds, &n_cmds ); + break; + default: + DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx)); + } + + *fns = cmds; + *n_fns = n_cmds; + + return; +} + + -- cgit From 8f75104da17dac200395ccc91c32878b0ee5ef9b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 14 Aug 2003 22:14:03 +0000 Subject: fix build (This used to be commit dd9cb6f820c2acf658eb081fb6ffc7e9b6b3c8d6) --- source3/rpc_server/srv_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1c99943a9d..ae6337e152 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1590,9 +1590,11 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_NETDFS: netdfs_get_pipe_fns( &cmds, &n_cmds ); break; +#ifdef DEVELOPER case PI_ECHO: echo_get_pipe_fns( &cmds, &n_cmds ); break; +#endif default: DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx)); } -- cgit From 062f89bc2833bf49f873a7fd5c2624babd702db0 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 01:42:30 +0000 Subject: get rid of some sompiler warnings on IRIX (This used to be commit a6a39c61e8228c8b3b7552ab3c61ec3a6a639143) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ae6337e152..d1fb587d74 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1226,10 +1226,10 @@ BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) sizeof(p->ntlmssp_hash)); dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n", - data, data_len); + (const unsigned char *)data, data_len); NTLMSSPcalc_p(p, (uchar*)data, data_len); dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n", - data, data_len); + (const unsigned char *)data, data_len); crc32 = crc32_calc_buffer(data, data_len); } -- cgit From cbe69f65f69b0c7b7c2d0d32005da488b50e52ba Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 1 Oct 2003 21:18:32 +0000 Subject: commit sign only patch from Andrew; bug 167; tested using 2k & XP clientspreviously joined to the Samba domain (This used to be commit 3802f5895ee18507c6f467bd11db0b1147a6fdfd) --- source3/rpc_server/srv_pipe.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index d1fb587d74..96261c665f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -254,18 +254,19 @@ BOOL create_next_pdu(pipes_struct *p) } if (p->netsec_auth_validated) { + int auth_type, auth_level; char *data; RPC_HDR_AUTH auth_info; - static const uchar netsec_sig[8] = NETSEC_SIGNATURE; - static const uchar nullbytes[8] = { 0,0,0,0,0,0,0,0 }; RPC_AUTH_NETSEC_CHK verf; prs_struct rverf; prs_struct rauth; data = prs_data_p(&outgoing_pdu) + data_pos; + /* Check it's the type of reply we were expecting to decode */ - init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, + get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level); + init_rpc_hdr_auth(&auth_info, auth_type, auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { @@ -277,10 +278,8 @@ BOOL create_next_pdu(pipes_struct *p) prs_init(&rverf, 0, p->mem_ctx, MARSHALL); prs_init(&rauth, 0, p->mem_ctx, MARSHALL); - init_rpc_auth_netsec_chk(&verf, netsec_sig, nullbytes, nullbytes, nullbytes); - netsec_encode(&p->netsec_auth, - AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL, + p->netsec_auth.auth_flags, SENDER_IS_ACCEPTOR, &verf, data, data_len); @@ -1337,10 +1336,19 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) return False; } - if ((auth_info.auth_type != NETSEC_AUTH_TYPE) || - (auth_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL)) { - DEBUG(0,("Invalid auth info %d or level %d on schannel\n", - auth_info.auth_type, auth_info.auth_level)); + if (auth_info.auth_type != NETSEC_AUTH_TYPE) { + DEBUG(0,("Invalid auth info %d on schannel\n", + auth_info.auth_type)); + return False; + } + + if (auth_info.auth_level == RPC_PIPE_AUTH_SEAL_LEVEL) { + p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL; + } else if (auth_info.auth_level == RPC_PIPE_AUTH_SIGN_LEVEL) { + p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN; + } else { + DEBUG(0,("Invalid auth level %d on schannel\n", + auth_info.auth_level)); return False; } @@ -1350,7 +1358,7 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) } if (!netsec_decode(&p->netsec_auth, - AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL, + p->netsec_auth.auth_flags, SENDER_IS_INITIATOR, &netsec_chk, prs_data_p(rpc_in)+old_offset, data_len)) { -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/rpc_server/srv_pipe.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 96261c665f..fa24efe589 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -420,9 +420,15 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); * Set up the sign/seal data. */ - { + if (server_info->lm_session_key.length != 16) { + DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \ +succeeded authentication on named pipe %s, but session key was of incorrect length [%u].\n", + domain, user_name, wks, p->name, server_info->lm_session_key.length)); + free_server_info(&server_info); + return False; + } else { uchar p24[24]; - NTLMSSPOWFencrypt(server_info->first_8_lm_hash, lm_owf, p24); + NTLMSSPOWFencrypt(server_info->lm_session_key.data, lm_owf, p24); { unsigned char j = 0; int ind; @@ -468,7 +474,7 @@ failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - memcpy(p->session_key, server_info->session_key, sizeof(p->session_key)); + p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length); p->pipe_user.uid = server_info->uid; p->pipe_user.gid = server_info->gid; -- cgit From f79e40072a963fd3b9698fa26c4e4dc135ab8c3e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 7 Apr 2004 12:42:03 +0000 Subject: r115: finally checking in tridge's winbindd_schannel patch for connections (This used to be commit 1fae60ab20c5cbe396dc8af1c8c9a98d5683fdf4) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index fa24efe589..8337c4e3c7 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -227,7 +227,7 @@ BOOL create_next_pdu(pipes_struct *p) if (auth_seal || auth_verify) { RPC_HDR_AUTH auth_info; - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, auth_info.auth_level, (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0)); if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); @@ -1106,7 +1106,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) re-used from the auth2 the client did before. */ p->dc = last_dcinfo; - init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1); + init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, auth_info.auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); goto err_exit; -- cgit From 8ad3d8c9b065f3a2040beff801bdc9dceac868a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 13 Apr 2004 14:39:48 +0000 Subject: r196: merging struct uuid from trunk (This used to be commit 911a28361b9d8dd50597627f245ebfb57c6294fb) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 8337c4e3c7..ad7c544b68 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -737,9 +737,9 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, { if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) - && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(RPC_UUID)) == 0) + && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0) && (transfer->version == pipe_names[i].trans_syntax.version) - && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(RPC_UUID)) == 0) ) + && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) ) { struct api_struct *fns = NULL; int n_fns = 0; -- cgit From c1b7b9662de0c03bd33879f23754a49de2a5209a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 May 2004 20:09:24 +0000 Subject: r473: Fix for Microsoft hotfix MS04-011 password change breakage. Jeremy. (This used to be commit 038cae8a377b75d70a099f03cb1b8ae9b50e7613) --- source3/rpc_server/srv_pipe.c | 78 ++++++++++++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 26 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ad7c544b68..076f800a40 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -87,6 +87,7 @@ BOOL create_next_pdu(pipes_struct *p) RPC_HDR_RESP hdr_resp; BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0); BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0); + uint32 ss_padding_len = 0; uint32 data_len; uint32 data_space_available; uint32 data_len_left; @@ -109,21 +110,22 @@ BOOL create_next_pdu(pipes_struct *p) p->hdr.pkt_type = RPC_RESPONSE; /* Set up rpc header flags. */ - if (p->out_data.data_sent_length == 0) + if (p->out_data.data_sent_length == 0) { p->hdr.flags = RPC_FLG_FIRST; - else + } else { p->hdr.flags = 0; + } /* * Work out how much we can fit in a single PDU. */ data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; - if(p->ntlmssp_auth_validated) + if(p->ntlmssp_auth_validated) { data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); - - if(p->netsec_auth_validated) + } else if(p->netsec_auth_validated) { data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN); + } /* * The amount we send is the minimum of the available @@ -150,16 +152,31 @@ BOOL create_next_pdu(pipes_struct *p) hdr_resp.alloc_hint = data_len_left; + /* + * Work out if this PDU will be the last. + */ + + if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) { + p->hdr.flags |= RPC_FLG_LAST; + if ((auth_seal || auth_verify) && (data_len_left % 8)) { + ss_padding_len = 8 - (data_len_left % 8); + DEBUG(10,("create_next_pdu: adding sign/seal padding of %u\n", + ss_padding_len )); + } + } + /* * Set up the header lengths. */ if (p->ntlmssp_auth_validated) { - p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + - RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN; + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + + data_len + ss_padding_len + + RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN; p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; } else if (p->netsec_auth_validated) { - p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + + data_len + ss_padding_len + RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN; p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN; } else { @@ -167,13 +184,6 @@ BOOL create_next_pdu(pipes_struct *p) p->hdr.auth_len = 0; } - /* - * Work out if this PDU will be the last. - */ - - if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) - p->hdr.flags |= RPC_FLG_LAST; - /* * Init the parse struct to point at the outgoing * data. @@ -206,12 +216,26 @@ BOOL create_next_pdu(pipes_struct *p) return False; } + /* Copy the sign/seal padding data. */ + if (ss_padding_len) { + char pad[8]; + memset(pad, '\0', 8); + if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) { + DEBUG(0,("create_next_pdu: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len)); + prs_mem_free(&outgoing_pdu); + return False; + } + } + if (p->ntlmssp_auth_validated) { + /* + * NTLMSSP processing. Mutually exclusive with Schannel. + */ uint32 crc32 = 0; char *data; DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n", - BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, p->hdr.auth_len)); + BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len + ss_padding_len, p->hdr.auth_len)); /* * Set data to point to where we copied the data into. @@ -220,15 +244,16 @@ BOOL create_next_pdu(pipes_struct *p) data = prs_data_p(&outgoing_pdu) + data_pos; if (auth_seal) { - crc32 = crc32_calc_buffer(data, data_len); - NTLMSSPcalc_p(p, (uchar*)data, data_len); + crc32 = crc32_calc_buffer(data, data_len + ss_padding_len); + NTLMSSPcalc_p(p, (uchar*)data, data_len + ss_padding_len); } if (auth_seal || auth_verify) { RPC_HDR_AUTH auth_info; - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, auth_info.auth_level, - (auth_verify ? RPC_HDR_AUTH_LEN : 0), (auth_verify ? 1 : 0)); + init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, + auth_seal ? RPC_PIPE_AUTH_SEAL_LEVEL : RPC_PIPE_AUTH_SIGN_LEVEL, + (auth_verify ? ss_padding_len : 0), (auth_verify ? 1 : 0)); if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); prs_mem_free(&outgoing_pdu); @@ -251,9 +276,10 @@ BOOL create_next_pdu(pipes_struct *p) } NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); } - } - - if (p->netsec_auth_validated) { + } else if (p->netsec_auth_validated) { + /* + * Schannel processing. Mutually exclusive with NTLMSSP. + */ int auth_type, auth_level; char *data; RPC_HDR_AUTH auth_info; @@ -267,7 +293,7 @@ BOOL create_next_pdu(pipes_struct *p) get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level); init_rpc_hdr_auth(&auth_info, auth_type, auth_level, - RPC_HDR_AUTH_LEN, 1); + ss_padding_len, 1); if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); @@ -281,7 +307,7 @@ BOOL create_next_pdu(pipes_struct *p) netsec_encode(&p->netsec_auth, p->netsec_auth.auth_flags, SENDER_IS_ACCEPTOR, - &verf, data, data_len); + &verf, data, data_len + ss_padding_len); smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0); @@ -292,7 +318,7 @@ BOOL create_next_pdu(pipes_struct *p) * Setup the counts for this PDU. */ - p->out_data.data_sent_length += data_len; + p->out_data.data_sent_length += (data_len + ss_padding_len); p->out_data.current_pdu_len = p->hdr.frag_len; p->out_data.current_pdu_sent = 0; -- cgit From 741545b4978cf638f4ed8ccd533240d51e6cb24b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 May 2004 20:16:59 +0000 Subject: r475: Don't add ss padding length to the sent length as this is compared with the actual data to return. Jeremy. (This used to be commit 7f837db6e47af39b4a33e10e745823b19edb3715) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 076f800a40..3a4e085276 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -318,7 +318,7 @@ BOOL create_next_pdu(pipes_struct *p) * Setup the counts for this PDU. */ - p->out_data.data_sent_length += (data_len + ss_padding_len); + p->out_data.data_sent_length += data_len; p->out_data.current_pdu_len = p->hdr.frag_len; p->out_data.current_pdu_sent = 0; -- cgit From 41db2016adc464691ea2c3497aedca55fcf004ed Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 13 May 2004 20:32:21 +0000 Subject: r704: BUG 1315: fix for schannel client connections to server's that don't support 128 bit encryption (This used to be commit 316ba5ad89ddfa445d44d28141c5901fc64aec90) --- source3/rpc_server/srv_pipe.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3a4e085276..13d894d2d8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -124,7 +124,7 @@ BOOL create_next_pdu(pipes_struct *p) if(p->ntlmssp_auth_validated) { data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); } else if(p->netsec_auth_validated) { - data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN); + data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN); } /* @@ -177,8 +177,8 @@ BOOL create_next_pdu(pipes_struct *p) } else if (p->netsec_auth_validated) { p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len + - RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN; - p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN; + RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; + p->hdr.auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; } else { p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; p->hdr.auth_len = 0; @@ -309,7 +309,8 @@ BOOL create_next_pdu(pipes_struct *p) SENDER_IS_ACCEPTOR, &verf, data, data_len + ss_padding_len); - smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0); + smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, + &verf, &outgoing_pdu, 0); p->netsec_auth.seq_num++; } @@ -1339,7 +1340,7 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) auth_len = p->hdr.auth_len; - if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + if (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) { DEBUG(0,("Incorrect auth_len %d.\n", auth_len )); return False; } @@ -1384,7 +1385,9 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) return False; } - if(!smb_io_rpc_auth_netsec_chk("", &netsec_chk, rpc_in, 0)) { + if(!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, + &netsec_chk, rpc_in, 0)) + { DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n")); return False; } -- cgit From 5f9af6df053f6608fba9a9c17a4945189de38a58 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Jul 2004 09:46:38 +0000 Subject: r1338: A netlogon schannel failure is a normal event with XP clients. They cache the netlogon session key and try to reconnect using that key. This fails with a restarted smbd, we expect another serverauth2. XP falls back immediately. Make the corresponding messages a debug level 3, not 0 to not flood log.smbd. Volker (This used to be commit 4fda68a62fec6c1e95d5176bc5d06bd49da6f358) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 13d894d2d8..36929150e5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1397,7 +1397,7 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) SENDER_IS_INITIATOR, &netsec_chk, prs_data_p(rpc_in)+old_offset, data_len)) { - DEBUG(0,("failed to decode PDU\n")); + DEBUG(3,("failed to decode PDU\n")); return False; } -- cgit From cd87b3b972b39003def69671d8a3c6aaf51afd50 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Jul 2004 00:13:55 +0000 Subject: r1414: Memory leak fixes found by valgrind whilst checking the password history code. Error code paths were not freeing up some memory. Jeremy. (This used to be commit 7c4666e56c2c281e023c6483459cb9e8d4787d36) --- source3/rpc_server/srv_pipe.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 36929150e5..2232f0bc24 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -52,28 +52,28 @@ struct dcinfo last_dcinfo; static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) { - unsigned char *hash = p->ntlmssp_hash; - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - int ind; + unsigned char *hash = p->ntlmssp_hash; + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; - for( ind = 0; ind < len; ind++) { - unsigned char tc; - unsigned char t; + for( ind = 0; ind < len; ind++) { + unsigned char tc; + unsigned char t; - index_i++; - index_j += hash[index_i]; + index_i++; + index_j += hash[index_i]; - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; - } + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } - hash[256] = index_i; - hash[257] = index_j; + hash[256] = index_i; + hash[257] = index_j; } /******************************************************************* -- cgit From ba3aaa96adc078adb2e99f6cd188edc264df236d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Jul 2004 00:59:06 +0000 Subject: r1415: One more memory leak, found by valgrind.. Jeremy. (This used to be commit 8cfaf575e5161e8307b0a53bd44e84c633e85aed) --- source3/rpc_server/srv_pipe.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 2232f0bc24..c5b0b5694d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -501,6 +501,9 @@ succeeded authentication on named pipe %s, but session key was of incorrect leng * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ + if (p->session_key.data) { + data_blob_free(&p->session_key); + } p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length); p->pipe_user.uid = server_info->uid; -- cgit From 9d0783bf211dffe58845b36b0669f05bf8bf25b5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jul 2004 04:36:01 +0000 Subject: r1492: Rework our random number generation system. On systems with /dev/urandom, this avoids a change to secrets.tdb for every fork(). For other systems, we now only re-seed after a fork, and on startup. No need to do it per-operation. This removes the 'need_reseed' parameter from generate_random_buffer(). Andrew Bartlett (This used to be commit 36741d3cf53a7bd17d361251f2bb50851cdb035f) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index c5b0b5694d..bcf5eb533f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1097,7 +1097,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) RPC_AUTH_VERIFIER auth_verifier; RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal; - generate_random_buffer(p->challenge, 8, False); + generate_random_buffer(p->challenge, 8); /*** Authentication info ***/ -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/rpc_server/srv_pipe.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index bcf5eb533f..01e91ce6c5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -775,7 +775,7 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, int n_fns = 0; PIPE_RPC_FNS *context_fns; - if ( !(context_fns = malloc(sizeof(PIPE_RPC_FNS))) ) { + if ( !(context_fns = SMB_MALLOC_P(PIPE_RPC_FNS)) ) { DEBUG(0,("check_bind_req: malloc() failed!\n")); return False; } @@ -831,8 +831,8 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s /* We use a temporary variable because this call can fail and rpc_lookup will still be valid afterwards. It could then succeed if called again later */ - rpc_entry = realloc(rpc_lookup, - ++rpc_lookup_size*sizeof(struct rpc_table)); + rpc_lookup_size++; + rpc_entry = SMB_REALLOC_ARRAY(rpc_lookup, struct rpc_table, rpc_lookup_size); if (NULL == rpc_entry) { rpc_lookup_size--; DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n")); @@ -843,13 +843,10 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s rpc_entry = rpc_lookup + (rpc_lookup_size - 1); ZERO_STRUCTP(rpc_entry); - rpc_entry->pipe.clnt = strdup(clnt); - rpc_entry->pipe.srv = strdup(srv); - rpc_entry->cmds = realloc(rpc_entry->cmds, - (rpc_entry->n_cmds + size) * - sizeof(struct api_struct)); - memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds, - size * sizeof(struct api_struct)); + rpc_entry->pipe.clnt = SMB_STRDUP(clnt); + rpc_entry->pipe.srv = SMB_STRDUP(srv); + rpc_entry->cmds = SMB_REALLOC_ARRAY(rpc_entry->cmds, struct api_struct, rpc_entry->n_cmds + size); + memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds, size * sizeof(struct api_struct)); rpc_entry->n_cmds += size; return NT_STATUS_OK; @@ -1585,9 +1582,7 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, if ((DEBUGLEVEL >= 10) && (prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) { size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data); - char *data; - - data = malloc(data_len); + char *data = SMB_MALLOC(data_len); DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n")); if (data) { -- cgit From 5d1cb8e79edea9e8581d3c2c9dd297310cd9a98c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Mar 2005 23:26:33 +0000 Subject: r6014: rather large change set.... pulling back all recent rpc changes from trunk into 3.0. I've tested a compile and so don't think I've missed any files. But if so, just mail me and I'll clean backup in a couple of hours. Changes include \winreg, \eventlog, \svcctl, and general parse_misc.c updates. I am planning on bracketing the event code with an #ifdef ENABLE_EVENTLOG until I finish merging Marcin's changes (very soon). (This used to be commit 4e0ac63c36527cd8c52ef720cae17e84f67e7221) --- source3/rpc_server/srv_pipe.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 01e91ce6c5..ab21f60902 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -765,6 +765,7 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, for ( i=0; pipe_names[i].client_pipe; i++ ) { + DEBUG(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0) @@ -1631,6 +1632,12 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_NETDFS: netdfs_get_pipe_fns( &cmds, &n_cmds ); break; + case PI_SVCCTL: + svcctl_get_pipe_fns( &cmds, &n_cmds ); + break; + case PI_EVENTLOG: + eventlog_get_pipe_fns( &cmds, &n_cmds ); + break; #ifdef DEVELOPER case PI_ECHO: echo_get_pipe_fns( &cmds, &n_cmds ); -- cgit From 978ca8486031e43754a3c23757f361bf3a85f335 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 6 Apr 2005 16:28:04 +0000 Subject: r6225: get rid of warnings from my compiler about nested externs (This used to be commit efea76ac71412f8622cd233912309e91b9ea52da) --- source3/rpc_server/srv_pipe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ab21f60902..ee6c42bd88 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -40,6 +40,9 @@ #include "includes.h" +extern struct pipe_id_info pipe_names[]; +extern struct current_user current_user; + #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -751,7 +754,6 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status) BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, RPC_IFACE* transfer, uint32 context_id) { - extern struct pipe_id_info pipe_names[]; char *pipe_name = p->name; int i=0; fstring pname; @@ -1427,7 +1429,6 @@ struct current_user *get_current_user(struct current_user *user, pipes_struct *p if (p->ntlmssp_auth_validated) { memcpy(user, &p->pipe_user, sizeof(struct current_user)); } else { - extern struct current_user current_user; memcpy(user, ¤t_user, sizeof(struct current_user)); } -- cgit From a01de91394f1723100bcd49870422e03f69afb7e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 3 Jun 2005 09:24:48 +0000 Subject: r7217: Only allow schannel connections if a successful Auth2 has been done before. Things tested: Domain join and subsequent interactive and network logon to NT4, W2kSP and XPSP2 workstations and a NT4 domain trusting us. Right now I've got problems with my W2k3 domain trusts. So this needs testing, although I'm really confident that this does not break. Volker (This used to be commit c25b4afda2b657b73a6215d3ff36461a36496ba3) --- source3/rpc_server/srv_pipe.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ee6c42bd88..ee4e803d9f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -52,6 +52,7 @@ extern struct current_user current_user; next. This is the way the netlogon schannel works. **************************************************************/ struct dcinfo last_dcinfo; +BOOL server_auth2_negotiated = False; static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) { @@ -975,6 +976,12 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) RPC_AUTH_NETSEC_NEG neg; struct netsec_auth_struct *a = &(p->netsec_auth); + if (!server_auth2_negotiated) { + DEBUG(0, ("Attempt to bind using schannel " + "without successful serverauth2\n")); + return False; + } + if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: " "Could not unmarshal SCHANNEL auth neg\n")); -- cgit From 04e07e8cc9d6615381e0501cd36cf7d78aeed189 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 8 Jun 2005 03:48:40 +0000 Subject: r7385: Rewrite the RPC bind parsing functions to follow the spec. I haven't yet tested this so I may have screwed this up - however it now follows the DCE spec. valgrinded tests to follow.... Jeremy. (This used to be commit 877e0a61f5821c89149b1403d08675dd7db8039e) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ee4e803d9f..9cf61d6357 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1068,15 +1068,15 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) unknown to NT4) Needed when adding entries to a DACL from NT5 - SK */ - if(check_bind_req(p, &hdr_rb.abstract, &hdr_rb.transfer, hdr_rb.context_id )) - { + if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0], + hdr_rb.rpc_context[0].context_id )) { init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN, MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x0, 0x0, - &hdr_rb.transfer); + &hdr_rb.rpc_context[0].transfer[0]); } else { RPC_IFACE null_interface; ZERO_STRUCT(null_interface); -- cgit From 3b1f21b812be54d4ed334e23161e6d9a54f9977f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 18 Jun 2005 04:23:06 +0000 Subject: r7708: Hint from Luke Howard (thanks Luke). Ensure the schannel authenticator is 8 byte aligned, just like the NTLMSSP ones. Trying to fix 64-bit Windows domain logon. Jeremy. (This used to be commit 475d5a277db7709c1b0f851ce8ec4dd8de5e25fc) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9cf61d6357..30aacdc4c5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -162,7 +162,7 @@ BOOL create_next_pdu(pipes_struct *p) if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) { p->hdr.flags |= RPC_FLG_LAST; - if ((auth_seal || auth_verify) && (data_len_left % 8)) { + if ((auth_seal || auth_verify || p->netsec_auth_validated) && (data_len_left % 8)) { ss_padding_len = 8 - (data_len_left % 8); DEBUG(10,("create_next_pdu: adding sign/seal padding of %u\n", ss_padding_len )); -- cgit From 8b2b177a8e07e3a0cb00fbd7fdbafc8aeba5b204 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Jul 2005 20:25:04 +0000 Subject: r8805: Merge a duplicate struct. Get ready to support SPNEGO rpc binds. Jeremy. (This used to be commit fd6e342746edfda2f25df1ae0067d359b756e0cd) --- source3/rpc_server/srv_pipe.c | 125 ++++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 60 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 30aacdc4c5..70563d3029 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -582,9 +582,9 @@ BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p) return False; } - if (autha_info.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) { + if (autha_info.auth.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) { DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n", - (int)autha_info.auth_type, (int)autha_info.auth_level )); + (int)autha_info.auth.auth_type, (int)autha_info.auth.auth_level )); return False; } @@ -941,67 +941,72 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) return False; } - if(auth_info.auth_type == NTLMSSP_AUTH_TYPE) { - - if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to " - "unmarshall RPC_HDR_AUTH struct.\n")); - return False; - } - - if(!strequal(auth_verifier.signature, "NTLMSSP")) { - DEBUG(0,("api_pipe_bind_req: " - "auth_verifier.signature != NTLMSSP\n")); - return False; - } - - if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { - DEBUG(0,("api_pipe_bind_req: " - "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", - auth_verifier.msg_type)); - return False; - } - - if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: " - "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); - return False; - } - - p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; - p->ntlmssp_auth_requested = True; - - } else if (auth_info.auth_type == NETSEC_AUTH_TYPE) { - - RPC_AUTH_NETSEC_NEG neg; - struct netsec_auth_struct *a = &(p->netsec_auth); - - if (!server_auth2_negotiated) { - DEBUG(0, ("Attempt to bind using schannel " - "without successful serverauth2\n")); - return False; + switch(auth_info.auth_type) { + case NTLMSSP_AUTH_TYPE: + + if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to " + "unmarshall RPC_HDR_AUTH struct.\n")); + return False; + } + + if(!strequal(auth_verifier.signature, "NTLMSSP")) { + DEBUG(0,("api_pipe_bind_req: " + "auth_verifier.signature != NTLMSSP\n")); + return False; + } + + if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { + DEBUG(0,("api_pipe_bind_req: " + "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", + auth_verifier.msg_type)); + return False; + } + + if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: " + "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); + return False; + } + + p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; + p->ntlmssp_auth_requested = True; + break; + + case NETSEC_AUTH_TYPE: + { + RPC_AUTH_NETSEC_NEG neg; + struct netsec_auth_struct *a = &(p->netsec_auth); + + if (!server_auth2_negotiated) { + DEBUG(0, ("Attempt to bind using schannel " + "without successful serverauth2\n")); + return False; + } + + if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: " + "Could not unmarshal SCHANNEL auth neg\n")); + return False; + } + + p->netsec_auth_validated = True; + + memset(a->sess_key, 0, sizeof(a->sess_key)); + memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key)); + + a->seq_num = 0; + + DEBUG(10,("schannel auth: domain [%s] myname [%s]\n", + neg.domain, neg.myname)); + break; } - if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: " - "Could not unmarshal SCHANNEL auth neg\n")); + case SPNEGO_AUTH_TYPE: + default: + DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", + auth_info.auth_type )); return False; - } - - p->netsec_auth_validated = True; - - memset(a->sess_key, 0, sizeof(a->sess_key)); - memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key)); - - a->seq_num = 0; - - DEBUG(10,("schannel auth: domain [%s] myname [%s]\n", - neg.domain, neg.myname)); - - } else { - DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", - auth_info.auth_type )); - return False; } } -- cgit From 777422836ccfd3f2cafa19537534b970bc96fc2b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Aug 2005 00:25:52 +0000 Subject: r9080: If we don't understand the auth, bind nak not pdu fault. Should fix usermgr on W2K3 SP1. Jeremy. (This used to be commit 592ec9fbffc704761c6b29cfc795cf3af7d5fe38) --- source3/rpc_server/srv_pipe.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 70563d3029..63e8d2f5cd 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -666,7 +666,7 @@ static BOOL setup_bind_nak(pipes_struct *p) if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) { prs_mem_free(&outgoing_rpc); - return False; + return False; } p->out_data.data_sent_length = 0; @@ -896,11 +896,9 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) if (i == rpc_lookup_size) { if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { - DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", - p->name )); - if(!setup_bind_nak(p)) - return False; - return True; + DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", + p->name )); + return setup_bind_nak(p); } for (i = 0; i < rpc_lookup_size; i++) { @@ -921,7 +919,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) /* decode the bind request */ if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); - return False; + return setup_bind_nak(p); } /* @@ -938,7 +936,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); - return False; + return setup_bind_nak(p); } switch(auth_info.auth_type) { @@ -947,26 +945,26 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: unable to " "unmarshall RPC_HDR_AUTH struct.\n")); - return False; + return setup_bind_nak(p); } if(!strequal(auth_verifier.signature, "NTLMSSP")) { DEBUG(0,("api_pipe_bind_req: " "auth_verifier.signature != NTLMSSP\n")); - return False; + return setup_bind_nak(p); } if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { DEBUG(0,("api_pipe_bind_req: " "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", auth_verifier.msg_type)); - return False; + return setup_bind_nak(p); } if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: " "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); - return False; + return setup_bind_nak(p); } p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; @@ -981,13 +979,13 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) if (!server_auth2_negotiated) { DEBUG(0, ("Attempt to bind using schannel " "without successful serverauth2\n")); - return False; + return setup_bind_nak(p); } if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: " "Could not unmarshal SCHANNEL auth neg\n")); - return False; + return setup_bind_nak(p); } p->netsec_auth_validated = True; @@ -1006,7 +1004,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) default: DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", auth_info.auth_type )); - return False; + return setup_bind_nak(p); } } -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/rpc_server/srv_pipe.c | 2001 +++++++++++++++++++++++++++-------------- 1 file changed, 1309 insertions(+), 692 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 63e8d2f5cd..ba6d9704e8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1,11 +1,7 @@ /* * Unix SMB/CIFS implementation. * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1998 - * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1997-1998, - * Copyright (C) Jeremy Allison 1999, - * Copyright (C) Jim McDonough 2003. + * Almost completely rewritten by (C) Jeremy Allison 2005. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,12 +26,6 @@ * and DCE/RPC, while minimising the amount of mallocs, unnecessary * data copies, and network traffic. * - * in this version, which takes a "let's learn what's going on and - * get something running" approach, there is additional network - * traffic generated, but the code should be easier to understand... - * - * ... if you read the docs. or stare at packets for weeks on end. - * */ #include "includes.h" @@ -51,52 +41,38 @@ extern struct current_user current_user; We need to transfer the session key from one rpc bind to the next. This is the way the netlogon schannel works. **************************************************************/ + struct dcinfo last_dcinfo; BOOL server_auth2_negotiated = False; -static void NTLMSSPcalc_p( pipes_struct *p, unsigned char *data, int len) +static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) { - unsigned char *hash = p->ntlmssp_hash; - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - int ind; - - for( ind = 0; ind < len; ind++) { - unsigned char tc; - unsigned char t; + AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state; - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; + if (a) { + auth_ntlmssp_end(&a); } - - hash[256] = index_i; - hash[257] = index_j; + auth->a_u.auth_ntlmssp_state = NULL; } /******************************************************************* Generate the next PDU to be returned from the data in p->rdata. - We cheat here as this function doesn't handle the special auth - footers of the authenticated bind response reply. + Handle NTLMSSP. ********************************************************************/ -BOOL create_next_pdu(pipes_struct *p) +static BOOL create_next_pdu_ntlmssp(pipes_struct *p) { RPC_HDR_RESP hdr_resp; - BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0); - BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0); uint32 ss_padding_len = 0; - uint32 data_len; uint32 data_space_available; uint32 data_len_left; + uint32 data_len; prs_struct outgoing_pdu; - uint32 data_pos; + NTSTATUS status; + DATA_BLOB auth_blob; + RPC_HDR_AUTH auth_info; + uint8 auth_type, auth_level; + AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state; /* * If we're in the fault state, keep returning fault PDU's until @@ -124,18 +100,6 @@ BOOL create_next_pdu(pipes_struct *p) * Work out how much we can fit in a single PDU. */ - data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; - if(p->ntlmssp_auth_validated) { - data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); - } else if(p->netsec_auth_validated) { - data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN); - } - - /* - * The amount we send is the minimum of the available - * space and the amount left to send. - */ - data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length; /* @@ -143,10 +107,18 @@ BOOL create_next_pdu(pipes_struct *p) */ if(!data_len_left) { - DEBUG(0,("create_next_pdu: no data left to send !\n")); + DEBUG(0,("create_next_pdu_ntlmssp: no data left to send !\n")); return False; } + data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - + RPC_HDR_AUTH_LEN - NTLMSSP_SIG_SIZE; + + /* + * The amount we send is the minimum of the available + * space and the amount left to send. + */ + data_len = MIN(data_len_left, data_space_available); /* @@ -162,9 +134,9 @@ BOOL create_next_pdu(pipes_struct *p) if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) { p->hdr.flags |= RPC_FLG_LAST; - if ((auth_seal || auth_verify || p->netsec_auth_validated) && (data_len_left % 8)) { + if (data_len_left % 8) { ss_padding_len = 8 - (data_len_left % 8); - DEBUG(10,("create_next_pdu: adding sign/seal padding of %u\n", + DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n", ss_padding_len )); } } @@ -173,20 +145,11 @@ BOOL create_next_pdu(pipes_struct *p) * Set up the header lengths. */ - if (p->ntlmssp_auth_validated) { - p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len + - RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN; - p->hdr.auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; - } else if (p->netsec_auth_validated) { - p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + - data_len + ss_padding_len + - RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; - p->hdr.auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; - } else { - p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; - p->hdr.auth_len = 0; - } + RPC_HDR_AUTH_LEN + NTLMSSP_SIG_SIZE; + p->hdr.auth_len = NTLMSSP_SIG_SIZE; + /* * Init the parse struct to point at the outgoing @@ -198,127 +161,105 @@ BOOL create_next_pdu(pipes_struct *p) /* Store the header in the data stream. */ if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR.\n")); + DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR.\n")); prs_mem_free(&outgoing_pdu); return False; } if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_RESP.\n")); + DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_RESP.\n")); prs_mem_free(&outgoing_pdu); return False; } - /* Store the current offset. */ - data_pos = prs_offset(&outgoing_pdu); - /* Copy the data into the PDU. */ if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) { - DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len)); + DEBUG(0,("create_next_pdu_ntlmssp: failed to copy %u bytes of data.\n", (unsigned int)data_len)); prs_mem_free(&outgoing_pdu); return False; } /* Copy the sign/seal padding data. */ if (ss_padding_len) { - char pad[8]; + unsigned char pad[8]; + memset(pad, '\0', 8); if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) { - DEBUG(0,("create_next_pdu: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len)); + DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes of pad data.\n", + (unsigned int)ss_padding_len)); prs_mem_free(&outgoing_pdu); return False; } } - if (p->ntlmssp_auth_validated) { - /* - * NTLMSSP processing. Mutually exclusive with Schannel. - */ - uint32 crc32 = 0; - char *data; - - DEBUG(5,("create_next_pdu: sign: %s seal: %s data %d auth %d\n", - BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len + ss_padding_len, p->hdr.auth_len)); - - /* - * Set data to point to where we copied the data into. - */ - data = prs_data_p(&outgoing_pdu) + data_pos; + /* Now write out the auth header and null blob. */ + if (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) { + auth_type = RPC_NTLMSSP_AUTH_TYPE; + } else { + auth_type = RPC_SPNEGO_AUTH_TYPE; + } + if (p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY) { + auth_level = RPC_AUTH_LEVEL_PRIVACY; + } else { + auth_level = RPC_AUTH_LEVEL_INTEGRITY; + } - if (auth_seal) { - crc32 = crc32_calc_buffer(data, data_len + ss_padding_len); - NTLMSSPcalc_p(p, (uchar*)data, data_len + ss_padding_len); - } + init_rpc_hdr_auth(&auth_info, auth_type, auth_level, ss_padding_len, 1 /* context id. */); + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu_ntlmssp: failed to marshall RPC_HDR_AUTH.\n")); + prs_mem_free(&outgoing_pdu); + return False; + } - if (auth_seal || auth_verify) { - RPC_HDR_AUTH auth_info; + /* Generate the sign blob. */ - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, - auth_seal ? RPC_PIPE_AUTH_SEAL_LEVEL : RPC_PIPE_AUTH_SIGN_LEVEL, - (auth_verify ? ss_padding_len : 0), (auth_verify ? 1 : 0)); - if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); + switch (p->auth.auth_level) { + case PIPE_AUTH_LEVEL_PRIVACY: + /* Data portion is encrypted. */ + status = ntlmssp_seal_packet(a->ntlmssp_state, + prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + data_len + ss_padding_len, + prs_data_p(&outgoing_pdu), + (size_t)prs_offset(&outgoing_pdu), + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&auth_blob); prs_mem_free(&outgoing_pdu); return False; } - } - - if (auth_verify) { - RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; - char *auth_data = prs_data_p(&outgoing_pdu); - - p->ntlmssp_seq_num++; - init_rpc_auth_ntlmssp_chk(&ntlmssp_chk, NTLMSSP_SIGN_VERSION, - crc32, p->ntlmssp_seq_num++); - auth_data = prs_data_p(&outgoing_pdu) + prs_offset(&outgoing_pdu) + 4; - if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_AUTH_NTLMSSP_CHK.\n")); + break; + case PIPE_AUTH_LEVEL_INTEGRITY: + /* Data is signed. */ + status = ntlmssp_sign_packet(a->ntlmssp_state, + prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + data_len + ss_padding_len, + prs_data_p(&outgoing_pdu), + (size_t)prs_offset(&outgoing_pdu), + &auth_blob); + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&auth_blob); prs_mem_free(&outgoing_pdu); return False; } - NTLMSSPcalc_p(p, (uchar*)auth_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); - } - } else if (p->netsec_auth_validated) { - /* - * Schannel processing. Mutually exclusive with NTLMSSP. - */ - int auth_type, auth_level; - char *data; - RPC_HDR_AUTH auth_info; - - RPC_AUTH_NETSEC_CHK verf; - prs_struct rverf; - prs_struct rauth; - - data = prs_data_p(&outgoing_pdu) + data_pos; - /* Check it's the type of reply we were expecting to decode */ - - get_auth_type_level(p->netsec_auth.auth_flags, &auth_type, &auth_level); - init_rpc_hdr_auth(&auth_info, auth_type, auth_level, - ss_padding_len, 1); - - if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { - DEBUG(0,("create_next_pdu: failed to marshall RPC_HDR_AUTH.\n")); + break; + default: prs_mem_free(&outgoing_pdu); return False; - } - - prs_init(&rverf, 0, p->mem_ctx, MARSHALL); - prs_init(&rauth, 0, p->mem_ctx, MARSHALL); - - netsec_encode(&p->netsec_auth, - p->netsec_auth.auth_flags, - SENDER_IS_ACCEPTOR, - &verf, data, data_len + ss_padding_len); - - smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, - &verf, &outgoing_pdu, 0); + } - p->netsec_auth.seq_num++; + /* Append the auth blob. */ + if (!prs_copy_data_in(&outgoing_pdu, auth_blob.data, NTLMSSP_SIG_SIZE)) { + DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes auth blob.\n", + (unsigned int)NTLMSSP_SIG_SIZE)); + data_blob_free(&auth_blob); + prs_mem_free(&outgoing_pdu); + return False; } + data_blob_free(&auth_blob); + /* * Setup the counts for this PDU. */ @@ -332,292 +273,501 @@ BOOL create_next_pdu(pipes_struct *p) } /******************************************************************* - Process an NTLMSSP authentication response. - If this function succeeds, the user has been authenticated - and their domain, name and calling workstation stored in - the pipe struct. - The initial challenge is stored in p->challenge. - *******************************************************************/ + Generate the next PDU to be returned from the data in p->rdata. + Return an schannel authenticated fragment. + ********************************************************************/ -static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp) +static BOOL create_next_pdu_schannel(pipes_struct *p) { - uchar lm_owf[24]; - uchar nt_owf[128]; - int nt_pw_len; - int lm_pw_len; - fstring user_name; - fstring domain; - fstring wks; + RPC_HDR_RESP hdr_resp; + uint32 ss_padding_len = 0; + uint32 data_len; + uint32 data_space_available; + uint32 data_len_left; + prs_struct outgoing_pdu; + uint32 data_pos; - NTSTATUS nt_status; + /* + * If we're in the fault state, keep returning fault PDU's until + * the pipe gets closed. JRA. + */ - struct auth_context *auth_context = NULL; - auth_usersupplied_info *user_info = NULL; - auth_serversupplied_info *server_info = NULL; + if(p->fault_state) { + setup_fault_pdu(p, NT_STATUS(0x1c010002)); + return True; + } - DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n")); + memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); - memset(p->user_name, '\0', sizeof(p->user_name)); - memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); - memset(p->domain, '\0', sizeof(p->domain)); - memset(p->wks, '\0', sizeof(p->wks)); + /* Change the incoming request header to a response. */ + p->hdr.pkt_type = RPC_RESPONSE; - /* Set up for non-authenticated user. */ - delete_nt_token(&p->pipe_user.nt_user_token); - p->pipe_user.ngroups = 0; - SAFE_FREE( p->pipe_user.groups); + /* Set up rpc header flags. */ + if (p->out_data.data_sent_length == 0) { + p->hdr.flags = RPC_FLG_FIRST; + } else { + p->hdr.flags = 0; + } - /* - * Setup an empty password for a guest user. + /* + * Work out how much we can fit in a single PDU. */ + data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length; + /* - * We always negotiate UNICODE. + * Ensure there really is data left to send. */ - if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { - rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 ); - rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0); - rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0); - } else { - pull_ascii_fstring(user_name, ntlmssp_resp->user); - pull_ascii_fstring(domain, ntlmssp_resp->domain); - pull_ascii_fstring(wks, ntlmssp_resp->wks); + if(!data_len_left) { + DEBUG(0,("create_next_pdu_schannel: no data left to send !\n")); + return False; } - DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks)); + data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - + RPC_HDR_AUTH_LEN - RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN; - nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len); - lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len); - - memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf)); - memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len); + /* + * The amount we send is the minimum of the available + * space and the amount left to send. + */ -#ifdef DEBUG_PASSWORD - DEBUG(100,("lm, nt owfs, chal\n")); - dump_data(100, (char *)lm_owf, sizeof(lm_owf)); - dump_data(100, (char *)nt_owf, nt_pw_len); - dump_data(100, (char *)p->challenge, 8); -#endif + data_len = MIN(data_len_left, data_space_available); /* - * Allow guest access. Patch from Shirish Kalele . + * Set up the alloc hint. This should be the data left to + * send. */ - if (*user_name) { - - /* - * Do the length checking only if user is not NULL. - */ + hdr_resp.alloc_hint = data_len_left; - if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_usr.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_domain.str_str_len == 0) - return False; - if (ntlmssp_resp->hdr_wks.str_str_len == 0) - return False; + /* + * Work out if this PDU will be the last. + */ + if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) { + p->hdr.flags |= RPC_FLG_LAST; + if (data_len_left % 8) { + ss_padding_len = 8 - (data_len_left % 8); + DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n", + ss_padding_len )); + } } - - make_auth_context_fixed(&auth_context, (uchar*)p->challenge); - if (!make_user_info_netlogon_network(&user_info, - user_name, domain, wks, - lm_owf, lm_pw_len, - nt_owf, nt_pw_len)) { - DEBUG(0,("make_user_info_netlogon_network failed! Failing authenticaion.\n")); - return False; - } - - nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); - - (auth_context->free)(&auth_context); - free_user_info(&user_info); - - p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status); - - if (!p->ntlmssp_auth_validated) { - DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \ -failed authentication on named pipe %s.\n", domain, user_name, wks, p->name )); - free_server_info(&server_info); - return False; - } + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len + + RPC_HDR_AUTH_LEN + RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN; + p->hdr.auth_len = RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN; /* - * Set up the sign/seal data. + * Init the parse struct to point at the outgoing + * data. */ - if (server_info->lm_session_key.length != 16) { - DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \ -succeeded authentication on named pipe %s, but session key was of incorrect length [%u].\n", - domain, user_name, wks, p->name, server_info->lm_session_key.length)); - free_server_info(&server_info); - return False; - } else { - uchar p24[24]; - NTLMSSPOWFencrypt(server_info->lm_session_key.data, lm_owf, p24); - { - unsigned char j = 0; - int ind; - - unsigned char k2[8]; + prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); - memcpy(k2, p24, 5); - k2[5] = 0xe5; - k2[6] = 0x38; - k2[7] = 0xb0; + /* Store the header in the data stream. */ + if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR.\n")); + prs_mem_free(&outgoing_pdu); + return False; + } - for (ind = 0; ind < 256; ind++) - p->ntlmssp_hash[ind] = (unsigned char)ind; + if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_RESP.\n")); + prs_mem_free(&outgoing_pdu); + return False; + } - for( ind = 0; ind < 256; ind++) { - unsigned char tc; + /* Store the current offset. */ + data_pos = prs_offset(&outgoing_pdu); - j += (p->ntlmssp_hash[ind] + k2[ind%8]); + /* Copy the data into the PDU. */ - tc = p->ntlmssp_hash[ind]; - p->ntlmssp_hash[ind] = p->ntlmssp_hash[j]; - p->ntlmssp_hash[j] = tc; - } + if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) { + DEBUG(0,("create_next_pdu_schannel: failed to copy %u bytes of data.\n", (unsigned int)data_len)); + prs_mem_free(&outgoing_pdu); + return False; + } - p->ntlmssp_hash[256] = 0; - p->ntlmssp_hash[257] = 0; + /* Copy the sign/seal padding data. */ + if (ss_padding_len) { + char pad[8]; + memset(pad, '\0', 8); + if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) { + DEBUG(0,("create_next_pdu_schannel: failed to add %u bytes of pad data.\n", (unsigned int)ss_padding_len)); + prs_mem_free(&outgoing_pdu); + return False; } + } - dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash, - sizeof(p->ntlmssp_hash)); - -/* NTLMSSPhash(p->ntlmssp_hash, p24); */ - p->ntlmssp_seq_num = 0; + { + /* + * Schannel processing. + */ + char *data; + RPC_HDR_AUTH auth_info; + RPC_AUTH_SCHANNEL_CHK verf; - } + data = prs_data_p(&outgoing_pdu) + data_pos; + /* Check it's the type of reply we were expecting to decode */ - fstrcpy(p->user_name, user_name); - fstrcpy(p->pipe_user_name, server_info->unix_name); - fstrcpy(p->domain, domain); - fstrcpy(p->wks, wks); + init_rpc_hdr_auth(&auth_info, + RPC_SCHANNEL_AUTH_TYPE, + p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY ? + RPC_AUTH_LEVEL_PRIVACY : RPC_AUTH_LEVEL_INTEGRITY, + ss_padding_len, 1); - /* - * Store the UNIX credential data (uid/gid pair) in the pipe structure. - */ + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu_schannel: failed to marshall RPC_HDR_AUTH.\n")); + prs_mem_free(&outgoing_pdu); + return False; + } - if (p->session_key.data) { - data_blob_free(&p->session_key); - } - p->session_key = data_blob(server_info->lm_session_key.data, server_info->lm_session_key.length); + schannel_encode(p->auth.a_u.schannel_auth, + p->auth.auth_level, + SENDER_IS_ACCEPTOR, + &verf, data, data_len + ss_padding_len); - p->pipe_user.uid = server_info->uid; - p->pipe_user.gid = server_info->gid; - - p->pipe_user.ngroups = server_info->n_groups; - if (p->pipe_user.ngroups) { - if (!(p->pipe_user.groups = memdup(server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) { - DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); - free_server_info(&server_info); + if (!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, + &verf, &outgoing_pdu, 0)) { + prs_mem_free(&outgoing_pdu); return False; } - } - if (server_info->ptok) - p->pipe_user.nt_user_token = dup_nt_token(server_info->ptok); - else { - DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); - p->pipe_user.nt_user_token = NULL; - free_server_info(&server_info); - return False; + p->auth.a_u.schannel_auth->seq_num++; } - p->ntlmssp_auth_validated = True; + /* + * Setup the counts for this PDU. + */ + + p->out_data.data_sent_length += data_len; + p->out_data.current_pdu_len = p->hdr.frag_len; + p->out_data.current_pdu_sent = 0; - free_server_info(&server_info); + prs_mem_free(&outgoing_pdu); return True; } /******************************************************************* - The switch table for the pipe names and the functions to handle them. - *******************************************************************/ + Generate the next PDU to be returned from the data in p->rdata. + No authentication done. +********************************************************************/ -struct rpc_table +static BOOL create_next_pdu_noauth(pipes_struct *p) { - struct - { - const char *clnt; - const char *srv; - } pipe; - struct api_struct *cmds; - int n_cmds; -}; + RPC_HDR_RESP hdr_resp; + uint32 data_len; + uint32 data_space_available; + uint32 data_len_left; + prs_struct outgoing_pdu; -static struct rpc_table *rpc_lookup; -static int rpc_lookup_size; + /* + * If we're in the fault state, keep returning fault PDU's until + * the pipe gets closed. JRA. + */ -/******************************************************************* - This is the client reply to our challenge for an authenticated - bind request. The challenge we sent is in p->challenge. -*******************************************************************/ + if(p->fault_state) { + setup_fault_pdu(p, NT_STATUS(0x1c010002)); + return True; + } -BOOL api_pipe_bind_auth_resp(pipes_struct *p, prs_struct *rpc_in_p) -{ - RPC_HDR_AUTHA autha_info; - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; + memset((char *)&hdr_resp, '\0', sizeof(hdr_resp)); - DEBUG(5,("api_pipe_bind_auth_resp: decode request. %d\n", __LINE__)); + /* Change the incoming request header to a response. */ + p->hdr.pkt_type = RPC_RESPONSE; - if (p->hdr.auth_len == 0) { - DEBUG(0,("api_pipe_bind_auth_resp: No auth field sent !\n")); - return False; + /* Set up rpc header flags. */ + if (p->out_data.data_sent_length == 0) { + p->hdr.flags = RPC_FLG_FIRST; + } else { + p->hdr.flags = 0; } /* - * Decode the authentication verifier response. + * Work out how much we can fit in a single PDU. + */ + + data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length; + + /* + * Ensure there really is data left to send. + */ + + if(!data_len_left) { + DEBUG(0,("create_next_pdu_noath: no data left to send !\n")); + return False; + } + + data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + + /* + * The amount we send is the minimum of the available + * space and the amount left to send. + */ + + data_len = MIN(data_len_left, data_space_available); + + /* + * Set up the alloc hint. This should be the data left to + * send. + */ + + hdr_resp.alloc_hint = data_len_left; + + /* + * Work out if this PDU will be the last. */ - if(!smb_io_rpc_hdr_autha("", &autha_info, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_HDR_AUTHA failed.\n")); + if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) { + p->hdr.flags |= RPC_FLG_LAST; + } + + /* + * Set up the header lengths. + */ + + p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; + p->hdr.auth_len = 0; + + /* + * Init the parse struct to point at the outgoing + * data. + */ + + prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); + + /* Store the header in the data stream. */ + if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu_noath: failed to marshall RPC_HDR.\n")); + prs_mem_free(&outgoing_pdu); return False; } - if (autha_info.auth.auth_type != NTLMSSP_AUTH_TYPE || autha_info.auth.auth_level != RPC_PIPE_AUTH_SEAL_LEVEL) { - DEBUG(0,("api_pipe_bind_auth_resp: incorrect auth type (%d) or level (%d).\n", - (int)autha_info.auth.auth_type, (int)autha_info.auth.auth_level )); + if(!smb_io_rpc_hdr_resp("resp", &hdr_resp, &outgoing_pdu, 0)) { + DEBUG(0,("create_next_pdu_noath: failed to marshall RPC_HDR_RESP.\n")); + prs_mem_free(&outgoing_pdu); return False; } - if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_auth_resp: unmarshall of RPC_AUTH_VERIFIER failed.\n")); + /* Copy the data into the PDU. */ + + if(!prs_append_some_prs_data(&outgoing_pdu, &p->out_data.rdata, p->out_data.data_sent_length, data_len)) { + DEBUG(0,("create_next_pdu_noauth: failed to copy %u bytes of data.\n", (unsigned int)data_len)); + prs_mem_free(&outgoing_pdu); return False; } /* - * Ensure this is a NTLMSSP_AUTH packet type. + * Setup the counts for this PDU. */ - if (!rpc_auth_verifier_chk(&auth_verifier, "NTLMSSP", NTLMSSP_AUTH)) { - DEBUG(0,("api_pipe_bind_auth_resp: rpc_auth_verifier_chk failed.\n")); + p->out_data.data_sent_length += data_len; + p->out_data.current_pdu_len = p->hdr.frag_len; + p->out_data.current_pdu_sent = 0; + + prs_mem_free(&outgoing_pdu); + return True; +} + +/******************************************************************* + Generate the next PDU to be returned from the data in p->rdata. +********************************************************************/ + +BOOL create_next_pdu(pipes_struct *p) +{ + switch(p->auth.auth_level) { + case PIPE_AUTH_LEVEL_NONE: + case PIPE_AUTH_LEVEL_CONNECT: + /* This is incorrect for auth level connect. Fixme. JRA */ + return create_next_pdu_noauth(p); + + default: + switch(p->auth.auth_type) { + case PIPE_AUTH_TYPE_NTLMSSP: + case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP: + return create_next_pdu_ntlmssp(p); + case PIPE_AUTH_TYPE_SCHANNEL: + return create_next_pdu_schannel(p); + default: + break; + } + } + + DEBUG(0,("create_next_pdu: invalid internal auth level %u / type %u", + (unsigned int)p->auth.auth_level, + (unsigned int)p->auth.auth_type)); + return False; +} + +/******************************************************************* + Process an NTLMSSP authentication response. + If this function succeeds, the user has been authenticated + and their domain, name and calling workstation stored in + the pipe struct. +*******************************************************************/ + +static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) +{ + DATA_BLOB reply; + NTSTATUS status; + AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state; + + DEBUG(5,("pipe_ntlmssp_verify_final: checking user details\n")); + + ZERO_STRUCT(reply); + + memset(p->user_name, '\0', sizeof(p->user_name)); + memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); + memset(p->domain, '\0', sizeof(p->domain)); + memset(p->wks, '\0', sizeof(p->wks)); + + /* Set up for non-authenticated user. */ + delete_nt_token(&p->pipe_user.nt_user_token); + p->pipe_user.ngroups = 0; + SAFE_FREE( p->pipe_user.groups); + + status = auth_ntlmssp_update(a, *p_resp_blob, &reply); + + /* Don't generate a reply. */ + data_blob_free(&reply); + + if (!NT_STATUS_IS_OK(status)) { return False; } - if(!smb_io_rpc_auth_ntlmssp_resp("", &ntlmssp_resp, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_auth_resp: Failed to unmarshall RPC_AUTH_NTLMSSP_RESP.\n")); + fstrcpy(p->user_name, a->ntlmssp_state->user); + fstrcpy(p->pipe_user_name, a->server_info->unix_name); + fstrcpy(p->domain, a->ntlmssp_state->domain); + fstrcpy(p->wks, a->ntlmssp_state->workstation); + + DEBUG(5,("pipe_ntlmssp_verify_final: OK: user: %s domain: %s workstation: %s\n", + p->user_name, p->domain, p->wks)); + + /* + * Store the UNIX credential data (uid/gid pair) in the pipe structure. + */ + + p->pipe_user.uid = a->server_info->uid; + p->pipe_user.gid = a->server_info->gid; + + /* + * Copy the session key from the ntlmssp state. + */ + + data_blob_free(&p->session_key); + p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length); + if (!p->session_key.data) { return False; } + p->pipe_user.ngroups = a->server_info->n_groups; + if (p->pipe_user.ngroups) { + if (!(p->pipe_user.groups = memdup(a->server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) { + DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); + return False; + } + } + + if (a->server_info->ptok) { + p->pipe_user.nt_user_token = dup_nt_token(a->server_info->ptok); + } else { + DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); + p->pipe_user.nt_user_token = NULL; + return False; + } + + return True; +} + +/******************************************************************* + The switch table for the pipe names and the functions to handle them. +*******************************************************************/ + +struct rpc_table { + struct { + const char *clnt; + const char *srv; + } pipe; + struct api_struct *cmds; + int n_cmds; +}; + +static struct rpc_table *rpc_lookup; +static int rpc_lookup_size; + +/******************************************************************* + This is the "stage3" NTLMSSP response after a bind request and reply. +*******************************************************************/ + +BOOL api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p) +{ + RPC_HDR_AUTH auth_info; + uint32 pad; + DATA_BLOB blob; + + ZERO_STRUCT(blob); + + DEBUG(5,("api_pipe_bind_auth3: decode request. %d\n", __LINE__)); + + if (p->hdr.auth_len == 0) { + DEBUG(0,("api_pipe_bind_auth3: No auth field sent !\n")); + goto err; + } + + /* 4 bytes padding. */ + if (!prs_uint32("pad", rpc_in_p, 0, &pad)) { + DEBUG(0,("api_pipe_bind_auth3: unmarshall of 4 byte pad failed.\n")); + goto err; + } + + /* + * Decode the authentication verifier response. + */ + + if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_auth3: unmarshall of RPC_HDR_AUTH failed.\n")); + goto err; + } + + if (auth_info.auth_type != RPC_NTLMSSP_AUTH_TYPE) { + DEBUG(0,("api_pipe_bind_auth3: incorrect auth type (%u).\n", + (unsigned int)auth_info.auth_type )); + return False; + } + + blob = data_blob(NULL,p->hdr.auth_len); + + if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) { + DEBUG(0,("api_pipe_bind_auth3: Failed to pull %u bytes - the response blob.\n", + (unsigned int)p->hdr.auth_len )); + goto err; + } + /* * The following call actually checks the challenge/response data. * for correctness against the given DOMAIN\user name. */ - if (!api_pipe_ntlmssp_verify(p, &ntlmssp_resp)) - return False; + if (!pipe_ntlmssp_verify_final(p, &blob)) { + goto err; + } + + data_blob_free(&blob); + + p->pipe_bound = True; - p->pipe_bound = True -; return True; + + err: + + data_blob_free(&blob); + free_pipe_ntlmssp_auth_data(&p->auth); + p->auth.a_u.auth_ntlmssp_state = NULL; + + return False; } /******************************************************************* @@ -642,13 +792,12 @@ static BOOL setup_bind_nak(pipes_struct *p) prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); - /* * Initialize a bind_nak header. */ init_rpc_hdr(&nak_hdr, RPC_BINDNACK, RPC_FLG_FIRST | RPC_FLG_LAST, - p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0); + p->hdr.call_id, RPC_HEADER_LEN + sizeof(uint16), 0); /* * Marshall the header into the outgoing PDU. @@ -673,6 +822,11 @@ static BOOL setup_bind_nak(pipes_struct *p) p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); p->out_data.current_pdu_sent = 0; + if (p->auth.auth_data_free_func) { + (*p->auth.auth_data_free_func)(&p->auth); + } + p->auth.auth_level = PIPE_AUTH_LEVEL_NONE; + p->auth.auth_type = PIPE_AUTH_TYPE_NONE; p->pipe_bound = False; return True; @@ -766,15 +920,13 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ - for ( i=0; pipe_names[i].client_pipe; i++ ) - { + for ( i=0; pipe_names[i].client_pipe; i++ ) { DEBUG(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0) && (transfer->version == pipe_names[i].trans_syntax.version) - && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) ) - { + && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) ) { struct api_struct *fns = NULL; int n_fns = 0; PIPE_RPC_FNS *context_fns; @@ -800,8 +952,9 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, } } - if(pipe_names[i].client_pipe == NULL) + if(pipe_names[i].client_pipe == NULL) { return False; + } return True; } @@ -809,6 +962,7 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, /******************************************************************* Register commands to an RPC pipe *******************************************************************/ + NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size) { struct rpc_table *rpc_entry; @@ -856,6 +1010,365 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s return NT_STATUS_OK; } +/******************************************************************* + Handle a SPNEGO krb5 bind auth. +*******************************************************************/ + +static BOOL pipe_spnego_auth_bind_kerberos(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, + DATA_BLOB *psecblob, prs_struct *pout_auth) +{ + return False; +} + +/******************************************************************* + Handle the first part of a SPNEGO bind auth. +*******************************************************************/ + +static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p, + RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) +{ + DATA_BLOB blob; + DATA_BLOB secblob; + DATA_BLOB response; + DATA_BLOB chal; + char *OIDs[ASN1_MAX_OIDS]; + int i; + NTSTATUS status; + BOOL got_kerberos_mechanism = False; + AUTH_NTLMSSP_STATE *a = NULL; + RPC_HDR_AUTH auth_info; + + ZERO_STRUCT(secblob); + ZERO_STRUCT(chal); + ZERO_STRUCT(response); + + /* Grab the SPNEGO blob. */ + blob = data_blob(NULL,p->hdr.auth_len); + + if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) { + DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to pull %u bytes - the SPNEGO auth header.\n", + (unsigned int)p->hdr.auth_len )); + goto err; + } + + if (blob.data[0] != ASN1_APPLICATION(0)) { + goto err; + } + + /* parse out the OIDs and the first sec blob */ + if (!parse_negTokenTarg(blob, OIDs, &secblob)) { + DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to parse the security blob.\n")); + goto err; + } + + if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { + got_kerberos_mechanism = True; + } + + for (i=0;OIDs[i];i++) { + DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got OID %s\n", OIDs[i])); + SAFE_FREE(OIDs[i]); + } + DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length)); + + if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { + BOOL ret = pipe_spnego_auth_bind_kerberos(p, rpc_in_p, pauth_info, &secblob, pout_auth); + data_blob_free(&secblob); + data_blob_free(&blob); + return ret; + } + + if (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP && p->auth.a_u.auth_ntlmssp_state) { + /* Free any previous auth type. */ + free_pipe_ntlmssp_auth_data(&p->auth); + } + + /* Initialize the NTLM engine. */ + status = auth_ntlmssp_start(&a); + if (!NT_STATUS_IS_OK(status)) { + goto err; + } + + /* + * Pass the first security blob of data to it. + * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED + * which means we need another packet to complete the bind. + */ + + status = auth_ntlmssp_update(a, secblob, &chal); + + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n")); + goto err; + } + + /* Generate the response blob we need for step 2 of the bind. */ + response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP); + + /* Copy the blob into the pout_auth parse struct */ + init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); + if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { + DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of RPC_HDR_AUTH failed.\n")); + goto err; + } + + if (!prs_copy_data_in(pout_auth, response.data, response.length)) { + DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of data blob failed.\n")); + goto err; + } + + p->auth.a_u.auth_ntlmssp_state = a; + p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data; + p->auth.auth_type = PIPE_AUTH_TYPE_SPNEGO_NTLMSSP; + + data_blob_free(&blob); + data_blob_free(&secblob); + data_blob_free(&chal); + data_blob_free(&response); + + /* We can't set pipe_bound True yet - we need an RPC_ALTER_CONTEXT response packet... */ + return True; + + err: + + data_blob_free(&blob); + data_blob_free(&secblob); + data_blob_free(&chal); + data_blob_free(&response); + + p->auth.a_u.auth_ntlmssp_state = NULL; + + return False; +} + +/******************************************************************* + Handle the second part of a SPNEGO bind auth. +*******************************************************************/ + +static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p, + RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) +{ + DATA_BLOB spnego_blob, auth_blob, auth_reply; + AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state; + + ZERO_STRUCT(spnego_blob); + ZERO_STRUCT(auth_blob); + ZERO_STRUCT(auth_reply); + + if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) { + DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n")); + goto err; + } + + /* Grab the SPNEGO blob. */ + spnego_blob = data_blob(NULL,p->hdr.auth_len); + + if (!prs_copy_data_out(spnego_blob.data, rpc_in_p, p->hdr.auth_len)) { + DEBUG(0,("pipe_spnego_auth_bind_continue: Failed to pull %u bytes - the SPNEGO auth header.\n", + (unsigned int)p->hdr.auth_len )); + goto err; + } + + if (spnego_blob.data[0] != ASN1_CONTEXT(1)) { + DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob type.\n")); + goto err; + } + + if (!spnego_parse_auth(spnego_blob, &auth_blob)) { + DEBUG(0,("pipe_spnego_auth_bind_continue: invalid SPNEGO blob.\n")); + goto err; + } + + /* + * The following call actually checks the challenge/response data. + * for correctness against the given DOMAIN\user name. + */ + + if (!pipe_ntlmssp_verify_final(p, &auth_blob)) { + goto err; + } + + data_blob_free(&spnego_blob); + data_blob_free(&auth_blob); + data_blob_free(&auth_reply); + + p->pipe_bound = True; + + return True; + + err: + + data_blob_free(&spnego_blob); + data_blob_free(&auth_blob); + data_blob_free(&auth_reply); + + free_pipe_ntlmssp_auth_data(&p->auth); + p->auth.a_u.auth_ntlmssp_state = NULL; + + return False; +} + +/******************************************************************* + Handle an schannel bind auth. +*******************************************************************/ + +static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, + RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) +{ + RPC_HDR_AUTH auth_info; + RPC_AUTH_SCHANNEL_NEG neg; + RPC_AUTH_VERIFIER auth_verifier; + uint32 flags; + + if (!server_auth2_negotiated) { + DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n")); + return False; + } + + if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) { + DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n")); + return False; + } + + p->auth.a_u.schannel_auth = TALLOC_P(p->pipe_state_mem_ctx, struct schannel_auth_struct); + if (!p->auth.a_u.schannel_auth) { + return False; + } + + memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key)); + memcpy(p->auth.a_u.schannel_auth->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key)); + + p->auth.a_u.schannel_auth->seq_num = 0; + + /* + * JRA. Should we also copy the schannel session key into the pipe session key p->session_key + * here ? We do that for NTLMSPP, but the session key is already set up from the vuser + * struct of the person who opened the pipe. I need to test this further. JRA. + */ + + /* The client opens a second RPC NETLOGON pipe without + doing a auth2. The credentials for the schannel are + re-used from the auth2 the client did before. */ + p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo); + if (!p->dc) { + return False; + } + *p->dc = last_dcinfo; + + init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); + if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { + DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); + return False; + } + + /*** SCHANNEL verifier ***/ + + init_rpc_auth_verifier(&auth_verifier, "\001", 0x0); + if(!smb_io_rpc_schannel_verifier("", &auth_verifier, pout_auth, 0)) { + DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_AUTH_VERIFIER failed.\n")); + return False; + } + + prs_align(pout_auth); + + flags = 5; + if(!prs_uint32("flags ", pout_auth, 0, &flags)) { + return False; + } + + DEBUG(10,("pipe_schannel_auth_bind: schannel auth: domain [%s] myname [%s]\n", + neg.domain, neg.myname)); + + /* We're finished with this bind - no more packets. */ + p->auth.auth_data_free_func = NULL; + p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL; + + p->pipe_bound = True; + + return True; +} + +/******************************************************************* + Handle an NTLMSSP bind auth. +*******************************************************************/ + +static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, + RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) +{ + RPC_HDR_AUTH auth_info; + DATA_BLOB blob; + DATA_BLOB response; + NTSTATUS status; + AUTH_NTLMSSP_STATE *a = NULL; + + ZERO_STRUCT(blob); + ZERO_STRUCT(response); + + /* Grab the NTLMSSP blob. */ + blob = data_blob(NULL,p->hdr.auth_len); + + if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) { + DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to pull %u bytes - the NTLM auth header.\n", + (unsigned int)p->hdr.auth_len )); + goto err; + } + + if (strncmp(blob.data, "NTLMSSP", 7) != 0) { + DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to read NTLMSSP in blob\n")); + goto err; + } + + /* We have an NTLMSSP blob. */ + status = auth_ntlmssp_start(&a); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_start failed: %s\n", + nt_errstr(status) )); + goto err; + } + + status = auth_ntlmssp_update(a, blob, &response); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(0,("pipe_ntlmssp_auth_bind: auth_ntlmssp_update failed: %s\n", + nt_errstr(status) )); + goto err; + } + + data_blob_free(&blob); + + /* Copy the blob into the pout_auth parse struct */ + init_rpc_hdr_auth(&auth_info, RPC_NTLMSSP_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); + if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { + DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); + goto err; + } + + if (!prs_copy_data_in(pout_auth, response.data, response.length)) { + DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of data blob failed.\n")); + goto err; + } + + p->auth.a_u.auth_ntlmssp_state = a; + p->auth.auth_data_free_func = &free_pipe_ntlmssp_auth_data; + p->auth.auth_type = PIPE_AUTH_TYPE_NTLMSSP; + + data_blob_free(&blob); + data_blob_free(&response); + + DEBUG(10,("pipe_ntlmssp_auth_bind: NTLMSSP auth started\n")); + + /* We can't set pipe_bound True yet - we need an RPC_AUTH3 response packet... */ + return True; + + err: + + data_blob_free(&blob); + data_blob_free(&response); + + free_pipe_ntlmssp_auth_data(&p->auth); + p->auth.a_u.auth_ntlmssp_state = NULL; + return False; +} + /******************************************************************* Respond to a pipe bind request. *******************************************************************/ @@ -872,162 +1385,280 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) prs_struct outgoing_rpc; int i = 0; int auth_len = 0; - enum RPC_PKT_TYPE reply_pkt_type; + unsigned int auth_type = RPC_ANONYMOUS_AUTH_TYPE; + + /* No rebinds on a bound pipe - use alter context. */ + if (p->pipe_bound) { + DEBUG(2,("api_pipe_bind_req: rejecting bind request on bound pipe %s.\n", p->pipe_srv_name)); + return setup_bind_nak(p); + } - p->ntlmssp_auth_requested = False; - p->netsec_auth_validated = False; + prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); + + /* + * Marshall directly into the outgoing PDU space. We + * must do this as we need to set to the bind response + * header and are never sending more than one PDU here. + */ + + prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); + + /* + * Setup the memory to marshall the ba header, and the + * auth footers. + */ + + if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) { + DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); + prs_mem_free(&outgoing_rpc); + return False; + } + + if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) { + DEBUG(0,("api_pipe_bind_req: malloc out_auth failed.\n")); + prs_mem_free(&outgoing_rpc); + prs_mem_free(&out_hdr_ba); + return False; + } DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); /* - * Try and find the correct pipe name to ensure - * that this is a pipe name we support. + * Try and find the correct pipe name to ensure + * that this is a pipe name we support. + */ + + + for (i = 0; i < rpc_lookup_size; i++) { + if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { + DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); + fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); + break; + } + } + + if (i == rpc_lookup_size) { + if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { + DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", + p->name )); + prs_mem_free(&outgoing_rpc); + prs_mem_free(&out_hdr_ba); + prs_mem_free(&out_auth); + + return setup_bind_nak(p); + } + + for (i = 0; i < rpc_lookup_size; i++) { + if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { + DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", + rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); + fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); + break; + } + } + + if (i == rpc_lookup_size) { + DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); + goto err_exit; + } + } + + /* decode the bind request */ + if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); + goto err_exit; + } + + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, p->pipe_srv_name); + + DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); + + /* + * Check if this is an authenticated bind request. + */ + + if (p->hdr.auth_len) { + /* + * Decode the authentication verifier. + */ + + if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); + goto err_exit; + } + + auth_type = auth_info.auth_type; + + /* Work out if we have to sign or seal etc. */ + switch (auth_info.auth_level) { + case RPC_AUTH_LEVEL_INTEGRITY: + p->auth.auth_level = PIPE_AUTH_LEVEL_INTEGRITY; + break; + case RPC_AUTH_LEVEL_PRIVACY: + p->auth.auth_level = PIPE_AUTH_LEVEL_PRIVACY; + break; + default: + DEBUG(0,("api_pipe_bind_req: unexpected auth level (%u).\n", + (unsigned int)auth_info.auth_level )); + goto err_exit; + } + } else { + ZERO_STRUCT(auth_info); + } + + assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0; + + switch(auth_type) { + case RPC_NTLMSSP_AUTH_TYPE: + if (!pipe_ntlmssp_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) { + goto err_exit; + } + assoc_gid = 0x7a77; + break; + + case RPC_SCHANNEL_AUTH_TYPE: + if (!pipe_schannel_auth_bind(p, rpc_in_p, &auth_info, &out_auth)) { + goto err_exit; + } + break; + + case RPC_SPNEGO_AUTH_TYPE: + if (!pipe_spnego_auth_bind_negotiate(p, rpc_in_p, &auth_info, &out_auth)) { + goto err_exit; + } + break; + + case RPC_ANONYMOUS_AUTH_TYPE: + /* Unauthenticated bind request. */ + /* We're finished - no more packets. */ + p->auth.auth_type = PIPE_AUTH_TYPE_NONE; + /* We must set the pipe auth_level here also. */ + p->auth.auth_level = PIPE_AUTH_LEVEL_NONE; + p->pipe_bound = True; + break; + + default: + DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", auth_type )); + goto err_exit; + } + + /* + * Create the bind response struct. + */ + + /* If the requested abstract synt uuid doesn't match our client pipe, + reject the bind_ack & set the transfer interface synt to all 0's, + ver 0 (observed when NT5 attempts to bind to abstract interfaces + unknown to NT4) + Needed when adding entries to a DACL from NT5 - SK */ + + if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0], + hdr_rb.rpc_context[0].context_id )) { + init_rpc_hdr_ba(&hdr_ba, + RPC_MAX_PDU_FRAG_LEN, + RPC_MAX_PDU_FRAG_LEN, + assoc_gid, + ack_pipe_name, + 0x1, 0x0, 0x0, + &hdr_rb.rpc_context[0].transfer[0]); + } else { + RPC_IFACE null_interface; + ZERO_STRUCT(null_interface); + /* Rejection reason: abstract syntax not supported */ + init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN, + RPC_MAX_PDU_FRAG_LEN, assoc_gid, + ack_pipe_name, 0x1, 0x2, 0x1, + &null_interface); + p->pipe_bound = False; + } + + /* + * and marshall it. */ - - for (i = 0; i < rpc_lookup_size; i++) { - if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { - DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", - rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); - fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); - break; - } + if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n")); + goto err_exit; } - if (i == rpc_lookup_size) { - if (NT_STATUS_IS_ERR(smb_probe_module("rpc", p->name))) { - DEBUG(3,("api_pipe_bind_req: Unknown pipe name %s in bind request.\n", - p->name )); - return setup_bind_nak(p); - } - - for (i = 0; i < rpc_lookup_size; i++) { - if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { - DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", - rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); - fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); - break; - } - } + /* + * Create the header, now we know the length. + */ - if (i == rpc_lookup_size) { - DEBUG(0, ("module %s doesn't provide functions for pipe %s!\n", p->name, p->name)); - return False; - } + if (prs_offset(&out_auth)) { + auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; } - /* decode the bind request */ - if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); - return setup_bind_nak(p); - } + init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, + RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), + auth_len); /* - * Check if this is an authenticated request. + * Marshall the header into the outgoing PDU. */ - if (p->hdr.auth_len != 0) { - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_NEG ntlmssp_neg; - - /* - * Decode the authentication verifier. - */ - - if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_AUTH struct.\n")); - return setup_bind_nak(p); - } - - switch(auth_info.auth_type) { - case NTLMSSP_AUTH_TYPE: - - if(!smb_io_rpc_auth_verifier("", &auth_verifier, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to " - "unmarshall RPC_HDR_AUTH struct.\n")); - return setup_bind_nak(p); - } - - if(!strequal(auth_verifier.signature, "NTLMSSP")) { - DEBUG(0,("api_pipe_bind_req: " - "auth_verifier.signature != NTLMSSP\n")); - return setup_bind_nak(p); - } - - if(auth_verifier.msg_type != NTLMSSP_NEGOTIATE) { - DEBUG(0,("api_pipe_bind_req: " - "auth_verifier.msg_type (%d) != NTLMSSP_NEGOTIATE\n", - auth_verifier.msg_type)); - return setup_bind_nak(p); - } + if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) { + DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR failed.\n")); + goto err_exit; + } - if(!smb_io_rpc_auth_ntlmssp_neg("", &ntlmssp_neg, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: " - "Failed to unmarshall RPC_AUTH_NTLMSSP_NEG.\n")); - return setup_bind_nak(p); - } + /* + * Now add the RPC_HDR_BA and any auth needed. + */ - p->ntlmssp_chal_flags = SMBD_NTLMSSP_NEG_FLAGS; - p->ntlmssp_auth_requested = True; - break; + if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) { + DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n")); + goto err_exit; + } - case NETSEC_AUTH_TYPE: - { - RPC_AUTH_NETSEC_NEG neg; - struct netsec_auth_struct *a = &(p->netsec_auth); + if (auth_len && !prs_append_prs_data( &outgoing_rpc, &out_auth)) { + DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n")); + goto err_exit; + } - if (!server_auth2_negotiated) { - DEBUG(0, ("Attempt to bind using schannel " - "without successful serverauth2\n")); - return setup_bind_nak(p); - } + /* + * Setup the lengths for the initial reply. + */ - if (!smb_io_rpc_auth_netsec_neg("", &neg, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: " - "Could not unmarshal SCHANNEL auth neg\n")); - return setup_bind_nak(p); - } + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); + p->out_data.current_pdu_sent = 0; - p->netsec_auth_validated = True; + prs_mem_free(&out_hdr_ba); + prs_mem_free(&out_auth); - memset(a->sess_key, 0, sizeof(a->sess_key)); - memcpy(a->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key)); + return True; - a->seq_num = 0; + err_exit: - DEBUG(10,("schannel auth: domain [%s] myname [%s]\n", - neg.domain, neg.myname)); - break; - } + prs_mem_free(&outgoing_rpc); + prs_mem_free(&out_hdr_ba); + prs_mem_free(&out_auth); + return setup_bind_nak(p); +} - case SPNEGO_AUTH_TYPE: - default: - DEBUG(0,("api_pipe_bind_req: unknown auth type %x requested.\n", - auth_info.auth_type )); - return setup_bind_nak(p); - } - } +/**************************************************************************** + Deal with an alter context call. Can be third part of 3 leg auth request for + SPNEGO calls. +****************************************************************************/ - switch(p->hdr.pkt_type) { - case RPC_BIND: - /* name has to be \PIPE\xxxxx */ - fstrcpy(ack_pipe_name, "\\PIPE\\"); - fstrcat(ack_pipe_name, p->pipe_srv_name); - reply_pkt_type = RPC_BINDACK; - break; - case RPC_ALTCONT: - /* secondary address CAN be NULL - * as the specs say it's ignored. - * It MUST NULL to have the spoolss working. - */ - fstrcpy(ack_pipe_name,""); - reply_pkt_type = RPC_ALTCONTRESP; - break; - default: - return False; - } +BOOL api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p) +{ + RPC_HDR_BA hdr_ba; + RPC_HDR_RB hdr_rb; + RPC_HDR_AUTH auth_info; + uint16 assoc_gid; + fstring ack_pipe_name; + prs_struct out_hdr_ba; + prs_struct out_auth; + prs_struct outgoing_rpc; + int auth_len = 0; - DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); + prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); /* * Marshall directly into the outgoing PDU space. We @@ -1035,7 +1666,6 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -1044,22 +1674,68 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) */ if(!prs_init(&out_hdr_ba, 1024, p->mem_ctx, MARSHALL)) { - DEBUG(0,("api_pipe_bind_req: malloc out_hdr_ba failed.\n")); + DEBUG(0,("api_pipe_alter_context: malloc out_hdr_ba failed.\n")); prs_mem_free(&outgoing_rpc); return False; } if(!prs_init(&out_auth, 1024, p->mem_ctx, MARSHALL)) { - DEBUG(0,("pi_pipe_bind_req: malloc out_auth failed.\n")); + DEBUG(0,("api_pipe_alter_context: malloc out_auth failed.\n")); prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); return False; } - if (p->ntlmssp_auth_requested) - assoc_gid = 0x7a77; - else - assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0; + DEBUG(5,("api_pipe_alter_context: decode request. %d\n", __LINE__)); + + /* decode the alter context request */ + if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_RB struct.\n")); + goto err_exit; + } + + /* secondary address CAN be NULL + * as the specs say it's ignored. + * It MUST be NULL to have the spoolss working. + */ + fstrcpy(ack_pipe_name,""); + + DEBUG(5,("api_pipe_alter_context: make response. %d\n", __LINE__)); + + /* + * Check if this is an authenticated alter context request. + */ + + if (p->hdr.auth_len != 0) { + /* + * Decode the authentication verifier. + */ + + if(!smb_io_rpc_hdr_auth("", &auth_info, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_alter_context: unable to unmarshall RPC_HDR_AUTH struct.\n")); + goto err_exit; + } + + /* + * Currently only the SPNEGO auth type uses the alter ctx + * response in place of the NTLMSSP auth3 type. + */ + + if (auth_info.auth_type == RPC_SPNEGO_AUTH_TYPE) { + /* We can only finish if the pipe is unbound. */ + if (!p->pipe_bound) { + if (!pipe_spnego_auth_bind_continue(p, rpc_in_p, &auth_info, &out_auth)) { + goto err_exit; + } + } else { + goto err_exit; + } + } + } else { + ZERO_STRUCT(auth_info); + } + + assoc_gid = hdr_rb.bba.assoc_gid ? hdr_rb.bba.assoc_gid : 0x53f0; /* * Create the bind response struct. @@ -1074,8 +1750,8 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) if(check_bind_req(p, &hdr_rb.rpc_context[0].abstract, &hdr_rb.rpc_context[0].transfer[0], hdr_rb.rpc_context[0].context_id )) { init_rpc_hdr_ba(&hdr_ba, - MAX_PDU_FRAG_LEN, - MAX_PDU_FRAG_LEN, + RPC_MAX_PDU_FRAG_LEN, + RPC_MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x0, 0x0, @@ -1084,10 +1760,11 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) RPC_IFACE null_interface; ZERO_STRUCT(null_interface); /* Rejection reason: abstract syntax not supported */ - init_rpc_hdr_ba(&hdr_ba, MAX_PDU_FRAG_LEN, - MAX_PDU_FRAG_LEN, assoc_gid, + init_rpc_hdr_ba(&hdr_ba, RPC_MAX_PDU_FRAG_LEN, + RPC_MAX_PDU_FRAG_LEN, assoc_gid, ack_pipe_name, 0x1, 0x2, 0x1, &null_interface); + p->pipe_bound = False; } /* @@ -1095,85 +1772,19 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) */ if(!smb_io_rpc_hdr_ba("", &hdr_ba, &out_hdr_ba, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_BA failed.\n")); + DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR_BA failed.\n")); goto err_exit; } /* - * Now the authentication. + * Create the header, now we know the length. */ - if (p->ntlmssp_auth_requested) { - RPC_AUTH_VERIFIER auth_verifier; - RPC_AUTH_NTLMSSP_CHAL ntlmssp_chal; - - generate_random_buffer(p->challenge, 8); - - /*** Authentication info ***/ - - init_rpc_hdr_auth(&auth_info, NTLMSSP_AUTH_TYPE, RPC_PIPE_AUTH_SEAL_LEVEL, RPC_HDR_AUTH_LEN, 1); - if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); - goto err_exit; - } - - /*** NTLMSSP verifier ***/ - - init_rpc_auth_verifier(&auth_verifier, "NTLMSSP", NTLMSSP_CHALLENGE); - if(!smb_io_rpc_auth_verifier("", &auth_verifier, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n")); - goto err_exit; - } - - /* NTLMSSP challenge ***/ - - init_rpc_auth_ntlmssp_chal(&ntlmssp_chal, p->ntlmssp_chal_flags, p->challenge); - if(!smb_io_rpc_auth_ntlmssp_chal("", &ntlmssp_chal, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_NTLMSSP_CHAL failed.\n")); - goto err_exit; - } - - /* Auth len in the rpc header doesn't include auth_header. */ - auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; - } - - if (p->netsec_auth_validated) { - RPC_AUTH_VERIFIER auth_verifier; - uint32 flags; - - /* The client opens a second RPC NETLOGON pipe without - doing a auth2. The credentials for the schannel are - re-used from the auth2 the client did before. */ - p->dc = last_dcinfo; - - init_rpc_hdr_auth(&auth_info, NETSEC_AUTH_TYPE, auth_info.auth_level, RPC_HDR_AUTH_LEN, 1); - if(!smb_io_rpc_hdr_auth("", &auth_info, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_HDR_AUTH failed.\n")); - goto err_exit; - } - - /*** NETSEC verifier ***/ - - init_rpc_auth_verifier(&auth_verifier, "\001", 0x0); - if(!smb_io_rpc_netsec_verifier("", &auth_verifier, &out_auth, 0)) { - DEBUG(0,("api_pipe_bind_req: marshalling of RPC_AUTH_VERIFIER failed.\n")); - goto err_exit; - } - - prs_align(&out_auth); - - flags = 5; - if(!prs_uint32("flags ", &out_auth, 0, &flags)) - goto err_exit; - + if (prs_offset(&out_auth)) { auth_len = prs_offset(&out_auth) - RPC_HDR_AUTH_LEN; } - /* - * Create the header, now we know the length. - */ - - init_rpc_hdr(&p->hdr, reply_pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, + init_rpc_hdr(&p->hdr, RPC_ALTCONTRESP, RPC_FLG_FIRST | RPC_FLG_LAST, p->hdr.call_id, RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), auth_len); @@ -1183,7 +1794,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) */ if(!smb_io_rpc_hdr("", &p->hdr, &outgoing_rpc, 0)) { - DEBUG(0,("pi_pipe_bind_req: marshalling of RPC_HDR failed.\n")); + DEBUG(0,("api_pipe_alter_context: marshalling of RPC_HDR failed.\n")); goto err_exit; } @@ -1192,19 +1803,15 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) */ if(!prs_append_prs_data( &outgoing_rpc, &out_hdr_ba)) { - DEBUG(0,("api_pipe_bind_req: append of RPC_HDR_BA failed.\n")); + DEBUG(0,("api_pipe_alter_context: append of RPC_HDR_BA failed.\n")); goto err_exit; } - if((p->ntlmssp_auth_requested|p->netsec_auth_validated) && - !prs_append_prs_data( &outgoing_rpc, &out_auth)) { - DEBUG(0,("api_pipe_bind_req: append of auth info failed.\n")); + if (auth_len && !prs_append_prs_data( &outgoing_rpc, &out_auth)) { + DEBUG(0,("api_pipe_alter_context: append of auth info failed.\n")); goto err_exit; } - if(!p->ntlmssp_auth_requested) - p->pipe_bound = True; - /* * Setup the lengths for the initial reply. */ @@ -1223,138 +1830,141 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) prs_mem_free(&outgoing_rpc); prs_mem_free(&out_hdr_ba); prs_mem_free(&out_auth); - return False; + return setup_bind_nak(p); } /**************************************************************************** - Deal with sign & seal processing on an RPC request. + Deal with NTLMSSP sign & seal processing on an RPC request. ****************************************************************************/ -BOOL api_pipe_auth_process(pipes_struct *p, prs_struct *rpc_in) +BOOL api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in, + uint32 *p_ss_padding_len, NTSTATUS *pstatus) { - /* - * We always negotiate the following two bits.... - */ - BOOL auth_verify = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SIGN) != 0); - BOOL auth_seal = ((p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_SEAL) != 0); - int data_len; - int auth_len; - uint32 old_offset; - uint32 crc32 = 0; + RPC_HDR_AUTH auth_info; + uint32 auth_len = p->hdr.auth_len; + uint32 save_offset = prs_offset(rpc_in); + AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state; + unsigned char *data = NULL; + size_t data_len; + unsigned char *full_packet_data = NULL; + size_t full_packet_data_len; + DATA_BLOB auth_blob; + + *pstatus = NT_STATUS_OK; - auth_len = p->hdr.auth_len; + if (p->auth.auth_level == PIPE_AUTH_LEVEL_NONE || p->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) { + return True; + } + + if (!a) { + *pstatus = NT_STATUS_INVALID_PARAMETER; + return False; + } - if ((auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) && auth_verify) { - DEBUG(0,("api_pipe_auth_process: Incorrect auth_len %d.\n", auth_len )); + /* Ensure there's enough data for an authenticated request. */ + if ((auth_len > RPC_MAX_SIGN_SIZE) || + (RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len > p->hdr.frag_len)) { + DEBUG(0,("api_pipe_ntlmssp_auth_process: auth_len %u is too large.\n", + (unsigned int)auth_len )); + *pstatus = NT_STATUS_INVALID_PARAMETER; return False; } /* - * The following is that length of the data we must verify or unseal. - * This doesn't include the RPC headers or the auth_len or the RPC_HDR_AUTH_LEN - * preceeding the auth_data. + * We need the full packet data + length (minus auth stuff) as well as the packet data + length + * after the RPC header. + * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal + * functions as NTLMv2 checks the rpc headers also. */ - data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - - (auth_verify ? RPC_HDR_AUTH_LEN : 0) - auth_len; - - DEBUG(5,("api_pipe_auth_process: sign: %s seal: %s data %d auth %d\n", - BOOLSTR(auth_verify), BOOLSTR(auth_seal), data_len, auth_len)); + data = (unsigned char *)(prs_data_p(rpc_in) + RPC_HDR_REQ_LEN); + data_len = (size_t)(p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - RPC_HDR_AUTH_LEN - auth_len); - if (auth_seal) { - /* - * The data in rpc_in doesn't contain the RPC_HEADER as this - * has already been consumed. - */ - char *data = prs_data_p(rpc_in) + RPC_HDR_REQ_LEN; - dump_data_pw("NTLMSSP hash (v1)\n", p->ntlmssp_hash, - sizeof(p->ntlmssp_hash)); + full_packet_data = p->in_data.current_in_pdu; + full_packet_data_len = p->hdr.frag_len - auth_len; - dump_data_pw("Incoming RPC PDU (NTLMSSP sealed)\n", - (const unsigned char *)data, data_len); - NTLMSSPcalc_p(p, (uchar*)data, data_len); - dump_data_pw("Incoming RPC PDU (NTLMSSP unsealed)\n", - (const unsigned char *)data, data_len); - crc32 = crc32_calc_buffer(data, data_len); + /* Pull the auth header and the following data into a blob. */ + if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) { + DEBUG(0,("api_pipe_ntlmssp_auth_process: cannot move offset to %u.\n", + (unsigned int)RPC_HDR_REQ_LEN + (unsigned int)data_len )); + *pstatus = NT_STATUS_INVALID_PARAMETER; + return False; } - old_offset = prs_offset(rpc_in); - - if (auth_seal || auth_verify) { - RPC_HDR_AUTH auth_info; - - if(!prs_set_offset(rpc_in, old_offset + data_len)) { - DEBUG(0,("api_pipe_auth_process: cannot move offset to %u.\n", - (unsigned int)old_offset + data_len )); - return False; - } - - if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { - DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_HDR_AUTH.\n")); - return False; - } + if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, rpc_in, 0)) { + DEBUG(0,("api_pipe_ntlmssp_auth_process: failed to unmarshall RPC_HDR_AUTH.\n")); + *pstatus = NT_STATUS_INVALID_PARAMETER; + return False; } - if (auth_verify) { - RPC_AUTH_NTLMSSP_CHK ntlmssp_chk; - char *req_data = prs_data_p(rpc_in) + prs_offset(rpc_in) + 4; - - DEBUG(5,("api_pipe_auth_process: auth %d\n", prs_offset(rpc_in) + 4)); - - /* - * Ensure we have RPC_AUTH_NTLMSSP_CHK_LEN - 4 more bytes in the - * incoming buffer. - */ - if(prs_mem_get(rpc_in, RPC_AUTH_NTLMSSP_CHK_LEN - 4) == NULL) { - DEBUG(0,("api_pipe_auth_process: missing %d bytes in buffer.\n", - RPC_AUTH_NTLMSSP_CHK_LEN - 4 )); - return False; - } - - NTLMSSPcalc_p(p, (uchar*)req_data, RPC_AUTH_NTLMSSP_CHK_LEN - 4); - if(!smb_io_rpc_auth_ntlmssp_chk("auth_sign", &ntlmssp_chk, rpc_in, 0)) { - DEBUG(0,("api_pipe_auth_process: failed to unmarshall RPC_AUTH_NTLMSSP_CHK.\n")); - return False; - } - - if (!rpc_auth_ntlmssp_chk(&ntlmssp_chk, crc32, p->ntlmssp_seq_num)) { - DEBUG(0,("api_pipe_auth_process: NTLMSSP check failed.\n")); + auth_blob.data = prs_data_p(rpc_in) + prs_offset(rpc_in); + auth_blob.length = auth_len; + + switch (p->auth.auth_level) { + case PIPE_AUTH_LEVEL_PRIVACY: + /* Data is encrypted. */ + *pstatus = ntlmssp_unseal_packet(a->ntlmssp_state, + data, data_len, + full_packet_data, + full_packet_data_len, + &auth_blob); + if (!NT_STATUS_IS_OK(*pstatus)) { + return False; + } + break; + case PIPE_AUTH_LEVEL_INTEGRITY: + /* Data is signed. */ + *pstatus = ntlmssp_check_packet(a->ntlmssp_state, + data, data_len, + full_packet_data, + full_packet_data_len, + &auth_blob); + if (!NT_STATUS_IS_OK(*pstatus)) { + return False; + } + break; + default: + *pstatus = NT_STATUS_INVALID_PARAMETER; return False; - } } /* * Return the current pointer to the data offset. */ - if(!prs_set_offset(rpc_in, old_offset)) { + if(!prs_set_offset(rpc_in, save_offset)) { DEBUG(0,("api_pipe_auth_process: failed to set offset back to %u\n", - (unsigned int)old_offset )); + (unsigned int)save_offset )); + *pstatus = NT_STATUS_INVALID_PARAMETER; return False; } + /* + * Remember the padding length. We must remove it from the real data + * stream once the sign/seal is done. + */ + + *p_ss_padding_len = auth_info.auth_pad_len; + return True; } /**************************************************************************** Deal with schannel processing on an RPC request. ****************************************************************************/ -BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) + +BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len) { - /* - * We always negotiate the following two bits.... - */ - int data_len; - int auth_len; - uint32 old_offset; + uint32 data_len; + uint32 auth_len; + uint32 save_offset = prs_offset(rpc_in); RPC_HDR_AUTH auth_info; - RPC_AUTH_NETSEC_CHK netsec_chk; - + RPC_AUTH_SCHANNEL_CHK schannel_chk; auth_len = p->hdr.auth_len; - if (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) { - DEBUG(0,("Incorrect auth_len %d.\n", auth_len )); + if (auth_len != RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN) { + DEBUG(0,("Incorrect auth_len %u.\n", (unsigned int)auth_len )); return False; } @@ -1364,16 +1974,21 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) * preceeding the auth_data. */ + if (p->hdr.frag_len < RPC_HEADER_LEN + RPC_HDR_REQ_LEN + RPC_HDR_AUTH_LEN + auth_len) { + DEBUG(0,("Incorrect frag %u, auth %u.\n", + (unsigned int)p->hdr.frag_len, + (unsigned int)auth_len )); + return False; + } + data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN - RPC_HDR_AUTH_LEN - auth_len; DEBUG(5,("data %d auth %d\n", data_len, auth_len)); - old_offset = prs_offset(rpc_in); - - if(!prs_set_offset(rpc_in, old_offset + data_len)) { + if(!prs_set_offset(rpc_in, RPC_HDR_REQ_LEN + data_len)) { DEBUG(0,("cannot move offset to %u.\n", - (unsigned int)old_offset + data_len )); + (unsigned int)RPC_HDR_REQ_LEN + data_len )); return False; } @@ -1382,34 +1997,22 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) return False; } - if (auth_info.auth_type != NETSEC_AUTH_TYPE) { + if (auth_info.auth_type != RPC_SCHANNEL_AUTH_TYPE) { DEBUG(0,("Invalid auth info %d on schannel\n", auth_info.auth_type)); return False; } - if (auth_info.auth_level == RPC_PIPE_AUTH_SEAL_LEVEL) { - p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN|AUTH_PIPE_SEAL; - } else if (auth_info.auth_level == RPC_PIPE_AUTH_SIGN_LEVEL) { - p->netsec_auth.auth_flags = AUTH_PIPE_NETSEC|AUTH_PIPE_SIGN; - } else { - DEBUG(0,("Invalid auth level %d on schannel\n", - auth_info.auth_level)); - return False; - } - - if(!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, - &netsec_chk, rpc_in, 0)) - { - DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n")); + if(!smb_io_rpc_auth_schannel_chk("", RPC_AUTH_SCHANNEL_SIGN_OR_SEAL_CHK_LEN, &schannel_chk, rpc_in, 0)) { + DEBUG(0,("failed to unmarshal RPC_AUTH_SCHANNEL_CHK.\n")); return False; } - if (!netsec_decode(&p->netsec_auth, - p->netsec_auth.auth_flags, + if (!schannel_decode(p->auth.a_u.schannel_auth, + p->auth.auth_level, SENDER_IS_INITIATOR, - &netsec_chk, - prs_data_p(rpc_in)+old_offset, data_len)) { + &schannel_chk, + prs_data_p(rpc_in)+RPC_HDR_REQ_LEN, data_len)) { DEBUG(3,("failed to decode PDU\n")); return False; } @@ -1418,14 +2021,21 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) * Return the current pointer to the data offset. */ - if(!prs_set_offset(rpc_in, old_offset)) { + if(!prs_set_offset(rpc_in, save_offset)) { DEBUG(0,("failed to set offset back to %u\n", - (unsigned int)old_offset )); + (unsigned int)save_offset )); return False; } /* The sequence number gets incremented on both send and receive. */ - p->netsec_auth.seq_num++; + p->auth.a_u.schannel_auth->seq_num++; + + /* + * Remember the padding length. We must remove it from the real data + * stream once the sign/seal is done. + */ + + *p_ss_padding_len = auth_info.auth_pad_len; return True; } @@ -1436,7 +2046,9 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) struct current_user *get_current_user(struct current_user *user, pipes_struct *p) { - if (p->ntlmssp_auth_validated) { + if (p->pipe_bound && + (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP || + (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { memcpy(user, &p->pipe_user, sizeof(struct current_user)); } else { memcpy(user, ¤t_user, sizeof(struct current_user)); @@ -1470,7 +2082,7 @@ static PIPE_RPC_FNS* find_pipe_fns_by_context( PIPE_RPC_FNS *list, uint32 contex } /**************************************************************************** - memory cleanup + Memory cleanup. ****************************************************************************/ void free_pipe_rpc_context( PIPE_RPC_FNS *list ) @@ -1496,14 +2108,17 @@ void free_pipe_rpc_context( PIPE_RPC_FNS *list ) BOOL api_pipe_request(pipes_struct *p) { BOOL ret = False; + BOOL changed_user = False; PIPE_RPC_FNS *pipe_fns; - if (p->ntlmssp_auth_validated) { - + if (p->pipe_bound && + ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) || + (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { if(!become_authenticated_pipe_user(p)) { prs_mem_free(&p->out_data.rdata); return False; } + changed_user = True; } DEBUG(5, ("Requested \\PIPE\\%s\n", p->name)); @@ -1522,8 +2137,9 @@ BOOL api_pipe_request(pipes_struct *p) p->hdr_req.context_id, p->name)); } - if(p->ntlmssp_auth_validated) + if (changed_user) { unbecome_authenticated_pipe_user(); + } return ret; } @@ -1649,6 +2265,9 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_EVENTLOG: eventlog_get_pipe_fns( &cmds, &n_cmds ); break; + case PI_NTSVCS: + ntsvcs_get_pipe_fns( &cmds, &n_cmds ); + break; #ifdef DEVELOPER case PI_ECHO: echo_get_pipe_fns( &cmds, &n_cmds ); @@ -1663,5 +2282,3 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) return; } - - -- cgit From e127501d4589a5a9c92e2f400fc67bda5a8e6855 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Oct 2005 01:46:19 +0000 Subject: r10792: Fix the "schannel not stored across client disconnects" problem. Based on the Samba4 solution - stores data in $samba/private/schannel_store.tdb. This tdb is not left open but open and closed on demand. Jeremy. (This used to be commit a6d8a4b1ff31c5552075455dbd98cb58795958a9) --- source3/rpc_server/srv_pipe.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ba6d9704e8..1ca5210842 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -36,15 +36,6 @@ extern struct current_user current_user; #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV -/************************************************************* - HACK Alert! - We need to transfer the session key from one rpc bind to the - next. This is the way the netlogon schannel works. -**************************************************************/ - -struct dcinfo last_dcinfo; -BOOL server_auth2_negotiated = False; - static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) { AUTH_NTLMSSP_STATE *a = auth->a_u.auth_ntlmssp_state; @@ -1218,15 +1209,23 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH auth_info; RPC_AUTH_SCHANNEL_NEG neg; RPC_AUTH_VERIFIER auth_verifier; + BOOL ret; + struct dcinfo stored_dcinfo; uint32 flags; - if (!server_auth2_negotiated) { - DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n")); + if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) { + DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n")); return False; } - if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) { - DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n")); + ZERO_STRUCT(stored_dcinfo); + + become_root(); + ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &stored_dcinfo); + unbecome_root(); + + if (!ret) { + DEBUG(0, ("pipe_schannel_auth_bind: Attempt to bind using schannel without successful serverauth2\n")); return False; } @@ -1236,7 +1235,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, } memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key)); - memcpy(p->auth.a_u.schannel_auth->sess_key, last_dcinfo.sess_key, sizeof(last_dcinfo.sess_key)); + memcpy(p->auth.a_u.schannel_auth->sess_key, stored_dcinfo.sess_key, sizeof(stored_dcinfo.sess_key)); p->auth.a_u.schannel_auth->seq_num = 0; @@ -1253,7 +1252,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, if (!p->dc) { return False; } - *p->dc = last_dcinfo; + *p->dc = stored_dcinfo; init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { -- cgit From 8d7c88667190fe286971ac4fffb64ee5bd9eeeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Oct 2005 03:24:00 +0000 Subject: r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4 x86_64 box. Jeremy. (This used to be commit d720867a788c735e56d53d63265255830ec21208) --- source3/rpc_server/srv_pipe.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1ca5210842..b615080d34 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -173,7 +173,7 @@ static BOOL create_next_pdu_ntlmssp(pipes_struct *p) /* Copy the sign/seal padding data. */ if (ss_padding_len) { - unsigned char pad[8]; + char pad[8]; memset(pad, '\0', 8); if (!prs_copy_data_in(&outgoing_pdu, pad, ss_padding_len)) { @@ -210,9 +210,9 @@ static BOOL create_next_pdu_ntlmssp(pipes_struct *p) case PIPE_AUTH_LEVEL_PRIVACY: /* Data portion is encrypted. */ status = ntlmssp_seal_packet(a->ntlmssp_state, - prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + (unsigned char *)prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, data_len + ss_padding_len, - prs_data_p(&outgoing_pdu), + (unsigned char *)prs_data_p(&outgoing_pdu), (size_t)prs_offset(&outgoing_pdu), &auth_blob); if (!NT_STATUS_IS_OK(status)) { @@ -224,9 +224,9 @@ static BOOL create_next_pdu_ntlmssp(pipes_struct *p) case PIPE_AUTH_LEVEL_INTEGRITY: /* Data is signed. */ status = ntlmssp_sign_packet(a->ntlmssp_state, - prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, + (unsigned char *)prs_data_p(&outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN, data_len + ss_padding_len, - prs_data_p(&outgoing_pdu), + (unsigned char *)prs_data_p(&outgoing_pdu), (size_t)prs_offset(&outgoing_pdu), &auth_blob); if (!NT_STATUS_IS_OK(status)) { @@ -241,7 +241,7 @@ static BOOL create_next_pdu_ntlmssp(pipes_struct *p) } /* Append the auth blob. */ - if (!prs_copy_data_in(&outgoing_pdu, auth_blob.data, NTLMSSP_SIG_SIZE)) { + if (!prs_copy_data_in(&outgoing_pdu, (char *)auth_blob.data, NTLMSSP_SIG_SIZE)) { DEBUG(0,("create_next_pdu_ntlmssp: failed to add %u bytes auth blob.\n", (unsigned int)NTLMSSP_SIG_SIZE)); data_blob_free(&auth_blob); @@ -731,7 +731,7 @@ BOOL api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p) blob = data_blob(NULL,p->hdr.auth_len); - if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) { + if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) { DEBUG(0,("api_pipe_bind_auth3: Failed to pull %u bytes - the response blob.\n", (unsigned int)p->hdr.auth_len )); goto err; @@ -1036,7 +1036,7 @@ static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ /* Grab the SPNEGO blob. */ blob = data_blob(NULL,p->hdr.auth_len); - if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) { + if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) { DEBUG(0,("pipe_spnego_auth_bind_negotiate: Failed to pull %u bytes - the SPNEGO auth header.\n", (unsigned int)p->hdr.auth_len )); goto err; @@ -1103,7 +1103,7 @@ static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ goto err; } - if (!prs_copy_data_in(pout_auth, response.data, response.length)) { + if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) { DEBUG(0,("pipe_spnego_auth_bind_negotiate: marshalling of data blob failed.\n")); goto err; } @@ -1154,7 +1154,7 @@ static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p /* Grab the SPNEGO blob. */ spnego_blob = data_blob(NULL,p->hdr.auth_len); - if (!prs_copy_data_out(spnego_blob.data, rpc_in_p, p->hdr.auth_len)) { + if (!prs_copy_data_out((char *)spnego_blob.data, rpc_in_p, p->hdr.auth_len)) { DEBUG(0,("pipe_spnego_auth_bind_continue: Failed to pull %u bytes - the SPNEGO auth header.\n", (unsigned int)p->hdr.auth_len )); goto err; @@ -1306,13 +1306,13 @@ static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, /* Grab the NTLMSSP blob. */ blob = data_blob(NULL,p->hdr.auth_len); - if (!prs_copy_data_out(blob.data, rpc_in_p, p->hdr.auth_len)) { + if (!prs_copy_data_out((char *)blob.data, rpc_in_p, p->hdr.auth_len)) { DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to pull %u bytes - the NTLM auth header.\n", (unsigned int)p->hdr.auth_len )); goto err; } - if (strncmp(blob.data, "NTLMSSP", 7) != 0) { + if (strncmp((char *)blob.data, "NTLMSSP", 7) != 0) { DEBUG(0,("pipe_ntlmssp_auth_bind: Failed to read NTLMSSP in blob\n")); goto err; } @@ -1341,7 +1341,7 @@ static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, goto err; } - if (!prs_copy_data_in(pout_auth, response.data, response.length)) { + if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) { DEBUG(0,("pipe_ntlmssp_auth_bind: marshalling of data blob failed.\n")); goto err; } @@ -1896,7 +1896,7 @@ BOOL api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in, return False; } - auth_blob.data = prs_data_p(rpc_in) + prs_offset(rpc_in); + auth_blob.data = (unsigned char *)prs_data_p(rpc_in) + prs_offset(rpc_in); auth_blob.length = auth_len; switch (p->auth.auth_level) { -- cgit From 05fafb83968a31907d996d37b91bdd9b72998701 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Nov 2005 02:10:52 +0000 Subject: r11950: If we got a connection oriented cancel pdu we would spin processing it. Fix that, and also add in comments for all possible CL and CO PDU types. Make sure we process them correctly. Jeremy. (This used to be commit 672113a627aa9060795871bc2ea3a02e696d7d7d) --- source3/rpc_server/srv_pipe.c | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index b615080d34..8084e7673a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -892,6 +892,55 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status) return True; } +#if 0 +/******************************************************************* + Marshall a cancel_ack pdu. + We should probably check the auth-verifier here. +*******************************************************************/ + +BOOL setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p) +{ + prs_struct outgoing_pdu; + RPC_HDR ack_reply_hdr; + + /* Free any memory in the current return data buffer. */ + prs_mem_free(&p->out_data.rdata); + + /* + * Marshall directly into the outgoing PDU space. We + * must do this as we need to set to the bind response + * header and are never sending more than one PDU here. + */ + + prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); + + /* + * Initialize a cancel_ack header. + */ + + init_rpc_hdr(&ack_reply_hdr, RPC_CANCEL_ACK, RPC_FLG_FIRST | RPC_FLG_LAST, + p->hdr.call_id, RPC_HEADER_LEN, 0); + + /* + * Marshall the header into the outgoing PDU. + */ + + if(!smb_io_rpc_hdr("", &ack_reply_hdr, &outgoing_pdu, 0)) { + DEBUG(0,("setup_cancel_ack_reply: marshalling of RPC_HDR failed.\n")); + prs_mem_free(&outgoing_pdu); + return False; + } + + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_len = prs_offset(&outgoing_pdu); + p->out_data.current_pdu_sent = 0; + + prs_mem_free(&outgoing_pdu); + return True; +} +#endif + /******************************************************************* Ensure a bind request has the correct abstract & transfer interface. Used to reject unknown binds from Win2k. -- cgit From f1022af07bbc72412d8fca7945a2c276fba88a7e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Jan 2006 02:35:08 +0000 Subject: r13176: Fix show-stopper bug for 3.0.21b where 4 leg NTLMSSP SPNEGO auth was not generating the correct auth header on the 4th packet. This may fix a lot of Windows client complaints and is essential for release. Jeremy. (This used to be commit 48dd8c732b890e3fd3d8e80ace765487601cfb26) --- source3/rpc_server/srv_pipe.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 8084e7673a..ecf79d0c1f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1188,12 +1188,17 @@ static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) { - DATA_BLOB spnego_blob, auth_blob, auth_reply; + RPC_HDR_AUTH auth_info; + DATA_BLOB spnego_blob; + DATA_BLOB auth_blob; + DATA_BLOB auth_reply; + DATA_BLOB response; AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state; ZERO_STRUCT(spnego_blob); ZERO_STRUCT(auth_blob); ZERO_STRUCT(auth_reply); + ZERO_STRUCT(response); if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) { DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n")); @@ -1230,7 +1235,24 @@ static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p data_blob_free(&spnego_blob); data_blob_free(&auth_blob); + + /* Generate the spnego "accept completed" blob - no incoming data. */ + response = spnego_gen_auth_response(&auth_reply, NT_STATUS_OK, OID_NTLMSSP); + + /* Copy the blob into the pout_auth parse struct */ + init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); + if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { + DEBUG(0,("pipe_spnego_auth_bind_continue: marshalling of RPC_HDR_AUTH failed.\n")); + goto err; + } + + if (!prs_copy_data_in(pout_auth, (char *)response.data, response.length)) { + DEBUG(0,("pipe_spnego_auth_bind_continue: marshalling of data blob failed.\n")); + goto err; + } + data_blob_free(&auth_reply); + data_blob_free(&response); p->pipe_bound = True; @@ -1241,6 +1263,7 @@ static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p data_blob_free(&spnego_blob); data_blob_free(&auth_blob); data_blob_free(&auth_reply); + data_blob_free(&response); free_pipe_ntlmssp_auth_data(&p->auth); p->auth.a_u.auth_ntlmssp_state = NULL; -- cgit From d14af63e6ab600eb3ac705f2f425c860e927553a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Feb 2006 20:44:50 +0000 Subject: r13293: Rather a big patch I'm afraid, but this should fix bug #3347 by saving the UNIX token used to set a delete on close flag, and using it when doing the delete. libsmbsharemodes.so still needs updating to cope with this change. Samba4 torture tests to follow. Jeremy. (This used to be commit 23f16cbc2e8cde97c486831e26bcafd4ab4a9654) --- source3/rpc_server/srv_pipe.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index ecf79d0c1f..381adbe635 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -617,8 +617,8 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) /* Set up for non-authenticated user. */ delete_nt_token(&p->pipe_user.nt_user_token); - p->pipe_user.ngroups = 0; - SAFE_FREE( p->pipe_user.groups); + p->pipe_user.ut.ngroups = 0; + SAFE_FREE( p->pipe_user.ut.groups); status = auth_ntlmssp_update(a, *p_resp_blob, &reply); @@ -641,8 +641,8 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - p->pipe_user.uid = a->server_info->uid; - p->pipe_user.gid = a->server_info->gid; + p->pipe_user.ut.uid = a->server_info->uid; + p->pipe_user.ut.gid = a->server_info->gid; /* * Copy the session key from the ntlmssp state. @@ -654,9 +654,10 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } - p->pipe_user.ngroups = a->server_info->n_groups; - if (p->pipe_user.ngroups) { - if (!(p->pipe_user.groups = memdup(a->server_info->groups, sizeof(gid_t) * p->pipe_user.ngroups))) { + p->pipe_user.ut.ngroups = a->server_info->n_groups; + if (p->pipe_user.ut.ngroups) { + if (!(p->pipe_user.ut.groups = memdup(a->server_info->groups, + sizeof(gid_t) * p->pipe_user.ut.ngroups))) { DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); return False; } -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/rpc_server/srv_pipe.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 381adbe635..68b3a2d434 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -616,7 +616,7 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) memset(p->wks, '\0', sizeof(p->wks)); /* Set up for non-authenticated user. */ - delete_nt_token(&p->pipe_user.nt_user_token); + talloc_free(p->pipe_user.nt_user_token); p->pipe_user.ut.ngroups = 0; SAFE_FREE( p->pipe_user.ut.groups); @@ -664,7 +664,8 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) } if (a->server_info->ptok) { - p->pipe_user.nt_user_token = dup_nt_token(a->server_info->ptok); + p->pipe_user.nt_user_token = + dup_nt_token(NULL, a->server_info->ptok); } else { DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); p->pipe_user.nt_user_token = NULL; -- cgit From 3e4cf56fa3f9d465d27dadaa6790bbcdea5d3cd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Feb 2006 23:15:55 +0000 Subject: r13519: Fix the credentials chaining across netlogon pipe disconnects. I mean it this time :-). Jeremy. (This used to be commit 80f4868944d349015d2b64c2414b06466a8194aa) --- source3/rpc_server/srv_pipe.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 68b3a2d434..716654103a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1284,7 +1284,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, RPC_AUTH_SCHANNEL_NEG neg; RPC_AUTH_VERIFIER auth_verifier; BOOL ret; - struct dcinfo stored_dcinfo; + struct dcinfo *pdcinfo; uint32 flags; if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) { @@ -1292,10 +1292,8 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, return False; } - ZERO_STRUCT(stored_dcinfo); - become_root(); - ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &stored_dcinfo); + ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &pdcinfo); unbecome_root(); if (!ret) { @@ -1305,29 +1303,24 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, p->auth.a_u.schannel_auth = TALLOC_P(p->pipe_state_mem_ctx, struct schannel_auth_struct); if (!p->auth.a_u.schannel_auth) { + talloc_free(pdcinfo); return False; } memset(p->auth.a_u.schannel_auth->sess_key, 0, sizeof(p->auth.a_u.schannel_auth->sess_key)); - memcpy(p->auth.a_u.schannel_auth->sess_key, stored_dcinfo.sess_key, sizeof(stored_dcinfo.sess_key)); + memcpy(p->auth.a_u.schannel_auth->sess_key, pdcinfo->sess_key, + sizeof(pdcinfo->sess_key)); + + talloc_free(pdcinfo); p->auth.a_u.schannel_auth->seq_num = 0; /* * JRA. Should we also copy the schannel session key into the pipe session key p->session_key - * here ? We do that for NTLMSPP, but the session key is already set up from the vuser + * here ? We do that for NTLMSSP, but the session key is already set up from the vuser * struct of the person who opened the pipe. I need to test this further. JRA. */ - /* The client opens a second RPC NETLOGON pipe without - doing a auth2. The credentials for the schannel are - re-used from the auth2 the client did before. */ - p->dc = TALLOC_ZERO_P(p->pipe_state_mem_ctx, struct dcinfo); - if (!p->dc) { - return False; - } - *p->dc = stored_dcinfo; - init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); -- cgit From 3403fc2d4966e7b2e29ec45ecdc53332302427e4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Feb 2006 23:57:28 +0000 Subject: r13552: Make sure we're using the same name to load the stored creds under all circumstances. This may be wrong, but at least we're now consistent. Jeremy. (This used to be commit 09f0b3e1a366ba3eef4ab9a8e302daabd4f36936) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 716654103a..23419d5c55 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1293,7 +1293,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, } become_root(); - ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &pdcinfo); + ret = secrets_restore_schannel_session_info(p->mem_ctx, get_remote_machine_name(), &pdcinfo); unbecome_root(); if (!ret) { -- cgit From 0bc643620b38e647d62140d545c042e459df9a6c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 18 Feb 2006 01:21:18 +0000 Subject: r13557: (Hopefully) get the creds store/restore key right from the correct part of the netlogon and schannel packets. Jeremy. (This used to be commit 4877f336b257e6f59833a6e0679959a2ec879974) --- source3/rpc_server/srv_pipe.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 23419d5c55..3ed33ca691 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1292,8 +1292,14 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, return False; } + /* + * The neg.myname key here must match the remote computer name + * given in the DOM_CLNT_SRV.uni_comp_name used on all netlogon pipe + * operations that use credentials. + */ + become_root(); - ret = secrets_restore_schannel_session_info(p->mem_ctx, get_remote_machine_name(), &pdcinfo); + ret = secrets_restore_schannel_session_info(p->mem_ctx, neg.myname, &pdcinfo); unbecome_root(); if (!ret) { -- cgit From fb5362c069b5b6548478b2217a0519c56d856705 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 20 Feb 2006 17:59:58 +0000 Subject: r13571: Replace all calls to talloc_free() with thye TALLOC_FREE() macro which sets the freed pointer to NULL. (This used to be commit b65be8874a2efe5a4b167448960a4fcf6bd995e2) --- source3/rpc_server/srv_pipe.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3ed33ca691..67fb89ef79 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -616,7 +616,7 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) memset(p->wks, '\0', sizeof(p->wks)); /* Set up for non-authenticated user. */ - talloc_free(p->pipe_user.nt_user_token); + TALLOC_FREE(p->pipe_user.nt_user_token); p->pipe_user.ut.ngroups = 0; SAFE_FREE( p->pipe_user.ut.groups); @@ -1309,7 +1309,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, p->auth.a_u.schannel_auth = TALLOC_P(p->pipe_state_mem_ctx, struct schannel_auth_struct); if (!p->auth.a_u.schannel_auth) { - talloc_free(pdcinfo); + TALLOC_FREE(pdcinfo); return False; } @@ -1317,7 +1317,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, memcpy(p->auth.a_u.schannel_auth->sess_key, pdcinfo->sess_key, sizeof(pdcinfo->sess_key)); - talloc_free(pdcinfo); + TALLOC_FREE(pdcinfo); p->auth.a_u.schannel_auth->seq_num = 0; -- cgit From 894358a8f3e338b339b6c37233edef794b312087 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Mar 2006 06:31:04 +0000 Subject: r13915: Fixed a very interesting class of realloc() bugs found by Coverity. realloc can return NULL in one of two cases - (1) the realloc failed, (2) realloc succeeded but the new size requested was zero, in which case this is identical to a free() call. The error paths dealing with these two cases should be different, but mostly weren't. Secondly the standard idiom for dealing with realloc when you know the new size is non-zero is the following : tmp = realloc(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } However, there were *many* *many* places in Samba where we were using the old (broken) idiom of : p = realloc(p, size) if (!p) { return error; } which will leak the memory pointed to by p on realloc fail. This commit (hopefully) fixes all these cases by moving to a standard idiom of : p = SMB_REALLOC(p, size) if (!p) { return error; } Where if the realloc returns null due to the realloc failing or size == 0 we *guarentee* that the storage pointed to by p has been freed. This allows me to remove a lot of code that was dealing with the standard (more verbose) method that required a tmp pointer. This is almost always what you want. When a realloc fails you never usually want the old memory, you want to free it and get into your error processing asap. For the 11 remaining cases where we really do need to keep the old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR, which can be used as follows : tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the pointer p, even on size == 0 or realloc fail. All this is done by a hidden extra argument to Realloc(), BOOL free_old_on_error which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR macros (and their array counterparts). It remains to be seen what this will do to our Coverity bug count :-). Jeremy. (This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0) --- source3/rpc_server/srv_pipe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 67fb89ef79..eb7fd25daa 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1032,7 +1032,7 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s rpc_lookup will still be valid afterwards. It could then succeed if called again later */ rpc_lookup_size++; - rpc_entry = SMB_REALLOC_ARRAY(rpc_lookup, struct rpc_table, rpc_lookup_size); + rpc_entry = SMB_REALLOC_ARRAY_KEEP_OLD_ON_ERROR(rpc_lookup, struct rpc_table, rpc_lookup_size); if (NULL == rpc_entry) { rpc_lookup_size--; DEBUG(0, ("rpc_pipe_register_commands: memory allocation failed\n")); @@ -1046,6 +1046,9 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s rpc_entry->pipe.clnt = SMB_STRDUP(clnt); rpc_entry->pipe.srv = SMB_STRDUP(srv); rpc_entry->cmds = SMB_REALLOC_ARRAY(rpc_entry->cmds, struct api_struct, rpc_entry->n_cmds + size); + if (!rpc_entry->cmds) { + return NT_STATUS_NO_MEMORY; + } memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds, size * sizeof(struct api_struct)); rpc_entry->n_cmds += size; -- cgit From 1d5ab8fd05123dd46e64a6249db2928c89aec2f2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 21 Mar 2006 00:04:05 +0000 Subject: r14597: Merge DCERPC_FAULT constants from Samba 4. Guenther (This used to be commit 3f195f8248c88ec8bf8ceb195575ce6bb49d7fc4) --- source3/rpc_server/srv_pipe.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index eb7fd25daa..9b6fcb2f15 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -71,7 +71,7 @@ static BOOL create_next_pdu_ntlmssp(pipes_struct *p) */ if(p->fault_state) { - setup_fault_pdu(p, NT_STATUS(0x1c010002)); + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); return True; } @@ -284,7 +284,7 @@ static BOOL create_next_pdu_schannel(pipes_struct *p) */ if(p->fault_state) { - setup_fault_pdu(p, NT_STATUS(0x1c010002)); + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); return True; } @@ -460,7 +460,7 @@ static BOOL create_next_pdu_noauth(pipes_struct *p) */ if(p->fault_state) { - setup_fault_pdu(p, NT_STATUS(0x1c010002)); + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); return True; } @@ -2250,7 +2250,7 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, * and not put the pipe into fault state. JRA. */ DEBUG(4, ("unknown\n")); - setup_fault_pdu(p, NT_STATUS(0x1c010002)); + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); return True; } @@ -2268,7 +2268,7 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, if (p->bad_handle_fault_state) { DEBUG(4,("api_rpcTNP: bad handle fault return.\n")); p->bad_handle_fault_state = False; - setup_fault_pdu(p, NT_STATUS(0x1C00001A)); + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_CONTEXT_MISMATCH)); return True; } -- cgit From 0498f3b8890ec62eeb9275a6bf685a6c3d81fce5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Apr 2006 18:00:57 +0000 Subject: r15129: Separate out mechanism and policy for NTLMSSP auth/sign/seal. With this change (and setting lanman auth = no in smb.conf) we have *identical* NTLMSSP flags to W2K3 in SPNEGO auth. Jeremy (This used to be commit 93ca3eee55297eb7fdd38fca38103ce129987e2a) --- source3/rpc_server/srv_pipe.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 9b6fcb2f15..72298520e3 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -606,7 +606,7 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) NTSTATUS status; AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state; - DEBUG(5,("pipe_ntlmssp_verify_final: checking user details\n")); + DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n", p->name)); ZERO_STRUCT(reply); @@ -629,6 +629,27 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } + /* Finally - if the pipe negotiated integrity (sign) or privacy (seal) + ensure the underlying NTLMSSP flags are also set. If not we should + refuse the bind. */ + + if (p->auth.auth_level == PIPE_AUTH_LEVEL_INTEGRITY) { + if (!(a->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet integrity requested " + "but client declined signing.\n", + p->name )); + return False; + } + } + if (p->auth.auth_level == PIPE_AUTH_LEVEL_PRIVACY) { + if (!(a->ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + DEBUG(0,("pipe_ntlmssp_verify_final: pipe %s : packet privacy requested " + "but client declined sealing.\n", + p->name )); + return False; + } + } + fstrcpy(p->user_name, a->ntlmssp_state->user); fstrcpy(p->pipe_user_name, a->server_info->unix_name); fstrcpy(p->domain, a->ntlmssp_state->domain); -- cgit From d1014c1cdfce116741ddd6eccd65b69530ce0b84 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 00:50:14 +0000 Subject: r16582: Fix Klocwork #1997 and all generic class of problems where we don't correctly check the return from memdup. Jeremy. (This used to be commit ce14daf51c7ee2f9c68c77f7f4674e6f0e35c9ca) --- source3/rpc_server/srv_pipe.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 72298520e3..1c91735756 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -679,7 +679,8 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) if (p->pipe_user.ut.ngroups) { if (!(p->pipe_user.ut.groups = memdup(a->server_info->groups, sizeof(gid_t) * p->pipe_user.ut.ngroups))) { - DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); + DEBUG(0,("pipe_ntlmssp_verify_final: failed to memdup group list to p->pipe_user.groups\n")); + data_blob_free(&p->session_key); return False; } } @@ -687,9 +688,17 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) if (a->server_info->ptok) { p->pipe_user.nt_user_token = dup_nt_token(NULL, a->server_info->ptok); + if (!p->pipe_user.nt_user_token) { + DEBUG(1,("pipe_ntlmssp_verify_final: dup_nt_token failed.\n")); + data_blob_free(&p->session_key); + SAFE_FREE(p->pipe_user.ut.groups); + return False; + } + } else { - DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); - p->pipe_user.nt_user_token = NULL; + DEBUG(1,("pipe_ntlmssp_verify_final: Error: Authmodule failed to provide nt_user_token\n")); + data_blob_free(&p->session_key); + SAFE_FREE(p->pipe_user.ut.groups); return False; } -- cgit From 26c0b81d757d711646239fc55ed326fa3b0180cc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 3 Jul 2006 16:12:16 +0000 Subject: r16785: BUG 3908: Fix rpc bin authentication failure which broke user password changes Jeremy, please review. (This used to be commit 154e4a281503f0cbc2e654640f1dfa4b4d35a3cd) --- source3/rpc_server/srv_pipe.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 1c91735756..812a720d90 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -620,7 +620,10 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.ngroups = 0; SAFE_FREE( p->pipe_user.ut.groups); + /* this has to be done as root in order to verify the password */ + become_root(); status = auth_ntlmssp_update(a, *p_resp_blob, &reply); + unbecome_root(); /* Don't generate a reply. */ data_blob_free(&reply); -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/rpc_server/srv_pipe.c | 105 ++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 49 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 812a720d90..e2c5e865ed 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -46,6 +46,11 @@ static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) auth->a_u.auth_ntlmssp_state = NULL; } +static DATA_BLOB generic_session_key(void) +{ + return data_blob("SystemLibraryDTC", 16); +} + /******************************************************************* Generate the next PDU to be returned from the data in p->rdata. Handle NTLMSSP. @@ -610,16 +615,6 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) ZERO_STRUCT(reply); - memset(p->user_name, '\0', sizeof(p->user_name)); - memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); - memset(p->domain, '\0', sizeof(p->domain)); - memset(p->wks, '\0', sizeof(p->wks)); - - /* Set up for non-authenticated user. */ - TALLOC_FREE(p->pipe_user.nt_user_token); - p->pipe_user.ut.ngroups = 0; - SAFE_FREE( p->pipe_user.ut.groups); - /* this has to be done as root in order to verify the password */ become_root(); status = auth_ntlmssp_update(a, *p_resp_blob, &reply); @@ -632,6 +627,12 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } + if (a->server_info->ptok == NULL) { + DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); + p->pipe_user.nt_user_token = NULL; + return False; + } + /* Finally - if the pipe negotiated integrity (sign) or privacy (seal) ensure the underlying NTLMSSP flags are also set. If not we should refuse the bind. */ @@ -653,13 +654,9 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) } } - fstrcpy(p->user_name, a->ntlmssp_state->user); - fstrcpy(p->pipe_user_name, a->server_info->unix_name); - fstrcpy(p->domain, a->ntlmssp_state->domain); - fstrcpy(p->wks, a->ntlmssp_state->workstation); - DEBUG(5,("pipe_ntlmssp_verify_final: OK: user: %s domain: %s workstation: %s\n", - p->user_name, p->domain, p->wks)); + a->ntlmssp_state->user, a->ntlmssp_state->domain, + a->ntlmssp_state->workstation)); /* * Store the UNIX credential data (uid/gid pair) in the pipe structure. @@ -669,11 +666,13 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.gid = a->server_info->gid; /* - * Copy the session key from the ntlmssp state. + * We're an authenticated bind over smb, so the session key needs to + * be set to "SystemLibraryDTC". Weird, but this is what Windows + * does. See the RPC-SAMBA3SESSIONKEY. */ data_blob_free(&p->session_key); - p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length); + p->session_key = generic_session_key(); if (!p->session_key.data) { return False; } @@ -688,23 +687,21 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) } } - if (a->server_info->ptok) { - p->pipe_user.nt_user_token = - dup_nt_token(NULL, a->server_info->ptok); - if (!p->pipe_user.nt_user_token) { - DEBUG(1,("pipe_ntlmssp_verify_final: dup_nt_token failed.\n")); - data_blob_free(&p->session_key); - SAFE_FREE(p->pipe_user.ut.groups); - return False; - } - - } else { + if (!a->server_info->ptok) { DEBUG(1,("pipe_ntlmssp_verify_final: Error: Authmodule failed to provide nt_user_token\n")); data_blob_free(&p->session_key); SAFE_FREE(p->pipe_user.ut.groups); return False; } + p->pipe_user.nt_user_token = dup_nt_token(NULL, a->server_info->ptok); + if (!p->pipe_user.nt_user_token) { + DEBUG(1,("pipe_ntlmssp_verify_final: dup_nt_token failed.\n")); + data_blob_free(&p->session_key); + SAFE_FREE(p->pipe_user.ut.groups); + return False; + } + return True; } @@ -1361,8 +1358,21 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, * JRA. Should we also copy the schannel session key into the pipe session key p->session_key * here ? We do that for NTLMSSP, but the session key is already set up from the vuser * struct of the person who opened the pipe. I need to test this further. JRA. + * + * VL. As we are mapping this to guest set the generic key + * "SystemLibraryDTC" key here. It's a bit difficult to test against + * W2k3, as it does not allow schannel binds against SAMR and LSA + * anymore. */ + data_blob_free(&p->session_key); + p->session_key = generic_session_key(); + if (p->session_key.data == NULL) { + DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session" + " key\n")); + return False; + } + init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); @@ -1391,6 +1401,12 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, p->auth.auth_data_free_func = NULL; p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL; + if (!set_current_user_guest(&p->pipe_user)) { + DEBUG(1, ("pipe_schannel_auth_bind: Could not set guest " + "token\n")); + return False; + } + p->pipe_bound = True; return True; @@ -1641,11 +1657,18 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) case RPC_ANONYMOUS_AUTH_TYPE: /* Unauthenticated bind request. */ + /* Get the authenticated pipe user from current_user */ + if (!copy_current_user(&p->pipe_user, ¤t_user)) { + DEBUG(10, ("Could not copy current user\n")); + goto err_exit; + } /* We're finished - no more packets. */ p->auth.auth_type = PIPE_AUTH_TYPE_NONE; /* We must set the pipe auth_level here also. */ p->auth.auth_level = PIPE_AUTH_LEVEL_NONE; p->pipe_bound = True; + /* The session key was initialized from the SMB + * session in make_internal_rpc_pipe_p */ break; default: @@ -2148,23 +2171,6 @@ BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss return True; } -/**************************************************************************** - Return a user struct for a pipe user. -****************************************************************************/ - -struct current_user *get_current_user(struct current_user *user, pipes_struct *p) -{ - if (p->pipe_bound && - (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP || - (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { - memcpy(user, &p->pipe_user, sizeof(struct current_user)); - } else { - memcpy(user, ¤t_user, sizeof(struct current_user)); - } - - return user; -} - /**************************************************************************** Find the set of RPC functions associated with this context_id ****************************************************************************/ @@ -2219,9 +2225,7 @@ BOOL api_pipe_request(pipes_struct *p) BOOL changed_user = False; PIPE_RPC_FNS *pipe_fns; - if (p->pipe_bound && - ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) || - (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { + if (p->pipe_bound) { if(!become_authenticated_pipe_user(p)) { prs_mem_free(&p->out_data.rdata); return False; @@ -2373,6 +2377,9 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_EVENTLOG: eventlog_get_pipe_fns( &cmds, &n_cmds ); break; + case PI_UNIXINFO: + unixinfo_get_pipe_fns( &cmds, &n_cmds ); + break; case PI_NTSVCS: ntsvcs_get_pipe_fns( &cmds, &n_cmds ); break; -- cgit From 430fa0eba08cbf180d83740a895a0018af1c7f21 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Jul 2006 21:40:25 +0000 Subject: r17348: Some C++ warnings (This used to be commit ae6b9b34e59167e3958bfdb9997fa25340b9a0a3) --- source3/rpc_server/srv_pipe.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index e2c5e865ed..74583f075b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -679,8 +679,9 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.ngroups = a->server_info->n_groups; if (p->pipe_user.ut.ngroups) { - if (!(p->pipe_user.ut.groups = memdup(a->server_info->groups, - sizeof(gid_t) * p->pipe_user.ut.ngroups))) { + if (!(p->pipe_user.ut.groups = (gid_t *) + memdup(a->server_info->groups, + sizeof(gid_t) * p->pipe_user.ut.ngroups))) { DEBUG(0,("pipe_ntlmssp_verify_final: failed to memdup group list to p->pipe_user.groups\n")); data_blob_free(&p->session_key); return False; @@ -2322,7 +2323,7 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, if ((DEBUGLEVEL >= 10) && (prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) { size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data); - char *data = SMB_MALLOC(data_len); + char *data = (char *)SMB_MALLOC(data_len); DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n")); if (data) { -- cgit From e5db7fee0f5cb3bd7434cdefebabc7a8376aa0d4 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 15 Sep 2006 22:49:27 +0000 Subject: r18572: Use the autogenerated client and server for the echo interface and implement some of the missing functions. RPC-ECHO now passes against Samba3. (This used to be commit 9e9a05366176454cc1779acc6c2b6070743f5939) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 74583f075b..4c798e4300 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2385,8 +2385,8 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) ntsvcs_get_pipe_fns( &cmds, &n_cmds ); break; #ifdef DEVELOPER - case PI_ECHO: - echo_get_pipe_fns( &cmds, &n_cmds ); + case PI_RPCECHO: + rpcecho_get_pipe_fns( &cmds, &n_cmds ); break; #endif default: -- cgit From 4e7d11449ad419f4fa791e26e059a9f73d6d4042 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 19 Sep 2006 00:12:11 +0000 Subject: r18654: Rename "struct uuid" => "struct GUID" for consistency. (This used to be commit 5de76767e857e9d159ea46e2ded612ccd6d6bf19) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4c798e4300..5abf1c293a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -997,9 +997,9 @@ BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, DEBUG(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) - && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct uuid)) == 0) + && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct GUID)) == 0) && (transfer->version == pipe_names[i].trans_syntax.version) - && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct uuid)) == 0) ) { + && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct GUID)) == 0) ) { struct api_struct *fns = NULL; int n_fns = 0; PIPE_RPC_FNS *context_fns; -- cgit From eab57a0a0fe90be464f5061691f57ca1da150885 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 21 Sep 2006 17:51:06 +0000 Subject: r18789: Replace the winreg server code with the libndr parsing code. Many things work (OpenHKLM, etc...) but some still don't. This shouldn't block anyone so I'm checking it in. Will probably move to a bzr tree after this for longer dev cycles between checkins. (This used to be commit cf1404a0d7538288b9370ba80df328f81b713ce0) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5abf1c293a..b60ee37f40 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2364,7 +2364,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) wkssvc_get_pipe_fns( &cmds, &n_cmds ); break; case PI_WINREG: - reg_get_pipe_fns( &cmds, &n_cmds ); + winreg_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SPOOLSS: spoolss_get_pipe_fns( &cmds, &n_cmds ); -- cgit From b71a0be998c0171a01c632f3e14e9764c2dda6c2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 10 Oct 2006 07:53:41 +0000 Subject: r19220: Check if a backend has set rng_fault_state and send a dce-level fault pdu. Volker (This used to be commit 21c08e7ef460ae7eaf1f441e8aadcfe0502fa1ad) --- source3/rpc_server/srv_pipe.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index b60ee37f40..50ef195015 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2310,6 +2310,13 @@ BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, return True; } + if (p->rng_fault_state) { + DEBUG(4, ("api_rpcTNP: rng fault return\n")); + p->rng_fault_state = False; + setup_fault_pdu(p, NT_STATUS(DCERPC_FAULT_OP_RNG_ERROR)); + return True; + } + slprintf(name, sizeof(name)-1, "out_%s", rpc_name); offset2 = prs_offset(&p->out_data.rdata); prs_set_offset(&p->out_data.rdata, offset1); -- cgit From 0389cad7c492eda5aee590d0396748c7da9b44ff Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 3 Apr 2007 12:28:40 +0000 Subject: r22055: Port the endpoint mapper (and functions it requires) to Samba 3. (This used to be commit ad981261877e6a2dce0c4f4e71fd9127aa31538a) --- source3/rpc_server/srv_pipe.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 50ef195015..83c059d36c 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2382,7 +2382,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_SVCCTL: svcctl_get_pipe_fns( &cmds, &n_cmds ); break; - case PI_EVENTLOG: + case PI_EVENTLOG: eventlog_get_pipe_fns( &cmds, &n_cmds ); break; case PI_UNIXINFO: @@ -2396,6 +2396,9 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) rpcecho_get_pipe_fns( &cmds, &n_cmds ); break; #endif + case PI_EPMAPPER: + epmapper_get_pipe_fns( &cmds, &n_cmds ); + break; default: DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx)); } -- cgit From 97a164ba96d48a81d5e24dda6b866a4d78ea1a78 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 31 May 2007 17:59:04 +0000 Subject: r23274: merge CloseEventlog() pidl conversion from 3.0.26 && fix a few init call renames for svcctl in the previous commit (This used to be commit ebcae48ec10fefa74efcc3563cff50e3b9c2388c) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 83c059d36c..8aab80db72 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2380,10 +2380,10 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) netdfs_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SVCCTL: - svcctl_get_pipe_fns( &cmds, &n_cmds ); + svcctl2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_EVENTLOG: - eventlog_get_pipe_fns( &cmds, &n_cmds ); + eventlog2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_UNIXINFO: unixinfo_get_pipe_fns( &cmds, &n_cmds ); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 8aab80db72..3ab628959d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -5,7 +5,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, -- cgit From 153cfb9c83534b09f15cc16205d7adb19b394928 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 05:23:25 +0000 Subject: r23801: The FSF has moved around a lot. This fixes their Mass Ave address. (This used to be commit 87c91e4362c51819032bfbebbb273c52e203b227) --- source3/rpc_server/srv_pipe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3ab628959d..7493aaddb9 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ /* this module apparently provides an implementation of DCE/RPC over a -- cgit From 929e1d99209e20a9c2c95c8bdfc8eaa37b2c2291 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 30 Aug 2007 19:48:31 +0000 Subject: r24809: Consolidate the use of temporary talloc contexts. This adds the two functions talloc_stackframe() and talloc_tos(). * When a new talloc stackframe is allocated with talloc_stackframe(), then * the TALLOC_CTX returned with talloc_tos() is reset to that new * frame. Whenever that stack frame is TALLOC_FREE()'ed, then the reverse * happens: The previous talloc_tos() is restored. * * This API is designed to be robust in the sense that if someone forgets to * TALLOC_FREE() a stackframe, then the next outer one correctly cleans up and * resets the talloc_tos(). The original motivation for this patch was to get rid of the sid_string_static & friends buffers. Explicitly passing talloc context everywhere clutters code too much for my taste, so an implicit talloc_tos() is introduced here. Many of these static buffers are replaced by a single static pointer. The intended use would thus be that low-level functions can rather freely push stuff to talloc_tos, the upper layers clean up by freeing the stackframe. The more of these stackframes are used and correctly freed the more exact the memory cleanup happens. This patch removes the main_loop_talloc_ctx, tmp_talloc_ctx and lp_talloc_ctx (did I forget any?) So, never do a tmp_ctx = talloc_init("foo"); anymore, instead, use tmp_ctx = talloc_stackframe() :-) Volker (This used to be commit 6585ea2cb7f417e14540495b9c7380fe9c8c717b) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7493aaddb9..fefdb529b2 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2240,9 +2240,9 @@ BOOL api_pipe_request(pipes_struct *p) pipe_fns = find_pipe_fns_by_context(p->contexts, p->hdr_req.context_id); if ( pipe_fns ) { - set_current_rpc_talloc(p->mem_ctx); + TALLOC_CTX *frame = talloc_stackframe(); ret = api_rpcTNP(p, p->name, pipe_fns->cmds, pipe_fns->n_cmds); - set_current_rpc_talloc(NULL); + TALLOC_FREE(frame); } else { DEBUG(0,("api_pipe_request: No rpc function table associated with context [%d] on pipe [%s]\n", -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/rpc_server/srv_pipe.c | 111 +++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 62 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index fefdb529b2..72ce72fb28 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -45,11 +45,6 @@ static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) auth->a_u.auth_ntlmssp_state = NULL; } -static DATA_BLOB generic_session_key(void) -{ - return data_blob("SystemLibraryDTC", 16); -} - /******************************************************************* Generate the next PDU to be returned from the data in p->rdata. Handle NTLMSSP. @@ -614,6 +609,16 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) ZERO_STRUCT(reply); + memset(p->user_name, '\0', sizeof(p->user_name)); + memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); + memset(p->domain, '\0', sizeof(p->domain)); + memset(p->wks, '\0', sizeof(p->wks)); + + /* Set up for non-authenticated user. */ + TALLOC_FREE(p->pipe_user.nt_user_token); + p->pipe_user.ut.ngroups = 0; + SAFE_FREE( p->pipe_user.ut.groups); + /* this has to be done as root in order to verify the password */ become_root(); status = auth_ntlmssp_update(a, *p_resp_blob, &reply); @@ -626,12 +631,6 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } - if (a->server_info->ptok == NULL) { - DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); - p->pipe_user.nt_user_token = NULL; - return False; - } - /* Finally - if the pipe negotiated integrity (sign) or privacy (seal) ensure the underlying NTLMSSP flags are also set. If not we should refuse the bind. */ @@ -653,9 +652,13 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) } } + fstrcpy(p->user_name, a->ntlmssp_state->user); + fstrcpy(p->pipe_user_name, a->server_info->unix_name); + fstrcpy(p->domain, a->ntlmssp_state->domain); + fstrcpy(p->wks, a->ntlmssp_state->workstation); + DEBUG(5,("pipe_ntlmssp_verify_final: OK: user: %s domain: %s workstation: %s\n", - a->ntlmssp_state->user, a->ntlmssp_state->domain, - a->ntlmssp_state->workstation)); + p->user_name, p->domain, p->wks)); /* * Store the UNIX credential data (uid/gid pair) in the pipe structure. @@ -665,40 +668,30 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.gid = a->server_info->gid; /* - * We're an authenticated bind over smb, so the session key needs to - * be set to "SystemLibraryDTC". Weird, but this is what Windows - * does. See the RPC-SAMBA3SESSIONKEY. + * Copy the session key from the ntlmssp state. */ data_blob_free(&p->session_key); - p->session_key = generic_session_key(); + p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length); if (!p->session_key.data) { return False; } p->pipe_user.ut.ngroups = a->server_info->n_groups; if (p->pipe_user.ut.ngroups) { - if (!(p->pipe_user.ut.groups = (gid_t *) - memdup(a->server_info->groups, - sizeof(gid_t) * p->pipe_user.ut.ngroups))) { - DEBUG(0,("pipe_ntlmssp_verify_final: failed to memdup group list to p->pipe_user.groups\n")); - data_blob_free(&p->session_key); + if (!(p->pipe_user.ut.groups = (gid_t *)memdup(a->server_info->groups, + sizeof(gid_t) * p->pipe_user.ut.ngroups))) { + DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); return False; } } - if (!a->server_info->ptok) { - DEBUG(1,("pipe_ntlmssp_verify_final: Error: Authmodule failed to provide nt_user_token\n")); - data_blob_free(&p->session_key); - SAFE_FREE(p->pipe_user.ut.groups); - return False; - } - - p->pipe_user.nt_user_token = dup_nt_token(NULL, a->server_info->ptok); - if (!p->pipe_user.nt_user_token) { - DEBUG(1,("pipe_ntlmssp_verify_final: dup_nt_token failed.\n")); - data_blob_free(&p->session_key); - SAFE_FREE(p->pipe_user.ut.groups); + if (a->server_info->ptok) { + p->pipe_user.nt_user_token = + dup_nt_token(NULL, a->server_info->ptok); + } else { + DEBUG(1,("Error: Authmodule failed to provide nt_user_token\n")); + p->pipe_user.nt_user_token = NULL; return False; } @@ -1358,21 +1351,8 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, * JRA. Should we also copy the schannel session key into the pipe session key p->session_key * here ? We do that for NTLMSSP, but the session key is already set up from the vuser * struct of the person who opened the pipe. I need to test this further. JRA. - * - * VL. As we are mapping this to guest set the generic key - * "SystemLibraryDTC" key here. It's a bit difficult to test against - * W2k3, as it does not allow schannel binds against SAMR and LSA - * anymore. */ - data_blob_free(&p->session_key); - p->session_key = generic_session_key(); - if (p->session_key.data == NULL) { - DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session" - " key\n")); - return False; - } - init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); @@ -1401,12 +1381,6 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, p->auth.auth_data_free_func = NULL; p->auth.auth_type = PIPE_AUTH_TYPE_SCHANNEL; - if (!set_current_user_guest(&p->pipe_user)) { - DEBUG(1, ("pipe_schannel_auth_bind: Could not set guest " - "token\n")); - return False; - } - p->pipe_bound = True; return True; @@ -2171,6 +2145,23 @@ BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss return True; } +/**************************************************************************** + Return a user struct for a pipe user. +****************************************************************************/ + +struct current_user *get_current_user(struct current_user *user, pipes_struct *p) +{ + if (p->pipe_bound && + (p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP || + (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { + memcpy(user, &p->pipe_user, sizeof(struct current_user)); + } else { + memcpy(user, ¤t_user, sizeof(struct current_user)); + } + + return user; +} + /**************************************************************************** Find the set of RPC functions associated with this context_id ****************************************************************************/ @@ -2225,7 +2216,9 @@ BOOL api_pipe_request(pipes_struct *p) BOOL changed_user = False; PIPE_RPC_FNS *pipe_fns; - if (p->pipe_bound) { + if (p->pipe_bound && + ((p->auth.auth_type == PIPE_AUTH_TYPE_NTLMSSP) || + (p->auth.auth_type == PIPE_AUTH_TYPE_SPNEGO_NTLMSSP))) { if(!become_authenticated_pipe_user(p)) { prs_mem_free(&p->out_data.rdata); return False; @@ -2364,7 +2357,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) netlog_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SRVSVC: - srvsvc_get_pipe_fns( &cmds, &n_cmds ); + srvsvc2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_WKSSVC: wkssvc_get_pipe_fns( &cmds, &n_cmds ); @@ -2381,12 +2374,9 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_SVCCTL: svcctl2_get_pipe_fns( &cmds, &n_cmds ); break; - case PI_EVENTLOG: + case PI_EVENTLOG: eventlog2_get_pipe_fns( &cmds, &n_cmds ); break; - case PI_UNIXINFO: - unixinfo_get_pipe_fns( &cmds, &n_cmds ); - break; case PI_NTSVCS: ntsvcs_get_pipe_fns( &cmds, &n_cmds ); break; @@ -2395,9 +2385,6 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) rpcecho_get_pipe_fns( &cmds, &n_cmds ); break; #endif - case PI_EPMAPPER: - epmapper_get_pipe_fns( &cmds, &n_cmds ); - break; default: DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx)); } -- cgit From 7ed90852c5aae0f3dc71b07f22a5f983985c2086 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 Jun 2006 20:38:21 +0000 Subject: r16050: Set the session key "SystemLibraryDTC" on ntlmssp binds. We only do INTEGRITY and PRIVACY, so no other cases to take care of so far... Andrew B., if you have time, could you take a look? This makes us survive the RPC-SAMBA3SESSIONKEY test. Volker (cherry picked from commit 25cc1e7ff15675b70001d1cb8d8584880650dd2e) (This used to be commit b4746009735bf66b2578b884973c505b0363a79d) --- source3/rpc_server/srv_pipe.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 72ce72fb28..c213ec556a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -45,6 +45,11 @@ static void free_pipe_ntlmssp_auth_data(struct pipe_auth_data *auth) auth->a_u.auth_ntlmssp_state = NULL; } +static DATA_BLOB generic_session_key(void) +{ + return data_blob("SystemLibraryDTC", 16); +} + /******************************************************************* Generate the next PDU to be returned from the data in p->rdata. Handle NTLMSSP. @@ -668,11 +673,13 @@ static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.gid = a->server_info->gid; /* - * Copy the session key from the ntlmssp state. + * We're an authenticated bind over smbd, so the session key needs to + * be set to "SystemLibraryDTC". Weird, but this is what Windows + * does. See the RPC-SAMBA3SESSIONKEY. */ data_blob_free(&p->session_key); - p->session_key = data_blob(a->ntlmssp_state->session_key.data, a->ntlmssp_state->session_key.length); + p->session_key = generic_session_key(); if (!p->session_key.data) { return False; } @@ -1351,8 +1358,21 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, * JRA. Should we also copy the schannel session key into the pipe session key p->session_key * here ? We do that for NTLMSSP, but the session key is already set up from the vuser * struct of the person who opened the pipe. I need to test this further. JRA. + * + * VL. As we are mapping this to guest set the generic key + * "SystemLibraryDTC" key here. It's a bit difficult to test against + * W2k3, as it does not allow schannel binds against SAMR and LSA + * anymore. */ + data_blob_free(&p->session_key); + p->session_key = generic_session_key(); + if (p->session_key.data == NULL) { + DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session" + " key\n")); + return False; + } + init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); if(!smb_io_rpc_hdr_auth("", &auth_info, pout_auth, 0)) { DEBUG(0,("pipe_schannel_auth_bind: marshalling of RPC_HDR_AUTH failed.\n")); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/rpc_server/srv_pipe.c | 52 +++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 26 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index c213ec556a..49ffcf13a6 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -55,7 +55,7 @@ static DATA_BLOB generic_session_key(void) Handle NTLMSSP. ********************************************************************/ -static BOOL create_next_pdu_ntlmssp(pipes_struct *p) +static bool create_next_pdu_ntlmssp(pipes_struct *p) { RPC_HDR_RESP hdr_resp; uint32 ss_padding_len = 0; @@ -272,7 +272,7 @@ static BOOL create_next_pdu_ntlmssp(pipes_struct *p) Return an schannel authenticated fragment. ********************************************************************/ -static BOOL create_next_pdu_schannel(pipes_struct *p) +static bool create_next_pdu_schannel(pipes_struct *p) { RPC_HDR_RESP hdr_resp; uint32 ss_padding_len = 0; @@ -450,7 +450,7 @@ static BOOL create_next_pdu_schannel(pipes_struct *p) No authentication done. ********************************************************************/ -static BOOL create_next_pdu_noauth(pipes_struct *p) +static bool create_next_pdu_noauth(pipes_struct *p) { RPC_HDR_RESP hdr_resp; uint32 data_len; @@ -571,7 +571,7 @@ static BOOL create_next_pdu_noauth(pipes_struct *p) Generate the next PDU to be returned from the data in p->rdata. ********************************************************************/ -BOOL create_next_pdu(pipes_struct *p) +bool create_next_pdu(pipes_struct *p) { switch(p->auth.auth_level) { case PIPE_AUTH_LEVEL_NONE: @@ -604,7 +604,7 @@ BOOL create_next_pdu(pipes_struct *p) the pipe struct. *******************************************************************/ -static BOOL pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) +static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) { DATA_BLOB reply; NTSTATUS status; @@ -725,7 +725,7 @@ static int rpc_lookup_size; This is the "stage3" NTLMSSP response after a bind request and reply. *******************************************************************/ -BOOL api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p) +bool api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p) { RPC_HDR_AUTH auth_info; uint32 pad; @@ -797,7 +797,7 @@ BOOL api_pipe_bind_auth3(pipes_struct *p, prs_struct *rpc_in_p) Marshall a bind_nak pdu. *******************************************************************/ -static BOOL setup_bind_nak(pipes_struct *p) +static bool setup_bind_nak(pipes_struct *p) { prs_struct outgoing_rpc; RPC_HDR nak_hdr; @@ -859,7 +859,7 @@ static BOOL setup_bind_nak(pipes_struct *p) Marshall a fault pdu. *******************************************************************/ -BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status) +bool setup_fault_pdu(pipes_struct *p, NTSTATUS status) { prs_struct outgoing_pdu; RPC_HDR fault_hdr; @@ -930,7 +930,7 @@ BOOL setup_fault_pdu(pipes_struct *p, NTSTATUS status) We should probably check the auth-verifier here. *******************************************************************/ -BOOL setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p) +bool setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p) { prs_struct outgoing_pdu; RPC_HDR ack_reply_hdr; @@ -978,7 +978,7 @@ BOOL setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p) Used to reject unknown binds from Win2k. *******************************************************************/ -BOOL check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, +bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, RPC_IFACE* transfer, uint32 context_id) { char *pipe_name = p->name; @@ -1089,7 +1089,7 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s Handle a SPNEGO krb5 bind auth. *******************************************************************/ -static BOOL pipe_spnego_auth_bind_kerberos(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, +static bool pipe_spnego_auth_bind_kerberos(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, DATA_BLOB *psecblob, prs_struct *pout_auth) { return False; @@ -1099,7 +1099,7 @@ static BOOL pipe_spnego_auth_bind_kerberos(pipes_struct *p, prs_struct *rpc_in_p Handle the first part of a SPNEGO bind auth. *******************************************************************/ -static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p, +static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) { DATA_BLOB blob; @@ -1109,7 +1109,7 @@ static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ char *OIDs[ASN1_MAX_OIDS]; int i; NTSTATUS status; - BOOL got_kerberos_mechanism = False; + bool got_kerberos_mechanism = False; AUTH_NTLMSSP_STATE *a = NULL; RPC_HDR_AUTH auth_info; @@ -1147,7 +1147,7 @@ static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ DEBUG(3,("pipe_spnego_auth_bind_negotiate: Got secblob of size %lu\n", (unsigned long)secblob.length)); if ( got_kerberos_mechanism && ((lp_security()==SEC_ADS) || lp_use_kerberos_keytab()) ) { - BOOL ret = pipe_spnego_auth_bind_kerberos(p, rpc_in_p, pauth_info, &secblob, pout_auth); + bool ret = pipe_spnego_auth_bind_kerberos(p, rpc_in_p, pauth_info, &secblob, pout_auth); data_blob_free(&secblob); data_blob_free(&blob); return ret; @@ -1220,7 +1220,7 @@ static BOOL pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ Handle the second part of a SPNEGO bind auth. *******************************************************************/ -static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p, +static bool pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) { RPC_HDR_AUTH auth_info; @@ -1310,13 +1310,13 @@ static BOOL pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p Handle an schannel bind auth. *******************************************************************/ -static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, +static bool pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) { RPC_HDR_AUTH auth_info; RPC_AUTH_SCHANNEL_NEG neg; RPC_AUTH_VERIFIER auth_verifier; - BOOL ret; + bool ret; struct dcinfo *pdcinfo; uint32 flags; @@ -1410,7 +1410,7 @@ static BOOL pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, Handle an NTLMSSP bind auth. *******************************************************************/ -static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, +static bool pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, RPC_HDR_AUTH *pauth_info, prs_struct *pout_auth) { RPC_HDR_AUTH auth_info; @@ -1491,7 +1491,7 @@ static BOOL pipe_ntlmssp_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, Respond to a pipe bind request. *******************************************************************/ -BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) +bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) { RPC_HDR_BA hdr_ba; RPC_HDR_RB hdr_rb; @@ -1771,7 +1771,7 @@ BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) SPNEGO calls. ****************************************************************************/ -BOOL api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p) +bool api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p) { RPC_HDR_BA hdr_ba; RPC_HDR_RB hdr_rb; @@ -1962,7 +1962,7 @@ BOOL api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p) Deal with NTLMSSP sign & seal processing on an RPC request. ****************************************************************************/ -BOOL api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in, +bool api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len, NTSTATUS *pstatus) { RPC_HDR_AUTH auth_info; @@ -2078,7 +2078,7 @@ BOOL api_pipe_ntlmssp_auth_process(pipes_struct *p, prs_struct *rpc_in, Deal with schannel processing on an RPC request. ****************************************************************************/ -BOOL api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len) +bool api_pipe_schannel_process(pipes_struct *p, prs_struct *rpc_in, uint32 *p_ss_padding_len) { uint32 data_len; uint32 auth_len; @@ -2230,10 +2230,10 @@ void free_pipe_rpc_context( PIPE_RPC_FNS *list ) before doing the call. ****************************************************************************/ -BOOL api_pipe_request(pipes_struct *p) +bool api_pipe_request(pipes_struct *p) { - BOOL ret = False; - BOOL changed_user = False; + bool ret = False; + bool changed_user = False; PIPE_RPC_FNS *pipe_fns; if (p->pipe_bound && @@ -2273,7 +2273,7 @@ BOOL api_pipe_request(pipes_struct *p) Calls the underlying RPC function for a named pipe. ********************************************************************/ -BOOL api_rpcTNP(pipes_struct *p, const char *rpc_name, +bool api_rpcTNP(pipes_struct *p, const char *rpc_name, const struct api_struct *api_rpc_cmds, int n_cmds) { int fn_num; -- cgit From 6bec071408c80a85dc2a7830d2cf4c48157b5187 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 9 Dec 2007 19:46:06 +0100 Subject: Don't copy the rpc function pointers This actually shows up in a valgrind massif run with 4.1% of allocated memory. I don't see why we would have to make a copy here. Metze? (This used to be commit 616d6b97e594a846e9b3ac4cbe48538d649462e9) --- source3/rpc_server/srv_pipe.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 49ffcf13a6..5ede0c93f4 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -714,7 +714,7 @@ struct rpc_table { const char *clnt; const char *srv; } pipe; - struct api_struct *cmds; + const struct api_struct *cmds; int n_cmds; }; @@ -1075,12 +1075,8 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s ZERO_STRUCTP(rpc_entry); rpc_entry->pipe.clnt = SMB_STRDUP(clnt); rpc_entry->pipe.srv = SMB_STRDUP(srv); - rpc_entry->cmds = SMB_REALLOC_ARRAY(rpc_entry->cmds, struct api_struct, rpc_entry->n_cmds + size); - if (!rpc_entry->cmds) { - return NT_STATUS_NO_MEMORY; - } - memcpy(rpc_entry->cmds + rpc_entry->n_cmds, cmds, size * sizeof(struct api_struct)); - rpc_entry->n_cmds += size; + rpc_entry->cmds = cmds; + rpc_entry->n_cmds = size; return NT_STATUS_OK; } -- cgit From 05ff7fd46e19d9c1aab8524495c9b926290927c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 25 Jan 2008 13:26:10 +0100 Subject: Use generated DSSETUP client & server rpc functions and remove the hand-written ones. Guenther (This used to be commit d5ebfccebb1f1b56b45673a506fcdb414103c43b) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 5ede0c93f4..06694a2701 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2363,8 +2363,8 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) case PI_LSARPC: lsa_get_pipe_fns( &cmds, &n_cmds ); break; - case PI_LSARPC_DS: - lsa_ds_get_pipe_fns( &cmds, &n_cmds ); + case PI_DSSETUP: + dssetup_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SAMR: samr_get_pipe_fns( &cmds, &n_cmds ); -- cgit From 3d507a2fcab9da3d9ba928fbe1d30f2642ab4e93 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 30 Jan 2008 12:53:09 +0100 Subject: Let _samr_Close() use pidl generated server code. Guenther (This used to be commit 2df3408079fc382d00d01a0b82b0b8e1ffeba6e4) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 06694a2701..8c7c43f686 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2367,7 +2367,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) dssetup_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SAMR: - samr_get_pipe_fns( &cmds, &n_cmds ); + samr2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NETLOGON: netlog_get_pipe_fns( &cmds, &n_cmds ); -- cgit From 80d20d8e54cd3bddf9011d0281a8d6bcdffc369c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 12 Feb 2008 14:26:10 +0100 Subject: w00t! SAMR server-side conversion to pidl is finished. Guenther (This used to be commit c6d9650930510982ef4e4759272dba573fc81067) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 8c7c43f686..06694a2701 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2367,7 +2367,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) dssetup_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SAMR: - samr2_get_pipe_fns( &cmds, &n_cmds ); + samr_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NETLOGON: netlog_get_pipe_fns( &cmds, &n_cmds ); -- cgit From ba9499e8dcdebda06ff1a3a38ad601011151410e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Feb 2008 18:08:23 -0800 Subject: Currently we don't SPNEGO negotiate back to NTLMSSP. Note this. Jeremy. (This used to be commit 67768fc71f9bd7ff3d61acc50360356b524ae923) --- source3/rpc_server/srv_pipe.c | 55 +++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 06694a2701..a671f89238 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1105,7 +1105,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ char *OIDs[ASN1_MAX_OIDS]; int i; NTSTATUS status; - bool got_kerberos_mechanism = False; + bool got_kerberos_mechanism = false; AUTH_NTLMSSP_STATE *a = NULL; RPC_HDR_AUTH auth_info; @@ -1133,7 +1133,7 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ } if (strcmp(OID_KERBEROS5, OIDs[0]) == 0 || strcmp(OID_KERBEROS5_OLD, OIDs[0]) == 0) { - got_kerberos_mechanism = True; + got_kerberos_mechanism = true; } for (i=0;OIDs[i];i++) { @@ -1154,27 +1154,38 @@ static bool pipe_spnego_auth_bind_negotiate(pipes_struct *p, prs_struct *rpc_in_ free_pipe_ntlmssp_auth_data(&p->auth); } - /* Initialize the NTLM engine. */ - status = auth_ntlmssp_start(&a); - if (!NT_STATUS_IS_OK(status)) { - goto err; - } + if (!got_kerberos_mechanism) { + /* Initialize the NTLM engine. */ + status = auth_ntlmssp_start(&a); + if (!NT_STATUS_IS_OK(status)) { + goto err; + } - /* - * Pass the first security blob of data to it. - * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED - * which means we need another packet to complete the bind. - */ + /* + * Pass the first security blob of data to it. + * This can return an error or NT_STATUS_MORE_PROCESSING_REQUIRED + * which means we need another packet to complete the bind. + */ - status = auth_ntlmssp_update(a, secblob, &chal); + status = auth_ntlmssp_update(a, secblob, &chal); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n")); - goto err; - } + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(3,("pipe_spnego_auth_bind_negotiate: auth_ntlmssp_update failed.\n")); + goto err; + } - /* Generate the response blob we need for step 2 of the bind. */ - response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP); + /* Generate the response blob we need for step 2 of the bind. */ + response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP); + } else { + /* + * SPNEGO negotiate down to NTLMSSP. The subsequent + * code to process follow-up packets is not complete + * yet. JRA. + */ + response = spnego_gen_auth_response(NULL, + NT_STATUS_MORE_PROCESSING_REQUIRED, + OID_NTLMSSP); + } /* Copy the blob into the pout_auth parse struct */ init_rpc_hdr_auth(&auth_info, RPC_SPNEGO_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); @@ -1231,6 +1242,10 @@ static bool pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p ZERO_STRUCT(auth_reply); ZERO_STRUCT(response); + /* + * NB. If we've negotiated down from krb5 to NTLMSSP we'll currently + * fail here as 'a' == NULL. + */ if (p->auth.auth_type != PIPE_AUTH_TYPE_SPNEGO_NTLMSSP || !a) { DEBUG(0,("pipe_spnego_auth_bind_continue: not in NTLMSSP auth state.\n")); goto err; @@ -1259,7 +1274,7 @@ static bool pipe_spnego_auth_bind_continue(pipes_struct *p, prs_struct *rpc_in_p * The following call actually checks the challenge/response data. * for correctness against the given DOMAIN\user name. */ - + if (!pipe_ntlmssp_verify_final(p, &auth_blob)) { goto err; } -- cgit From b4989afbab6e795c08bda37e500898d86a943b94 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 16 Feb 2008 13:42:12 +0100 Subject: YES! NETLOGON rpc server side migration to pidl finished. Guenther (This used to be commit 7845a0d9a8f938c1be888ab2d9aa6c35d6f1dbad) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a671f89238..de9f22da1d 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2385,7 +2385,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) samr_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NETLOGON: - netlog_get_pipe_fns( &cmds, &n_cmds ); + netlogon_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SRVSVC: srvsvc2_get_pipe_fns( &cmds, &n_cmds ); -- cgit From d8fcfb161540d3cb6d64f04b82dbf9590c1d5c9b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 23:03:22 +0100 Subject: Build the generated ntsvcs server (not at all useable yet). Guenther (This used to be commit acce1092d90db1f90265de44fd340d7df73e4e0e) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index de9f22da1d..a7a7f9a389 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2409,7 +2409,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) eventlog2_get_pipe_fns( &cmds, &n_cmds ); break; case PI_NTSVCS: - ntsvcs_get_pipe_fns( &cmds, &n_cmds ); + ntsvcs2_get_pipe_fns( &cmds, &n_cmds ); break; #ifdef DEVELOPER case PI_RPCECHO: -- cgit From 8db780ac8fc30df1e20e70d83a49365b74a10e0a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 19 Feb 2008 01:16:00 +0100 Subject: Yippie! LSARPC server-side migration to pidl finished. Guenther (This used to be commit aa7023b88d3161897b9616d950c2a99624d81931) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index a7a7f9a389..4d066a6b7a 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2376,7 +2376,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) switch ( idx ) { case PI_LSARPC: - lsa_get_pipe_fns( &cmds, &n_cmds ); + lsarpc_get_pipe_fns( &cmds, &n_cmds ); break; case PI_DSSETUP: dssetup_get_pipe_fns( &cmds, &n_cmds ); -- cgit From 583aa074a9525e08d2d14696ca27f0a636bbf6a5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 27 Feb 2008 18:49:17 +0100 Subject: Cosmetics: make check_bind_req() debug statements a little nicer. Guenther (This used to be commit 997a0a4a12d97595ff4df963601cf2c24d612972) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4d066a6b7a..19c8db0533 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -993,7 +993,7 @@ bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ for ( i=0; pipe_names[i].client_pipe; i++ ) { - DEBUG(10,("checking %s\n", pipe_names[i].client_pipe)); + DEBUGADD(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) && (abstract->version == pipe_names[i].abstr_syntax.version) && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct GUID)) == 0) -- cgit From e06aa46b9fab1e107fea8f6453fb13deffa91e96 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Fri, 14 Mar 2008 14:26:28 -0800 Subject: Coverity fixes (This used to be commit 3fc85d22590550f0539215d020e4411bf5b14363) --- source3/rpc_server/srv_pipe.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 19c8db0533..6c1b65b858 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -151,7 +151,7 @@ static bool create_next_pdu_ntlmssp(pipes_struct *p) * data. */ - prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_pdu, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* Store the header in the data stream. */ @@ -358,7 +358,7 @@ static bool create_next_pdu_schannel(pipes_struct *p) * data. */ - prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_pdu, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* Store the header in the data stream. */ @@ -531,7 +531,7 @@ static bool create_next_pdu_noauth(pipes_struct *p) * data. */ - prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_pdu, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* Store the header in the data stream. */ @@ -812,7 +812,7 @@ static bool setup_bind_nak(pipes_struct *p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_rpc, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -875,7 +875,7 @@ bool setup_fault_pdu(pipes_struct *p, NTSTATUS status) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_pdu, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -944,7 +944,7 @@ bool setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p) * header and are never sending more than one PDU here. */ - prs_init( &outgoing_pdu, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_pdu, p->mem_ctx, MARSHALL); prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -1522,7 +1522,7 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) return setup_bind_nak(p); } - prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_rpc, p->mem_ctx, MARSHALL); /* * Marshall directly into the outgoing PDU space. We @@ -1794,7 +1794,7 @@ bool api_pipe_alter_context(pipes_struct *p, prs_struct *rpc_in_p) prs_struct outgoing_rpc; int auth_len = 0; - prs_init( &outgoing_rpc, 0, p->mem_ctx, MARSHALL); + prs_init_empty( &outgoing_rpc, p->mem_ctx, MARSHALL); /* * Marshall directly into the outgoing PDU space. We -- cgit From 5fdf4b8f4ae41bc44cdbfa6ac82d857c3dd955c1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Mar 2008 04:12:52 +0100 Subject: Remove remaining old srvsvc client and server rpc code entirely. Guenther (This used to be commit a5f0186f70abe8dba650265219e69ce5ca2fb642) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 6c1b65b858..f33ee88aec 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2388,7 +2388,7 @@ void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) netlogon_get_pipe_fns( &cmds, &n_cmds ); break; case PI_SRVSVC: - srvsvc2_get_pipe_fns( &cmds, &n_cmds ); + srvsvc_get_pipe_fns( &cmds, &n_cmds ); break; case PI_WKSSVC: wkssvc_get_pipe_fns( &cmds, &n_cmds ); -- cgit From e9ba13bc67576aa70694ce54ca70aef4375ebe13 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 23 Mar 2008 19:43:36 +0100 Subject: Fix Coverity ID 514 Not exactly an uninitialized variable, but having Coverity figure out that we're only UNMARSHALLING here is probably asking for a bit too much. (This used to be commit 07a9f7daa83c94afefe0d81db4812135121862c2) --- source3/rpc_server/srv_pipe.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index f33ee88aec..05cdb65a83 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1593,6 +1593,8 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } } + ZERO_STRUCT(hdr_rb); + /* decode the bind request */ if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); -- cgit From c751386bb8d797dcb714fac19e6d4b161e3d81d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Apr 2008 22:20:32 +0200 Subject: Remove some write-only fstrings (This used to be commit aacb07b1b0f674b8cb92347ef4b4dd1e7808dde8) --- source3/rpc_server/srv_pipe.c | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 05cdb65a83..4ac9f7a6f4 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -614,11 +614,6 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) ZERO_STRUCT(reply); - memset(p->user_name, '\0', sizeof(p->user_name)); - memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name)); - memset(p->domain, '\0', sizeof(p->domain)); - memset(p->wks, '\0', sizeof(p->wks)); - /* Set up for non-authenticated user. */ TALLOC_FREE(p->pipe_user.nt_user_token); p->pipe_user.ut.ngroups = 0; @@ -656,14 +651,10 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } } - - fstrcpy(p->user_name, a->ntlmssp_state->user); - fstrcpy(p->pipe_user_name, a->server_info->unix_name); - fstrcpy(p->domain, a->ntlmssp_state->domain); - fstrcpy(p->wks, a->ntlmssp_state->workstation); - DEBUG(5,("pipe_ntlmssp_verify_final: OK: user: %s domain: %s workstation: %s\n", - p->user_name, p->domain, p->wks)); + DEBUG(5, ("pipe_ntlmssp_verify_final: OK: user: %s domain: %s " + "workstation: %s\n", a->ntlmssp_state->user, + a->ntlmssp_state->domain, a->ntlmssp_state->workstation)); /* * Store the UNIX credential data (uid/gid pair) in the pipe structure. -- cgit From 28fd4f6fcb101fc0274c43611a59d22072fb7891 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2008 20:26:52 +0200 Subject: Reconcile ndr_syntax_id used by pidl-generated code and Samba3's RFC_IFACE. (This used to be commit 7bea00dca1ee08ef731dfa73110ef9c190a29919) --- source3/rpc_server/srv_pipe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 4ac9f7a6f4..3fe9c7f2ec 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -986,9 +986,9 @@ bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, for ( i=0; pipe_names[i].client_pipe; i++ ) { DEBUGADD(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) - && (abstract->version == pipe_names[i].abstr_syntax.version) + && (abstract->if_version == pipe_names[i].abstr_syntax.if_version) && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct GUID)) == 0) - && (transfer->version == pipe_names[i].trans_syntax.version) + && (transfer->if_version == pipe_names[i].trans_syntax.if_version) && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct GUID)) == 0) ) { struct api_struct *fns = NULL; int n_fns = 0; -- cgit From a4c60b2696962c7f83e033e00d97e4b1dacc05c9 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 17 Apr 2008 17:44:40 +0200 Subject: rpc_parse: Use UUIDs from librpc/gen_ndr/ when possible to reduce duplication. (This used to be commit 428654b473ba44b2f5340eefef0d4fcd51aff558) --- source3/rpc_server/srv_pipe.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3fe9c7f2ec..52e4fdfd5b 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -986,10 +986,10 @@ bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, for ( i=0; pipe_names[i].client_pipe; i++ ) { DEBUGADD(10,("checking %s\n", pipe_names[i].client_pipe)); if ( strequal(pipe_names[i].client_pipe, pname) - && (abstract->if_version == pipe_names[i].abstr_syntax.if_version) - && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax.uuid, sizeof(struct GUID)) == 0) - && (transfer->if_version == pipe_names[i].trans_syntax.if_version) - && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax.uuid, sizeof(struct GUID)) == 0) ) { + && (abstract->if_version == pipe_names[i].abstr_syntax->if_version) + && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax->uuid, sizeof(struct GUID)) == 0) + && (transfer->if_version == pipe_names[i].trans_syntax->if_version) + && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax->uuid, sizeof(struct GUID)) == 0) ) { struct api_struct *fns = NULL; int n_fns = 0; PIPE_RPC_FNS *context_fns; -- cgit From 40f5eab5eb515937e1b23cf6762b77c194d29b9d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 19 Jun 2008 16:54:12 +0200 Subject: Wrap the unix token info in a unix_user_token in auth_serversupplied_info No functional change, this is a preparation for more current_user ref removal (This used to be commit dcaedf345e62ab74ea87f0a3fa1e3199c75c5445) --- source3/rpc_server/srv_pipe.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 52e4fdfd5b..dcc4cd448f 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -660,8 +660,8 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) * Store the UNIX credential data (uid/gid pair) in the pipe structure. */ - p->pipe_user.ut.uid = a->server_info->uid; - p->pipe_user.ut.gid = a->server_info->gid; + p->pipe_user.ut.uid = a->server_info->utok.uid; + p->pipe_user.ut.gid = a->server_info->utok.gid; /* * We're an authenticated bind over smbd, so the session key needs to @@ -675,10 +675,11 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } - p->pipe_user.ut.ngroups = a->server_info->n_groups; + p->pipe_user.ut.ngroups = a->server_info->utok.ngroups; if (p->pipe_user.ut.ngroups) { - if (!(p->pipe_user.ut.groups = (gid_t *)memdup(a->server_info->groups, - sizeof(gid_t) * p->pipe_user.ut.ngroups))) { + if (!(p->pipe_user.ut.groups = (gid_t *)memdup( + a->server_info->utok.groups, + sizeof(gid_t) * p->pipe_user.ut.ngroups))) { DEBUG(0,("failed to memdup group list to p->pipe_user.groups\n")); return False; } -- cgit From df905a5d77037eaffe5f52edd26409152b740068 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 20 Jun 2008 16:22:49 +0200 Subject: Make pipes_struct its own talloc ctx (This used to be commit 829b1ad4697f2f1ea008377d591456722dccd025) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index dcc4cd448f..0987a420d5 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1343,7 +1343,7 @@ static bool pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, return False; } - p->auth.a_u.schannel_auth = TALLOC_P(p->pipe_state_mem_ctx, struct schannel_auth_struct); + p->auth.a_u.schannel_auth = talloc(p, struct schannel_auth_struct); if (!p->auth.a_u.schannel_auth) { TALLOC_FREE(pdcinfo); return False; -- cgit From d331624fdfe9fc72f1da7fd01c59a1a20cf1c7d7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Jun 2008 14:18:55 +0200 Subject: Add server_info to pipes_struct (This used to be commit d621867bb8767e1c4236d28dd9294a61db6cbb10) --- source3/rpc_server/srv_pipe.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 0987a420d5..04d18d51c9 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -694,6 +694,16 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return False; } + TALLOC_FREE(p->server_info); + + p->server_info = copy_serverinfo(p, a->server_info); + if (p->server_info == NULL) { + DEBUG(0, ("copy_serverinfo failed\n")); + return false; + } + + server_info_set_session_key(p->server_info, p->session_key); + return True; } -- cgit From cebbb2d84a8ab365f36d7e30177418a44fddb9e5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Jun 2008 14:25:23 +0200 Subject: Fix typo (This used to be commit 41d2daeaa5a87da82a0debc4c9cfe14976215bd8) --- source3/rpc_server/srv_pipe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 04d18d51c9..cac48db7ee 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -664,7 +664,7 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.gid = a->server_info->utok.gid; /* - * We're an authenticated bind over smbd, so the session key needs to + * We're an authenticated bind over smb, so the session key needs to * be set to "SystemLibraryDTC". Weird, but this is what Windows * does. See the RPC-SAMBA3SESSIONKEY. */ -- cgit From 747a5809528cffc40f46d7e27a96ce0c559056b4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 24 Jun 2008 14:33:31 +0200 Subject: Now that we have p->server_info, use p->server_info->user_session_key (This used to be commit aefad64e3a5c86d2f988d47e6215ed2085b8fc47) --- source3/rpc_server/srv_pipe.c | 47 ++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 18 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index cac48db7ee..80e2b2f9a9 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -606,9 +606,10 @@ bool create_next_pdu(pipes_struct *p) static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) { - DATA_BLOB reply; + DATA_BLOB session_key, reply; NTSTATUS status; AUTH_NTLMSSP_STATE *a = p->auth.a_u.auth_ntlmssp_state; + bool ret; DEBUG(5,("pipe_ntlmssp_verify_final: pipe %s checking user details\n", p->name)); @@ -663,18 +664,6 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) p->pipe_user.ut.uid = a->server_info->utok.uid; p->pipe_user.ut.gid = a->server_info->utok.gid; - /* - * We're an authenticated bind over smb, so the session key needs to - * be set to "SystemLibraryDTC". Weird, but this is what Windows - * does. See the RPC-SAMBA3SESSIONKEY. - */ - - data_blob_free(&p->session_key); - p->session_key = generic_session_key(); - if (!p->session_key.data) { - return False; - } - p->pipe_user.ut.ngroups = a->server_info->utok.ngroups; if (p->pipe_user.ut.ngroups) { if (!(p->pipe_user.ut.groups = (gid_t *)memdup( @@ -702,7 +691,20 @@ static bool pipe_ntlmssp_verify_final(pipes_struct *p, DATA_BLOB *p_resp_blob) return false; } - server_info_set_session_key(p->server_info, p->session_key); + /* + * We're an authenticated bind over smb, so the session key needs to + * be set to "SystemLibraryDTC". Weird, but this is what Windows + * does. See the RPC-SAMBA3SESSIONKEY. + */ + + session_key = generic_session_key(); + if (session_key.data == NULL) { + return False; + } + + ret = server_info_set_session_key(p->server_info, session_key); + + data_blob_free(&session_key); return True; } @@ -1332,6 +1334,7 @@ static bool pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, bool ret; struct dcinfo *pdcinfo; uint32 flags; + DATA_BLOB session_key; if (!smb_io_rpc_auth_schannel_neg("", &neg, rpc_in_p, 0)) { DEBUG(0,("pipe_schannel_auth_bind: Could not unmarshal SCHANNEL auth neg\n")); @@ -1378,12 +1381,20 @@ static bool pipe_schannel_auth_bind(pipes_struct *p, prs_struct *rpc_in_p, * anymore. */ - data_blob_free(&p->session_key); - p->session_key = generic_session_key(); - if (p->session_key.data == NULL) { + session_key = generic_session_key(); + if (session_key.data == NULL) { DEBUG(0, ("pipe_schannel_auth_bind: Could not alloc session" " key\n")); - return False; + return false; + } + + ret = server_info_set_session_key(p->server_info, session_key); + + data_blob_free(&session_key); + + if (!ret) { + DEBUG(0, ("server_info_set_session_key failed\n")); + return false; } init_rpc_hdr_auth(&auth_info, RPC_SCHANNEL_AUTH_TYPE, pauth_info->auth_level, RPC_HDR_AUTH_LEN, 1); -- cgit From 1bd72938176fc49c7fedd499e4860da0c78a871b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 Jul 2008 22:08:59 +0200 Subject: In api_pipe_bind_req(), decode the bind request before checking the pipe (This used to be commit 8be41382ed9bb4fb44a1846fff2c7652388e4f28) --- source3/rpc_server/srv_pipe.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 80e2b2f9a9..f8ec4bfc91 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1565,6 +1565,16 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) DEBUG(5,("api_pipe_bind_req: decode request. %d\n", __LINE__)); + ZERO_STRUCT(hdr_rb); + + /* decode the bind request */ + + if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { + DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB " + "struct.\n")); + goto err_exit; + } + /* * Try and find the correct pipe name to ensure * that this is a pipe name we support. @@ -1606,14 +1616,6 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) } } - ZERO_STRUCT(hdr_rb); - - /* decode the bind request */ - if(!smb_io_rpc_hdr_rb("", &hdr_rb, rpc_in_p, 0)) { - DEBUG(0,("api_pipe_bind_req: unable to unmarshall RPC_HDR_RB struct.\n")); - goto err_exit; - } - /* name has to be \PIPE\xxxxx */ fstrcpy(ack_pipe_name, "\\PIPE\\"); fstrcat(ack_pipe_name, p->pipe_srv_name); -- cgit From e0f3ea2cbeb61cb02be85d2b315948985bac27a8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 12 Jul 2008 23:17:23 +0200 Subject: In api_pipe_bind_req(), check for the iface id, not the pipe name This requires to store the rpc_interface in "struct rpc_table" (This used to be commit 654f8de8497aff29f9b1f1822b6a8e734ff329e0) --- source3/rpc_server/srv_pipe.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index f8ec4bfc91..48e6646c75 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -718,6 +718,7 @@ struct rpc_table { const char *clnt; const char *srv; } pipe; + struct ndr_syntax_id rpc_interface; const struct api_struct *cmds; int n_cmds; }; @@ -1039,7 +1040,10 @@ bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, Register commands to an RPC pipe *******************************************************************/ -NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *srv, const struct api_struct *cmds, int size) +NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, + const char *srv, + const struct ndr_syntax_id *interface, + const struct api_struct *cmds, int size) { struct rpc_table *rpc_entry; @@ -1079,6 +1083,7 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, const char *s ZERO_STRUCTP(rpc_entry); rpc_entry->pipe.clnt = SMB_STRDUP(clnt); rpc_entry->pipe.srv = SMB_STRDUP(srv); + rpc_entry->rpc_interface = *interface; rpc_entry->cmds = cmds; rpc_entry->n_cmds = size; @@ -1575,16 +1580,22 @@ bool api_pipe_bind_req(pipes_struct *p, prs_struct *rpc_in_p) goto err_exit; } + if (hdr_rb.num_contexts == 0) { + DEBUG(0, ("api_pipe_bind_req: no rpc contexts around\n")); + goto err_exit; + } + /* * Try and find the correct pipe name to ensure * that this is a pipe name we support. */ - for (i = 0; i < rpc_lookup_size; i++) { - if (strequal(rpc_lookup[i].pipe.clnt, p->name)) { + if (ndr_syntax_id_equal(&rpc_lookup[i].rpc_interface, + &hdr_rb.rpc_context[0].abstract)) { DEBUG(3, ("api_pipe_bind_req: \\PIPE\\%s -> \\PIPE\\%s\n", rpc_lookup[i].pipe.clnt, rpc_lookup[i].pipe.srv)); + fstrcpy(p->name, rpc_lookup[i].pipe.clnt); fstrcpy(p->pipe_srv_name, rpc_lookup[i].pipe.srv); break; } -- cgit From bcb652451b6360b0de595c13961b11134097f3bb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 Jul 2008 00:03:49 +0200 Subject: Simplify the RPC servers: remove get_pipe_fns The per-server xxx_get_pipe_fns functions can go once all the RPC servers are converted (This used to be commit 6aa2391cbe1cbda8269ded767117f53d83b243e1) --- source3/rpc_server/srv_pipe.c | 122 +++++++++--------------------------------- 1 file changed, 25 insertions(+), 97 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 48e6646c75..fa8fffa350 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -29,7 +29,6 @@ #include "includes.h" -extern struct pipe_id_info pipe_names[]; extern struct current_user current_user; #undef DBGC_CLASS @@ -986,53 +985,42 @@ bool setup_cancel_ack_reply(pipes_struct *p, prs_struct *rpc_in_p) bool check_bind_req(struct pipes_struct *p, RPC_IFACE* abstract, RPC_IFACE* transfer, uint32 context_id) { - char *pipe_name = p->name; int i=0; - fstring pname; - - fstrcpy(pname,"\\PIPE\\"); - fstrcat(pname,pipe_name); + struct pipe_rpc_fns *context_fns; - DEBUG(3,("check_bind_req for %s\n", pname)); + DEBUG(3,("check_bind_req for %s\n", p->name)); /* we have to check all now since win2k introduced a new UUID on the lsaprpc pipe */ - - for ( i=0; pipe_names[i].client_pipe; i++ ) { - DEBUGADD(10,("checking %s\n", pipe_names[i].client_pipe)); - if ( strequal(pipe_names[i].client_pipe, pname) - && (abstract->if_version == pipe_names[i].abstr_syntax->if_version) - && (memcmp(&abstract->uuid, &pipe_names[i].abstr_syntax->uuid, sizeof(struct GUID)) == 0) - && (transfer->if_version == pipe_names[i].trans_syntax->if_version) - && (memcmp(&transfer->uuid, &pipe_names[i].trans_syntax->uuid, sizeof(struct GUID)) == 0) ) { - struct api_struct *fns = NULL; - int n_fns = 0; - PIPE_RPC_FNS *context_fns; - - if ( !(context_fns = SMB_MALLOC_P(PIPE_RPC_FNS)) ) { - DEBUG(0,("check_bind_req: malloc() failed!\n")); - return False; - } - - /* save the RPC function table associated with this bind */ - - get_pipe_fns(i, &fns, &n_fns); - - context_fns->cmds = fns; - context_fns->n_cmds = n_fns; - context_fns->context_id = context_id; - - /* add to the list of open contexts */ - - DLIST_ADD( p->contexts, context_fns ); - + + for (i=0; iname) + && ndr_syntax_id_equal( + abstract, &rpc_lookup[i].rpc_interface) + && ndr_syntax_id_equal( + transfer, &ndr_transfer_syntax)) { break; } } - if(pipe_names[i].client_pipe == NULL) { + if (i == rpc_lookup_size) { + return false; + } + + context_fns = SMB_MALLOC_P(struct pipe_rpc_fns); + if (context_fns == NULL) { + DEBUG(0,("check_bind_req: malloc() failed!\n")); return False; } + context_fns->cmds = rpc_lookup[i].cmds; + context_fns->n_cmds = rpc_lookup[i].n_cmds; + context_fns->context_id = context_id; + + /* add to the list of open contexts */ + + DLIST_ADD( p->contexts, context_fns ); + return True; } @@ -2393,63 +2381,3 @@ bool api_rpcTNP(pipes_struct *p, const char *rpc_name, return True; } - -/******************************************************************* -*******************************************************************/ - -void get_pipe_fns( int idx, struct api_struct **fns, int *n_fns ) -{ - struct api_struct *cmds = NULL; - int n_cmds = 0; - - switch ( idx ) { - case PI_LSARPC: - lsarpc_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_DSSETUP: - dssetup_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_SAMR: - samr_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_NETLOGON: - netlogon_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_SRVSVC: - srvsvc_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_WKSSVC: - wkssvc_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_WINREG: - winreg_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_SPOOLSS: - spoolss_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_NETDFS: - netdfs_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_SVCCTL: - svcctl2_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_EVENTLOG: - eventlog2_get_pipe_fns( &cmds, &n_cmds ); - break; - case PI_NTSVCS: - ntsvcs2_get_pipe_fns( &cmds, &n_cmds ); - break; -#ifdef DEVELOPER - case PI_RPCECHO: - rpcecho_get_pipe_fns( &cmds, &n_cmds ); - break; -#endif - default: - DEBUG(0,("get_pipe_fns: Unknown pipe index! [%d]\n", idx)); - } - - *fns = cmds; - *n_fns = n_cmds; - - return; -} -- cgit From 2e7cb1a5ccf8ae513a432cef9ccebfcebe4241ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Jul 2008 20:27:56 +0200 Subject: Introduce is_known_pipename This scans the list of pipes registered via rpc_pipe_register_commands instead of using static tables. (This used to be commit 283e6039989adea1c8921b3600b410cb67b6492a) --- source3/rpc_server/srv_pipe.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index fa8fffa350..7b066d3830 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -1078,6 +1078,39 @@ NTSTATUS rpc_pipe_register_commands(int version, const char *clnt, return NT_STATUS_OK; } +/** + * Is a named pipe known? + * @param[in] cli_filename The pipe name requested by the client + * @result Do we want to serve this? + */ +bool is_known_pipename(const char *cli_filename) +{ + const char *pipename = cli_filename; + int i; + + if (strnequal(pipename, "\\PIPE\\", 6)) { + pipename += 5; + } + + if (*pipename == '\\') { + pipename += 1; + } + + if (lp_disable_spoolss() && strequal(pipename, "spoolss")) { + DEBUG(10, ("refusing spoolss access\n")); + return false; + } + + for (i=0; i Date: Sat, 26 Jul 2008 11:25:24 +0200 Subject: Make api_rpcTNP static to srv_pipe.c (This used to be commit 256c93a8b3d4d9a4e52a656c91b89a043a087066) --- source3/rpc_server/srv_pipe.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/rpc_server/srv_pipe.c') diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 7b066d3830..be7d3db444 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -2284,6 +2284,9 @@ void free_pipe_rpc_context( PIPE_RPC_FNS *list ) return; } +static bool api_rpcTNP(pipes_struct *p, const char *rpc_name, + const struct api_struct *api_rpc_cmds, int n_cmds); + /**************************************************************************** Find the correct RPC function to call for this request. If the pipe is authenticated then become the correct UNIX user @@ -2333,8 +2336,8 @@ bool api_pipe_request(pipes_struct *p) Calls the underlying RPC function for a named pipe. ********************************************************************/ -bool api_rpcTNP(pipes_struct *p, const char *rpc_name, - const struct api_struct *api_rpc_cmds, int n_cmds) +static bool api_rpcTNP(pipes_struct *p, const char *rpc_name, + const struct api_struct *api_rpc_cmds, int n_cmds) { int fn_num; fstring name; -- cgit